diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 378c898..0000000 --- a/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -bower_components/ -node_modules/ -coverage/ -junit/ -dist/ -out/ diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index f6162d2..0000000 --- a/.jshintrc +++ /dev/null @@ -1,24 +0,0 @@ -{ - "boss": true, - "browser": true, - "curly": true, - "eqnull": true, - "expr": true, - "immed": true, - "indent": 2, - "laxbreak": true, - "loopfunc": true, - "newcap": true, - "noarg": true, - "noempty": true, - "nonew": true, - "quotmark": true, - "smarttabs": true, - "sub": true, - "trailing": true, - "undef": true, - "unused": true, - "globals": { - "angular": false - } -} diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 0edfe4f..0000000 --- a/.npmignore +++ /dev/null @@ -1,6 +0,0 @@ -bower_components/ -node_modules/ -coverage/ -junit/ -# dist/ -out/ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 5c5237b..0000000 --- a/.prettierrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "single-quote": true -} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6d05475..0000000 --- a/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -language: node_js -node_js: -- '6' -addons: - firefox: "54.0.1" -before_install: -- export DISPLAY=:99.0 -- sh -e /etc/init.d/xvfb start -- npm install -qg bower grunt grunt-cli -- npm install -q -- bower install -after_success: -- ./node_modules/angular-ui-publisher/travis/authentication.sh || exit 0 -- grunt dist build:gh-pages publish:gh-pages build:bower publish:bower -script: grunt -env: - global: - - REPO="git@github.com:angular-ui/ui-sortable.git" - - secure: lv6/NYEdeaQi/ITVGbmWLdj2LoHjrMaF511YoDOOEWjdtCZPUmIciMYDvDidaLzr5NKgtaQCzGouHIgbdM2r+blJndTB+fydXYw3nq9qvRsXRGbWH0TY2KtdB++73NhomHN2kOYAx7IOW7XN+StWG6kdBFJ6lDOZl9vOZTHnHvE= - - secure: A6zLTHw99hvJ37FNKPnW4y6Eu/G+1M7NEw4vgWDlyH96RB0QYYvRKuHVn68FRBtHSdcaFzuANjzxeE0QEBBhq4kM4AjsQtveBHJcTBDZGnzZB7krH1E8yrNH70EWI8b3bXsWzUaYeNgUMFJpFa1pEMWq2rCe0CwEFVHf8TlF7MI= - - secure: BEWMRv9ET7fXabDkAvRQJBsIziyDeYrVkXDEINgdDwaoNclYtDSnxyYMG1wAcoNM6Znb8MdcmZm2SaOUOxIwplukomh1i8oT6wXeEl+vaYoCS6kz9iwcqgE0rFx9Zo+9q+UCvst30aB//XtVt71tbpKYaNTilZH2U6gvmUxYUAM= - - secure: SbIj+dXPq3y+cREpT+GoXBflKr2SmonL+ini3Q+7EL+82xMbqnTYRRdVvSBOAbK35fskBgDec91kuF2jKKvi3n2kYLWqYC5a6MteMsD/Ne7ntmebSZ4xIoI2CnHnYMoh8X5r2R5ykAu9phKDb6ujNol2bSI/2UBeSXse1ROp6M8= - - secure: RCFXr57oVjSOnM28rYMSfi4xlU70R5bjbDU+NUhQ+Mw7S1Bz1B0F+ZwMRuXDz2GnBnA+2Vu6i6qY0TWxfd7SAkG7+mW8hKc7OrHjYSt6tPPeCfwx6fcnFF6wxWR5fOt47aX4sNnOkaAoPQa2rf6uPHknTP0mVJgX//hsS++8orw= - - secure: VPb2CQUyWC0BY5Pf2qJpUBEV3nPvvxeQYMZ/woVy53TN+EL0n0un70Ia9ddGBljcRLYht08lRnf8SMnSkpCyqtDGVY/XskzdR7D2JJk0DoBoShPHeVPz6wb+Za1F/syp1S+P4L+9+ZTrDFwkXoTN6ZEVoOqh8S5SW5lyxpBcOjo= - - secure: fGkAkjv8+0UEpmVDK2tDsJ2b7pAazNkZnBtIB+dLNDxeIPp/o75TiIN52dsjYMS4v8AhPX9XEGgURHKO4Tt3CJ42oAV3SXFSSKZ+HUad0YzEw0SCLsMJOJvGSyg8A9d811//KpDZkSvNTLRER9kW+ONVGWkaqDzZk9JNAiZQ21E= - - secure: moG6EmijG8fnkSEKWT5939qubV7bupNHiR1f61HAaC4dFN2fnQuqzamBlRTmdISOuhFKkMAZRt9ZpRjeOTwcGzE+PV2WkbLzZggn19uPV/4J6cm3MBDhnbJfrTnNCD+XoxfgJezwWL+yA+OTKOjKoli/c2j3gA18lHxL8RGGfWA= - - secure: ey2lvN+BsXGwYm8uMuVl22fv6ABqdqr+wEGsXVq0IwMfoyifXu7Zjbqq3dbxwOADlm2BpuBM1EMOh4b3J5Xae5KbkZ1olh8wbTT07XN6GdRyKoxRgkxORyjQe35uPpxNXPG/4MDPGvOer4tP205GSSET7GzXgTjeoUP/Wn04l3U= - - secure: BkaTcpkvyph2ktmqHmWV2sM+3U2X/Np7LH6CjV/up1tyUqLUVOg7KcxVnDhrfrzxeQQqDv8CX4bkE9OIe0PrIU5FzRDAlxmEA1n8iR/ZFQdLmdLXIT5Aq58oEggyB3GvmojOLSB2MT2jPucz+RpftaglaUtxwa20nxryigEDOdU= - - secure: TQqMgKNva40V429OmdCpFHiAXc86wIhnSN4MYSKpWKb4vmG7pL75ycjYCxADpKJjOjGb4JYk/UZOk/3PIWi2g0j/thNEIK48jak7dtA7I9RZ/pKA6JN4LxaSlcsrOUhFfWAzfchrqpbHCwvzKlbFJmulRXKAeFbqXmzf6IaUVZg= - - secure: CbGh34phZ9Fbzow1JmtDcbbfu5si7piJLUFFAxGlXlu7lYVp5XpgCJ40uIpbzArZ8ZYaD9ZtoCqBgW5dDKRMUdbyobIqbeIcnljAXrHR+M6FonLuao+TLOe9s2k1fThU4Pdxm9aGedz63UwaTdibCY+mFK7jNptxkfO4RAsnsuw= - - secure: i41+wqwnBiQ+OICjPcOFFTkkznqS6E3sVay9plI7RSQJjN4hj9Nvmarr6l9dqIUUSuIrkZVfynvpOezPT6mrOJZulpGOamJMBfueJ03Vk2pT8vtRRMh1ICyNSz6ZznORa7tZYOM+oI8Bi9gXJzVfxWvTF958XyVgX6GeYEWYCME= - - secure: gH09SKPIpoUCci3DGJ6jQYIOCtGuU12pUyMNJbws+/AKKgLTfozPqbsYZ/CWZOC5Wh/dvTiW0tRsZDYRfq1MWosoDjd1QxlzlhvqxQ120F1LtLHm9IPgrVdHBzG1dJdKUIkgYL+4pwgMbPJUWDfJduxd4iI1eZzqYEWR+lapjEE= - - secure: LHeYrBZ1mfPRi4xEv1pc+HlQGtUtsRFUHLMel7UafILSfjhqRu0p0uH0RvqjB4ctrjufqrpZh+C5iAitKULoX7drRZABxR4fUAGUT7UADJ3YAFuhseNNpNPa5LOqhcsxA4t+oFsnZq+/1HvGAXi/tkrIJlogiNdIO5/EcwI2GOc= - - secure: dq9Bjf+44cEeOqdVT8za+3uCGXcjAZ1DdkSZ1bp7qlEcFsV4xjgwa1Qa4XWl9D5x1ZjuQ/CG2Hbcm1N+CW9UtmJsxqmQye+WkwD14HzKoRTQubMW2woiTuPWj2HcZB03S24f9r83kxCyvdhBeNcNgqPYZByQerlWhd8mKzKvLq8= - - secure: bMOOsktaSAshyBJQMlLZMBVoHguYJRFM0FUkskhIi9OTXsJajBAw5TYqsSlEJcMb65tgWR0KzHYOVKesoZvq5pyWkIANIJduoGwAuhY6loMmhY+kBF4ZKx6d+V1pnyzT5uW/0Jn+nN6XiuXHGx/fjppAvi/AYd05+bRYvAvYoRQ= - - secure: Nit2R7+Ob/jDz0i/3iUrcMjskkwlr/Bp+xWYm9MS/9LSG19N+eV/1McNEe1joFUeQ29IfZUU522u27Twbf9h10X/4um99vSwxUkqyTpR5Gl8N7bu51bbRzGwTFqAQoxiIc2bEpSwVyql0okLnYsaZVDOjlyuAqZ1RRj+xBfcUrI= - - secure: ZoIMbOS9tUpCEZyWGEzkNITPvPorJ+d7n3yMGJqhD6Ud7n6oFyLskT7JECZ4cUiykVaWsAHGMN+xxYLUkAJLdhd2gE3reN+8JrSjJb32W0Sf+5z1ajcwWBsZu4nyxRpPo2QZduS7lU2M0+YdFs8qG7gEhploFDu7hZOI2RaCkTo= - - secure: DZhkAksHSU8MGN0dISwGWA2uuMEvxpeSmqJu2fpPTei//n5l/n+RqlfYH8hUKdMf87RBpXRY1VpHiFYpkNYsmf903gw3kdRWhW07hG3Yt9hXc+YIR0OK6KZ5sb/XZi/ZkWrPEInAL2Yol00e6+U13134SZlPE84P6ktXiKKtlMc= - - secure: Cy34UQZ7/9toUKV6905XYeXIaFdDRhLb+ibEbLnjoo3ifeApNaecc1l4aBN88HN6nKnX1TKSZyiETwCpCWCee2d7KTi4IhSFTAa+SVUTV6BmikhdUs6MwemyreyWFlxZD32huZKyWU9ZEAwwQ0Oq9gPqECWWZkdT4LInF6SLWLY= - - secure: E9gahGC9Swvy83Kos9LhFsxZp/zBI6Ll9lqQd6HxT7YSXj2YeoxSMCsF629bODPdtuMirhmFqReKZKL1lDpJBswr1sFtnmVavSwVBW4v/CIAQu0ENC85Knv1wgoAcl7cRisWaueSHJ0DyNstZZWGNWryIINg9zjFdrOSztDvoN8= - - secure: UxCvWwq2GcUdL3BtJyRMEFPHPRGIdPPLthThmWrmUE7dnblpDUdWVXKc62f7Y42qtHlhYh1EjxX0GJFcS1F0Lfge0e0cxDNWBATBoLKpC67kTyz/cUgqFEv6tsbkziBtbOrBuy6/LMZly1BqG/3fIDEJezkKOIqHF+pdApvAC/8= - - secure: LY+rU4ouy35DfnXdTumu+lPQsMPzNWQktXlms1YG1jWqOs7As223fLQAFe5tyVs34K0xQsPCq3whfaDCd4ZNVYLO3srsXSuRpDw8DRt1fQhhVJo8IBI+Yv92FiFZr54BsBxM4Wzt8hFWEzDlIgziOYSriSXMuBomMHXbtm5vkzg= diff --git a/API.md b/API.md deleted file mode 100644 index 0094f7d..0000000 --- a/API.md +++ /dev/null @@ -1,84 +0,0 @@ -# ui.item.sortable API documentation - -This refers to the additional properties that are exposed through the `ui` parameter in the provided callback hooks. eg: -```js -$scope.sortableOptions = { - update: function(e, ui) { - if (ui.item.sortable.model == "can't be moved") { - ui.item.sortable.cancel(); - } - } -}; -``` - -## Properties - -**Note:** -The properties of `ui.item.sortable` object are cleared right after the stop callback fires. If you need to access them after the sorting ends, you should keep references in separate variables in your code. - -### dropindex -Type: [Integer](http://api.jquery.com/Types/#Integer) -Holds the index of the drop target that the dragged item was dropped. - - -### droptarget -Type: [jQuery](http://api.jquery.com/Types/#jQuery) -Holds the ui-sortable element that the dragged item was dropped on. - -### droptargetModel -Type: [Array](http://api.jquery.com/Types/#Array) -Holds the array that is specified by the `ng-model` attribute of the [`droptarget`](#droptarget) ui-sortable element. - -### index -Type: [Integer](http://api.jquery.com/Types/#Integer) -Holds the original index of the item dragged. - -### model -Type: [Object](http://api.jquery.com/Types/#Object) -Holds the JavaScript object that is used as the model of the dragged item, as specified by the ng-repeat of the [`source`](#source) ui-sortable element and the item's [`index`](#index). - -### moved -Type: [Object](http://api.jquery.com/Types/#Object)/`undefined` -Holds the model of the dragged item only when a sorting happens between two connected ui-sortable elements. -In other words: `'moved' in ui.item.sortable` will return false only when a sorting is withing the same ui-sortable element ([`source`](#source) equals to the [`droptarget`](#droptarget)). - -### received -Type: [Boolean](http://api.jquery.com/Types/#Boolean) -When sorting between two connected sortables, it will be set to true inside the `update` callback of the [`droptarget`](#droptarget). - -### source -Type: [jQuery](http://api.jquery.com/Types/#jQuery) -Holds the ui-sortable element that the dragged item originated from. - -### sourceModel -Type: [Array](http://api.jquery.com/Types/#Array) -Holds the array that is specified by the `ng-model` of the [`source`](#source) ui-sortable element. - - -## Methods - -### cancel[()](http://api.jquery.com/Types/#Function) -Returns: Nothing -Can be called inside the `update` callback, in order to prevent/revert a sorting. -Should be used instead of the [jquery-ui-sortable cancel()](http://api.jqueryui.com/sortable/#method-cancel) method. - -### isCanceled[()](http://api.jquery.com/Types/#Function) -Returns: [Boolean](http://api.jquery.com/Types/#Boolean) -Returns whether the current sorting is marked as canceled, by an earlier call to [`ui.item.sortable.cancel()`](#cancel). - -### isCustomHelperUsed[()](http://api.jquery.com/Types/#Function) -Returns: [Boolean](http://api.jquery.com/Types/#Boolean) -Returns whether the [`helper`](http://api.jqueryui.com/sortable/#option-helper) element used for the current sorting, is one of the original ui-sortable list elements. - - -## Events - -### `ui-sortable:moved` -Is emitted after the `stop` callback. -In connected sortables it is also emitted after the `update` on the receiving sortable. - -```js -$rootScope.$on('ui-sortable:moved', function (e, ui) { - -}); -``` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 4a98897..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,12 +0,0 @@ -# Contributing to UI Sortable - -## Reporting Issues - -The following examples are provided as a good starting point to demonstrate issues, proposals and use cases. -Feel free to edit any of them for your needs (don't forget to also update the libraries used to your version). - -* [Simple Demo](http://codepen.io/thgreasi/pen/jlkhr) -* [Connected Lists](http://codepen.io/thgreasi/pen/uFile) - -Since some issues may be caused by jquery-ui-sortable and not by the wrapping that angular-ui-sortable does, -please try your use case using [this plain jquery-ui sortable example](http://codepen.io/thgreasi/pen/rarQvR) before opening a new issue in the repositry. diff --git a/LICENSE b/LICENSE deleted file mode 100644 index dfc5e0c..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 2012 the AngularUI Team, http://angular-ui.github.com - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index 15758cb..0000000 --- a/README.md +++ /dev/null @@ -1,350 +0,0 @@ -# UI.Sortable directive -[![npm](https://img.shields.io/npm/v/angular-ui-sortable.svg)](https://www.npmjs.com/package/angular-ui-sortable) -[![npm](https://img.shields.io/npm/dm/angular-ui-sortable.svg)](https://www.npmjs.com/package/angular-ui-sortable) -[![Build Status](https://travis-ci.org/angular-ui/ui-sortable.svg?branch=master)](https://travis-ci.org/angular-ui/ui-sortable) -[![Coverage Status](https://coveralls.io/repos/angular-ui/ui-sortable/badge.svg?branch=master)](https://coveralls.io/r/angular-ui/ui-sortable?branch=master) -[![debugInfoEnabled(false) Ready Badge](https://rawgit.com/thgreasi/ng-debugInfoDisabled-badges/master/badge1.svg)](https://docs.angularjs.org/guide/production#disabling-debug-data) -[![Join the chat at https://gitter.im/angular-ui/ui-sortable](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/angular-ui/ui-sortable?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -This directive allows you to sort an array with drag & drop. - -## Requirements - -- JQuery v3.1+ (for jQuery v1.x & v2.x use [v0.14.x versions](https://github.com/angular-ui/ui-sortable/tree/v0.14.x-stable)) -- JQueryUI v1.12+ -- AngularJS v1.2+ - -[Single minified cdn link](http://cdn.jsdelivr.net/g/jquery@1,jquery.ui@1.10%28jquery.ui.core.min.js+jquery.ui.widget.min.js+jquery.ui.mouse.min.js+jquery.ui.sortable.min.js%29,angularjs@1.2,angular.ui-sortable) ~245kB and [example](http://codepen.io/thgreasi/pen/olDJi) with JQuery v1.x, required parts of JQueryUI v1.10, AngularJS v1.2 & latest angular-ui-sortable. - -**Notes:** -> * JQuery must be included before AngularJS. -> * JQueryUI dependecies include [widget](http://api.jqueryui.com/jQuery.widget/), [data](http://api.jqueryui.com/data-selector/), [scroll-parent](http://api.jqueryui.com/scrollParent/), [mouse](http://api.jqueryui.com/mouse/) & [sortable](http://api.jqueryui.com/sortable/). Creating a [custom build](http://jqueryui.com/download/#!version=1.12.1&components=101000000100000010000000010000000000000000000000) will [greatly reduce](https://github.com/angular-ui/ui-sortable/issues/154#issuecomment-40279430) the required file size. ([CDN](http://www.jsdelivr.com/) links for comparison: [full](https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js) vs [minimal](https://cdn.jsdelivr.net/combine/npm/jquery-ui@1.12/ui/version.min.js,npm/jquery-ui@1.12/ui/widget.min.js,npm/jquery-ui@1.12/ui/data.min.js,npm/jquery-ui@1.12/ui/scroll-parent.min.js,npm/jquery-ui@1.12/ui/widgets/mouse.min.js,npm/jquery-ui@1.12/ui/widgets/sortable.min.js)) -> * Users of AngularJS pre v1.2 can use [v0.10.x](https://github.com/angular-ui/ui-sortable/tree/v0.10.x-stable) or [v0.12.x](https://github.com/angular-ui/ui-sortable/tree/v0.12.x-stable) branches. -> * Early adopters of [Angular2](https://angular.io/) can use the [ng2 branch](https://github.com/angular-ui/ui-sortable/tree/ng2). - -## Installation - -* Install with Bower `bower install -S angular-ui-sortable` -* Install with npm `npm install -S angular-ui-sortable` -* Download one of the [Releases](https://github.com/angular-ui/ui-sortable/releases) or the [latest Master branch](https://github.com/angular-ui/ui-sortable/archive/master.zip) - -## Usage - -Load the script file: sortable.js in your application: - -```html - -``` - -Add the sortable module as a dependency to your application module: - -```js -var myAppModule = angular.module('MyApp', ['ui.sortable']) -``` - -Apply the directive to your form elements: - -```html - -``` - -**Developing Notes:** - -* `ng-model` is required, so that the directive knows which model to update. -* `ui-sortable` element should contain only one `ng-repeat`, but other non-repeater elements above or below may still exist. - Otherwise the index matching of the `ng-model`'s items and the DOM elements generated by the `ng-repeat` will break. - **In other words: The items of `ng-model` must match the indexes of the DOM elements generated by the `ng-repeat`.** -* [`Filters`](https://docs.angularjs.org/guide/filter) that manipulate the model (like [filter](https://docs.angularjs.org/api/ng/filter/filter), [orderBy](https://docs.angularjs.org/api/ng/filter/orderBy), [limitTo](https://docs.angularjs.org/api/ng/filter/limitTo),...) should be applied in the `controller` instead of the `ng-repeat` (refer to [the provided examples](#examples)). -This is the preferred way since it: - - is performance wise better - - reduces the chance of code duplication - - [is suggested by the angularJS team](https://www.youtube.com/watch?feature=player_detailpage&v=ZhfUv0spHCY#t=3048) - - it does not break the matching of the generated DOM elements and the `ng-model`'s items -* `ui-sortable` lists containing many 'types' of items can be implemented by using dynamic template loading [with ng-include](http://stackoverflow.com/questions/14607879/angularjs-load-dynamic-template-html-within-directive/14621927#14621927) or a [loader directive](https://github.com/thgreasi/tg-dynamic-directive), to determine how each model item should be rendered. Also take a look at the [Tree with dynamic template](http://codepen.io/thgreasi/pen/QKmWKj) example. - -### Options - -All the [jQueryUI Sortable options](http://api.jqueryui.com/sortable/) can be passed through the directive. -Additionally, the `ui` argument of the available callbacks gets enriched with some extra properties as specified to the [API.md file](API.md#uiitemsortable-api-documentation). -Any model changes that happen inside the available callbacks, are applied right after the stop event. We are not wrapping callbacks like `start`/`change`/... with `$apply`, in order to minimize the number of digest loops and avoid possible modifications of the model (eg: by watchers) before the drop takes place. - -```js -myAppModule.controller('MyController', function($scope) { - $scope.items = ["One", "Two", "Three"]; - - $scope.sortableOptions = { - update: function(e, ui) { ... }, - axis: 'x' - }; -}); -``` - -```html - -``` - -When using event callbacks ([start](http://api.jqueryui.com/sortable/#event-start)/[update](http://api.jqueryui.com/sortable/#event-update)/[stop](http://api.jqueryui.com/sortable/#event-stop)...), avoid manipulating DOM elements (especially the one with the ng-repeat attached). -The suggested pattern is to use callbacks for emmiting events and altering the scope (inside the 'Angular world'). - -#### ui-floating - -**ui-floating** (default: undefined) -Description: Enables a workaround for smooth horizontal sorting. -Type: [Boolean](http://api.jquery.com/Types/#Boolean)/[String](http://api.jquery.com/Types/#String)/`undefined` -* **undefined**: Relies on jquery.ui to detect the list's orientation. -* **false**: Forces jquery.ui.sortable to detect the list as vertical. -* **true**: Forces jquery.ui.sortable to detect the list as horizontal. -* **"auto"**: Detects on each drag `start` if the element is floating or not. - -To have a smooth horizontal-list reordering, jquery.ui.sortable needs to detect the orientation of the list. -This detection takes place during the initialization of the plugin (and some of the checks include: whether the first item is floating left/right or if 'axis' parameter is 'x', etc). -There is also a [known issue](https://bugs.jqueryui.com/ticket/7498) about initially empty horizontal lists. - -To provide a solution/workaround (till jquery.ui.sortable.refresh() also tests the orientation or a more appropriate method is provided), ui-sortable directive provides a `ui-floating` option as an extra to the [jquery.ui.sortable options](http://api.jqueryui.com/sortable/). - -```html - -``` - -**OR** - -```js -$scope.sortableOptions = { - 'ui-floating': true -}; -``` -```html - -``` - - -#### ui-model-items - -**ui-model-items** (default: `> [ng-repeat],> [data-ng-repeat],> [x-ng-repeat]`) -Description: Defines which elements should be considered as part of your model. -Type: [CSS selector](http://api.jquery.com/Types/#Selector)/[String](http://api.jquery.com/Types/#String) - -This is the model related counterpart option of [jQuery's items option](http://api.jqueryui.com/sortable/#option-items). - -#### ui-preserve-size - -**ui-preserve-size** (default: undefined) -Description: Set's the size of the sorting helper to the size of the original element before the sorting. -Type: [Boolean](http://api.jquery.com/Types/#Boolean)/`undefined` - -This is useful for elements that their size is dependent to other page characteristics. -A representative example of such cases are `` ``s and `
`s. - -### Attributes For Event Handling - -To handle events with html bindings just define any expression to listed event attributes. -If you defined an attribute for this events and defined callback function in sortableOptions at the same time, the attribute based callback will be called first. - -* **ui-sortable-start** -* **ui-sortable-activate** -* **ui-sortable-before-stop** -* **ui-sortable-update** -* **ui-sortable-remove** -* **ui-sortable-receive** -* **ui-sortable-deactivate** -* **ui-sortable-stop** - - - -Expression works on update event. -```html -
    -
  • {{ item }}
  • -
-``` - - -On update event callBackFunction1 if called before callBackFunction2. -```js -$scope.sortableOptions = { - 'update': callBackFunction2 -}; -``` -```html -
    -
  • {{ item }}
  • -
-``` - -### Canceling - -Inside the `update` callback, you can check the item that is dragged and cancel the sorting. - -```js -$scope.sortableOptions = { - update: function(e, ui) { - if (ui.item.sortable.model == "can't be moved") { - ui.item.sortable.cancel(); - } - } -}; -``` - -**Notes:** -* `update` is the appropriate place to cancel a sorting, since it occurs before any model/scope changes but after the DOM position has been updated. -So `ui.item.scope` and the directive's `ng-model`, are equal to the scope before the drag start. -* To [cancel a sorting between connected lists](https://github.com/angular-ui/ui-sortable/issues/107#issuecomment-33633638), `cancel` should be called inside the `update` callback of the originating list. A simple way to is to use the `ui.item.sortable.received` property: -```js -update: function(event, ui) { - if (// ensure we are in the first update() callback - !ui.item.sortable.received && - // check that its an actual moving between the two lists - ui.item.sortable.source[0] !== ui.item.sortable.droptarget[0] && - // check the size limitation - ui.item.sortable.model == "can't be moved between lists") { - ui.item.sortable.cancel(); - } -} -``` - -### jQueryUI Sortable Event order - -**Single sortable** [demo](http://codepen.io/thgreasi/pen/QKmWGj) -``` -create - -/* dragging starts */ -helper -start -activate - -/* multiple: sort/change/over/out */ - -beforeStop -update <= call cancel() here if needed -deactivate -stop -``` - -**Connected sortables** [demo](http://codepen.io/thgreasi/pen/YGazpJ) - -``` -list A: create -list B: create - -/* dragging starts from sortable A to B */ -list A: helper -list A: start -list B: activate -list A: activate - -/* both lists multiple: sort/change/over/out */ -list A: sort -list A: change -list B: change -list B: over -list A: sort -list B: out -list A: sort - -list A: beforeStop -list A: update <= call cancel() here if needed -list A: remove -list B: receive -list B: update -list B: deactivate -list A: deactivate -list A: stop -``` - -For more details about the events check the [jQueryUI API documentation](http://api.jqueryui.com/sortable/). - -## Integrating with directives doing transclusion -Wrap the transclusion directive element with the ui-sortable directive and set the `items` to target your `ng-repeat`ed elements. Following best practices, it is also highly recommended that you add a `track by` expression to your `ng-repeat`. [Angular Material example](http://codepen.io/thgreasi/pen/NbyLVK). - -```js -myAppModule.controller('MyController', function($scope) { - $scope.items = ["One", "Two", "Three"]; - - $scope.sortableOptions = { - items: '.sortable-item' - // It is suggested to use the most specific cssselector you can, - // after analyzing the DOM elements generated by the transclusion directive - // eg: items: '> .transclusionLvl1 > .transclusionLvl2 > .sortable-item' - }; -}); -``` - -```html -
- -
{{ item }}
-
-
-``` - -## Examples - -- [Simple Demo](http://codepen.io/thgreasi/pen/wzmvgw) - - [Simple Attribute Handlers Demo](http://codepen.io/thgreasi/pen/JWbmjb) - - [Simple RequireJS Demo](http://codepen.io/thgreasi/pen/rrdNjj) - - [Simple Touch-Enabled Demo](http://codepen.io/thgreasi/pen/wzmvJv) using [jQuery UI Touch Punch](https://github.com/furf/jquery-ui-touch-punch/) - - [Multiple items sorting (ctrl+click)](http://codepen.io/thgreasi/pen/mJAcL) using [ui-sortable-multiselection](https://github.com/thgreasi/ui-sortable-multiselection) -- [Connected Lists](http://codepen.io/thgreasi/pen/ozqNkr) -- [Filtering](http://codepen.io/thgreasi/pen/XjEWRa) ([details](https://github.com/angular-ui/ui-sortable/issues/113)) -- [Ordering 1](http://codepen.io/thgreasi/pen/PGRomA) & [Ordering 2](http://plnkr.co/edit/gYsZZdFLeoeb5N9iemAO?p=preview) ([details](https://github.com/angular-ui/ui-sortable/issues/70)) -- [Cloning](http://codepen.io/thgreasi/pen/jrzOLA) ([details](https://github.com/angular-ui/ui-sortable/issues/139)) -- [Horizontal List](http://codepen.io/thgreasi/pen/zKWYdP) -- [Tree with dynamic template](http://codepen.io/thgreasi/pen/VKXwzV) -- Canceling - - [Connected Lists With Max Size](http://codepen.io/thgreasi/pen/zKWYEP) - - [Connected Lists Without Duplicates](http://codepen.io/thgreasi/pen/PGRoJr) - - [Promised Reverting](http://codepen.io/thgreasi/pen/ORvJzJ) -- [Locked Items](http://codepen.io/thgreasi/pen/ALyBVQ) -- [Draggable Handle](http://codepen.io/thgreasi/pen/PGRoRY) -- [Drop Zone](http://codepen.io/thgreasi/pen/zKWYWR) -- [Draggable-Sortable like interaction](http://codepen.io/thgreasi/pen/mAxdxk) -- [Static HTML Sorting](http://codepen.io/thgreasi/pen/XjEWqV) - -## Integrations -- [firebase](http://codepen.io/thgreasi/pen/repEZg?editors=0010) -- [ui.bootstrap.accordion](http://plnkr.co/edit/TGIeeEbbvJwpJ3WRqo2z?p=preview) -- [Angular Material](http://codepen.io/thgreasi/pen/NbyLVK) (thanks yenoh2) -- [Asynchronous loading jQuery+jQueryUI with crisbeto/angular-ui-sortable-loader](https://github.com/crisbeto/angular-ui-sortable-loader) - -## Reporting Issues - -The [above](#examples) pen's are provided as a good starting point to demonstrate issues, proposals and use cases. -Feel free to edit any of them for your needs (don't forget to also update the libraries used to your version). - -## Testing - -We use Karma and JSHint to ensure the quality of the code. The easiest way to run these checks is to use grunt: - -```sh -npm install -g grunt-cli -npm install && bower install -grunt -``` - -The karma task will try to open Firefox and Chrome as browser in which to run the tests. Make sure this is available or change the configuration in `test\karma.conf.js`. - - -### Grunt Serve - -We have one task to serve them all! - -```sh -grunt serve -``` - -It's equal to run separately: - -* `grunt connect:server` : giving you a development server at [http://127.0.0.1:8000/](http://127.0.0.1:8000/). - -* `grunt karma:server` : giving you a Karma server to run tests (at [http://localhost:9876/](http://localhost:9876/) by default). You can force a test on this server with `grunt karma:unit:run`. - -* `grunt watch` : will automatically test your code and build your demo. You can demo generation with `grunt build:gh-pages`. diff --git a/assets/css/bootstrap.css b/assets/css/bootstrap.css new file mode 100644 index 0000000..6aef1f6 --- /dev/null +++ b/assets/css/bootstrap.css @@ -0,0 +1,7098 @@ +/*! + * Bootstrap v3.0.2 by @fat and @mdo + * Copyright 2013 Twitter, Inc. + * Licensed under http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world by @mdo and @fat. + */ + +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} + +audio, +canvas, +video { + display: inline-block; +} + +audio:not([controls]) { + display: none; + height: 0; +} + +[hidden], +template { + display: none; +} + +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +body { + margin: 0; +} + +a { + background: transparent; +} + +a:focus { + outline: thin dotted; +} + +a:active, +a:hover { + outline: 0; +} + +h1 { + margin: 0.67em 0; + font-size: 2em; +} + +abbr[title] { + border-bottom: 1px dotted; +} + +b, +strong { + font-weight: bold; +} + +dfn { + font-style: italic; +} + +hr { + height: 0; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +mark { + color: #000; + background: #ff0; +} + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; +} + +pre { + white-space: pre-wrap; +} + +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} + +small { + font-size: 80%; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +img { + border: 0; +} + +svg:not(:root) { + overflow: hidden; +} + +figure { + margin: 0; +} + +fieldset { + padding: 0.35em 0.625em 0.75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} + +legend { + padding: 0; + border: 0; +} + +button, +input, +select, +textarea { + margin: 0; + font-family: inherit; + font-size: 100%; +} + +button, +input { + line-height: normal; +} + +button, +select { + text-transform: none; +} + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} + +button[disabled], +html input[disabled] { + cursor: default; +} + +input[type="checkbox"], +input[type="radio"] { + padding: 0; + box-sizing: border-box; +} + +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} + +textarea { + overflow: auto; + vertical-align: top; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +@media print { + * { + color: #000 !important; + text-shadow: none !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; + } + @page { + margin: 2cm .5cm; + } + 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; + } +} + +*, +*: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.428571429; + color: #333333; + background-color: #ffffff; +} + +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +a { + color: #428bca; + text-decoration: none; +} + +a:hover, +a:focus { + color: #2a6496; + text-decoration: underline; +} + +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +img { + vertical-align: middle; +} + +.img-responsive { + display: block; + height: auto; + max-width: 100%; +} + +.img-rounded { + border-radius: 6px; +} + +.img-thumbnail { + display: inline-block; + height: auto; + max-width: 100%; + padding: 4px; + line-height: 1.428571429; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +.img-circle { + border-radius: 50%; +} + +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eeeeee; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} + +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-muted { + color: #999999; +} + +.text-primary { + color: #428bca; +} + +.text-primary:hover { + color: #3071a9; +} + +.text-warning { + color: #c09853; +} + +.text-warning:hover { + color: #a47e3c; +} + +.text-danger { + color: #b94a48; +} + +.text-danger:hover { + color: #953b39; +} + +.text-success { + color: #468847; +} + +.text-success:hover { + color: #356635; +} + +.text-info { + color: #3a87ad; +} + +.text-info:hover { + color: #2d6987; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-center { + text-align: center; +} + +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + 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: #999999; +} + +h1, +h2, +h3 { + margin-top: 20px; + margin-bottom: 10px; +} + +h1 small, +h2 small, +h3 small, +h1 .small, +h2 .small, +h3 .small { + font-size: 65%; +} + +h4, +h5, +h6 { + margin-top: 10px; + margin-bottom: 10px; +} + +h4 small, +h5 small, +h6 small, +h4 .small, +h5 .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; +} + +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eeeeee; +} + +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; +} + +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} + +.list-inline > li:first-child { + padding-left: 0; +} + +dl { + margin-bottom: 20px; +} + +dt, +dd { + line-height: 1.428571429; +} + +dt { + font-weight: bold; +} + +dd { + margin-left: 0; +} + +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } + .dl-horizontal dd:before, + .dl-horizontal dd:after { + display: table; + content: " "; + } + .dl-horizontal dd:after { + clear: both; + } + .dl-horizontal dd:before, + .dl-horizontal dd:after { + display: table; + content: " "; + } + .dl-horizontal dd:after { + clear: both; + } +} + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} + +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + border-left: 5px solid #eeeeee; +} + +blockquote p { + font-size: 17.5px; + font-weight: 300; + line-height: 1.25; +} + +blockquote p:last-child { + margin-bottom: 0; +} + +blockquote small { + display: block; + line-height: 1.428571429; + color: #999999; +} + +blockquote small:before { + content: '\2014 \00A0'; +} + +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} + +blockquote.pull-right p, +blockquote.pull-right small, +blockquote.pull-right .small { + text-align: right; +} + +blockquote.pull-right small:before, +blockquote.pull-right .small:before { + content: ''; +} + +blockquote.pull-right 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.428571429; +} + +code, +kbd, +pre, +samp { + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; +} + +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + white-space: nowrap; + background-color: #f9f2f4; + border-radius: 4px; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.428571429; + color: #333333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #cccccc; + 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 { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +.container:before, +.container:after { + display: table; + content: " "; +} + +.container:after { + clear: both; +} + +.container:before, +.container:after { + display: table; + content: " "; +} + +.container:after { + clear: both; +} + +.row { + margin-right: -15px; + margin-left: -15px; +} + +.row:before, +.row:after { + display: table; + content: " "; +} + +.row:after { + clear: both; +} + +.row:before, +.row:after { + display: table; + content: " "; +} + +.row:after { + clear: both; +} + +.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-right: 15px; + padding-left: 15px; +} + +.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 { + float: left; +} + +.col-xs-12 { + width: 100%; +} + +.col-xs-11 { + width: 91.66666666666666%; +} + +.col-xs-10 { + width: 83.33333333333334%; +} + +.col-xs-9 { + width: 75%; +} + +.col-xs-8 { + width: 66.66666666666666%; +} + +.col-xs-7 { + width: 58.333333333333336%; +} + +.col-xs-6 { + width: 50%; +} + +.col-xs-5 { + width: 41.66666666666667%; +} + +.col-xs-4 { + width: 33.33333333333333%; +} + +.col-xs-3 { + width: 25%; +} + +.col-xs-2 { + width: 16.666666666666664%; +} + +.col-xs-1 { + width: 8.333333333333332%; +} + +.col-xs-pull-12 { + right: 100%; +} + +.col-xs-pull-11 { + right: 91.66666666666666%; +} + +.col-xs-pull-10 { + right: 83.33333333333334%; +} + +.col-xs-pull-9 { + right: 75%; +} + +.col-xs-pull-8 { + right: 66.66666666666666%; +} + +.col-xs-pull-7 { + right: 58.333333333333336%; +} + +.col-xs-pull-6 { + right: 50%; +} + +.col-xs-pull-5 { + right: 41.66666666666667%; +} + +.col-xs-pull-4 { + right: 33.33333333333333%; +} + +.col-xs-pull-3 { + right: 25%; +} + +.col-xs-pull-2 { + right: 16.666666666666664%; +} + +.col-xs-pull-1 { + right: 8.333333333333332%; +} + +.col-xs-pull-0 { + right: 0; +} + +.col-xs-push-12 { + left: 100%; +} + +.col-xs-push-11 { + left: 91.66666666666666%; +} + +.col-xs-push-10 { + left: 83.33333333333334%; +} + +.col-xs-push-9 { + left: 75%; +} + +.col-xs-push-8 { + left: 66.66666666666666%; +} + +.col-xs-push-7 { + left: 58.333333333333336%; +} + +.col-xs-push-6 { + left: 50%; +} + +.col-xs-push-5 { + left: 41.66666666666667%; +} + +.col-xs-push-4 { + left: 33.33333333333333%; +} + +.col-xs-push-3 { + left: 25%; +} + +.col-xs-push-2 { + left: 16.666666666666664%; +} + +.col-xs-push-1 { + left: 8.333333333333332%; +} + +.col-xs-push-0 { + left: 0; +} + +.col-xs-offset-12 { + margin-left: 100%; +} + +.col-xs-offset-11 { + margin-left: 91.66666666666666%; +} + +.col-xs-offset-10 { + margin-left: 83.33333333333334%; +} + +.col-xs-offset-9 { + margin-left: 75%; +} + +.col-xs-offset-8 { + margin-left: 66.66666666666666%; +} + +.col-xs-offset-7 { + margin-left: 58.333333333333336%; +} + +.col-xs-offset-6 { + margin-left: 50%; +} + +.col-xs-offset-5 { + margin-left: 41.66666666666667%; +} + +.col-xs-offset-4 { + margin-left: 33.33333333333333%; +} + +.col-xs-offset-3 { + margin-left: 25%; +} + +.col-xs-offset-2 { + margin-left: 16.666666666666664%; +} + +.col-xs-offset-1 { + margin-left: 8.333333333333332%; +} + +.col-xs-offset-0 { + margin-left: 0; +} + +@media (min-width: 768px) { + .container { + width: 750px; + } + .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 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666666666666%; + } + .col-sm-10 { + width: 83.33333333333334%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666666666666%; + } + .col-sm-7 { + width: 58.333333333333336%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666666666667%; + } + .col-sm-4 { + width: 33.33333333333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.666666666666664%; + } + .col-sm-1 { + width: 8.333333333333332%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666666666666%; + } + .col-sm-pull-10 { + right: 83.33333333333334%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666666666666%; + } + .col-sm-pull-7 { + right: 58.333333333333336%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666666666667%; + } + .col-sm-pull-4 { + right: 33.33333333333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.666666666666664%; + } + .col-sm-pull-1 { + right: 8.333333333333332%; + } + .col-sm-pull-0 { + right: 0; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666666666666%; + } + .col-sm-push-10 { + left: 83.33333333333334%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666666666666%; + } + .col-sm-push-7 { + left: 58.333333333333336%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666666666667%; + } + .col-sm-push-4 { + left: 33.33333333333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.666666666666664%; + } + .col-sm-push-1 { + left: 8.333333333333332%; + } + .col-sm-push-0 { + left: 0; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666666666666%; + } + .col-sm-offset-10 { + margin-left: 83.33333333333334%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666666666666%; + } + .col-sm-offset-7 { + margin-left: 58.333333333333336%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666666666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.666666666666664%; + } + .col-sm-offset-1 { + margin-left: 8.333333333333332%; + } + .col-sm-offset-0 { + margin-left: 0; + } +} + +@media (min-width: 992px) { + .container { + width: 970px; + } + .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 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666666666666%; + } + .col-md-10 { + width: 83.33333333333334%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666666666666%; + } + .col-md-7 { + width: 58.333333333333336%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666666666667%; + } + .col-md-4 { + width: 33.33333333333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.666666666666664%; + } + .col-md-1 { + width: 8.333333333333332%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666666666666%; + } + .col-md-pull-10 { + right: 83.33333333333334%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666666666666%; + } + .col-md-pull-7 { + right: 58.333333333333336%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666666666667%; + } + .col-md-pull-4 { + right: 33.33333333333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.666666666666664%; + } + .col-md-pull-1 { + right: 8.333333333333332%; + } + .col-md-pull-0 { + right: 0; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666666666666%; + } + .col-md-push-10 { + left: 83.33333333333334%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666666666666%; + } + .col-md-push-7 { + left: 58.333333333333336%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666666666667%; + } + .col-md-push-4 { + left: 33.33333333333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.666666666666664%; + } + .col-md-push-1 { + left: 8.333333333333332%; + } + .col-md-push-0 { + left: 0; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666666666666%; + } + .col-md-offset-10 { + margin-left: 83.33333333333334%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666666666666%; + } + .col-md-offset-7 { + margin-left: 58.333333333333336%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666666666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.666666666666664%; + } + .col-md-offset-1 { + margin-left: 8.333333333333332%; + } + .col-md-offset-0 { + margin-left: 0; + } +} + +@media (min-width: 1200px) { + .container { + width: 1170px; + } + .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 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666666666666%; + } + .col-lg-10 { + width: 83.33333333333334%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666666666666%; + } + .col-lg-7 { + width: 58.333333333333336%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666666666667%; + } + .col-lg-4 { + width: 33.33333333333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.666666666666664%; + } + .col-lg-1 { + width: 8.333333333333332%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666666666666%; + } + .col-lg-pull-10 { + right: 83.33333333333334%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666666666666%; + } + .col-lg-pull-7 { + right: 58.333333333333336%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666666666667%; + } + .col-lg-pull-4 { + right: 33.33333333333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.666666666666664%; + } + .col-lg-pull-1 { + right: 8.333333333333332%; + } + .col-lg-pull-0 { + right: 0; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666666666666%; + } + .col-lg-push-10 { + left: 83.33333333333334%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666666666666%; + } + .col-lg-push-7 { + left: 58.333333333333336%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666666666667%; + } + .col-lg-push-4 { + left: 33.33333333333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.666666666666664%; + } + .col-lg-push-1 { + left: 8.333333333333332%; + } + .col-lg-push-0 { + left: 0; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666666666666%; + } + .col-lg-offset-10 { + margin-left: 83.33333333333334%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666666666666%; + } + .col-lg-offset-7 { + margin-left: 58.333333333333336%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666666666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.666666666666664%; + } + .col-lg-offset-1 { + margin-left: 8.333333333333332%; + } + .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.428571429; + vertical-align: top; + border-top: 1px solid #dddddd; +} + +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #dddddd; +} + +.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 #dddddd; +} + +.table .table { + background-color: #ffffff; +} + +.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 #dddddd; +} + +.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 #dddddd; +} + +.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-"] { + display: table-column; + float: none; +} + +table td[class*="col-"], +table th[class*="col-"] { + display: table-cell; + float: none; +} + +.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 > 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.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; +} + +.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; +} + +@media (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-x: scroll; + overflow-y: hidden; + border: 1px solid #dddddd; + -ms-overflow-style: -ms-autohiding-scrollbar; + -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; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333333; + 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; + /* IE8-9 */ + + line-height: normal; +} + +input[type="file"] { + display: block; +} + +select[multiple], +select[size] { + height: auto; +} + +select optgroup { + font-family: inherit; + font-size: inherit; + font-style: inherit; +} + +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +input[type="number"]::-webkit-outer-spin-button, +input[type="number"]::-webkit-inner-spin-button { + height: auto; +} + +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.428571429; + color: #555555; + vertical-align: middle; +} + +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.428571429; + color: #555555; + vertical-align: middle; + background-color: #ffffff; + background-image: none; + border: 1px solid #cccccc; + 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 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} + +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); +} + +.form-control:-moz-placeholder { + color: #999999; +} + +.form-control::-moz-placeholder { + color: #999999; +} + +.form-control:-ms-input-placeholder { + color: #999999; +} + +.form-control::-webkit-input-placeholder { + color: #999999; +} + +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eeeeee; +} + +textarea.form-control { + height: auto; +} + +.form-group { + margin-bottom: 15px; +} + +.radio, +.checkbox { + display: block; + min-height: 20px; + padding-left: 20px; + margin-top: 10px; + margin-bottom: 10px; + vertical-align: middle; +} + +.radio label, +.checkbox label { + display: inline; + margin-bottom: 0; + 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; + font-weight: normal; + vertical-align: middle; + 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 { + height: auto; +} + +.input-lg { + height: 45px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +select.input-lg { + height: 45px; + line-height: 45px; +} + +textarea.input-lg { + height: auto; +} + +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline { + color: #c09853; +} + +.has-warning .form-control { + border-color: #c09853; + -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: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} + +.has-warning .input-group-addon { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} + +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline { + color: #b94a48; +} + +.has-error .form-control { + border-color: #b94a48; + -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: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} + +.has-error .input-group-addon { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} + +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline { + color: #468847; +} + +.has-success .form-control { + border-color: #468847; + -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: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} + +.has-success .input-group-addon { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} + +.form-control-static { + margin-bottom: 0; +} + +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} + +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; + } +} + +.form-horizontal .control-label, +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} + +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} + +.form-horizontal .form-group:before, +.form-horizontal .form-group:after { + display: table; + content: " "; +} + +.form-horizontal .form-group:after { + clear: both; +} + +.form-horizontal .form-group:before, +.form-horizontal .form-group:after { + display: table; + content: " "; +} + +.form-horizontal .form-group:after { + clear: both; +} + +.form-horizontal .form-control-static { + padding-top: 7px; +} + +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + } +} + +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.428571429; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} + +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; +} + +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -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 { + pointer-events: none; + cursor: not-allowed; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; +} + +.btn-default { + color: #333333; + background-color: #ffffff; + border-color: #cccccc; +} + +.btn-default:hover, +.btn-default:focus, +.btn-default:active, +.btn-default.active, +.open .dropdown-toggle.btn-default { + color: #333333; + 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: #ffffff; + border-color: #cccccc; +} + +.btn-primary { + color: #ffffff; + background-color: #428bca; + border-color: #357ebd; +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + color: #ffffff; + background-color: #3276b1; + border-color: #285e8e; +} + +.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: #428bca; + border-color: #357ebd; +} + +.btn-warning { + color: #ffffff; + background-color: #f0ad4e; + border-color: #eea236; +} + +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.open .dropdown-toggle.btn-warning { + color: #ffffff; + background-color: #ed9c28; + border-color: #d58512; +} + +.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: #f0ad4e; + border-color: #eea236; +} + +.btn-danger { + color: #ffffff; + background-color: #d9534f; + border-color: #d43f3a; +} + +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.open .dropdown-toggle.btn-danger { + color: #ffffff; + background-color: #d2322d; + border-color: #ac2925; +} + +.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: #d9534f; + border-color: #d43f3a; +} + +.btn-success { + color: #ffffff; + background-color: #5cb85c; + border-color: #4cae4c; +} + +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.open .dropdown-toggle.btn-success { + color: #ffffff; + background-color: #47a447; + border-color: #398439; +} + +.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: #5cb85c; + border-color: #4cae4c; +} + +.btn-info { + color: #ffffff; + background-color: #5bc0de; + border-color: #46b8da; +} + +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.open .dropdown-toggle.btn-info { + color: #ffffff; + background-color: #39b3d7; + border-color: #269abc; +} + +.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: #5bc0de; + border-color: #46b8da; +} + +.btn-link { + font-weight: normal; + color: #428bca; + 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: #2a6496; + 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: #999999; + text-decoration: none; +} + +.btn-lg { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +.btn-sm, +.btn-xs { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.btn-xs { + padding: 1px 5px; +} + +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 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 0.15s linear; + transition: opacity 0.15s linear; +} + +.fade.in { + opacity: 1; +} + +.collapse { + display: none; +} + +.collapse.in { + display: block; +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + transition: height 0.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'; + -webkit-font-smoothing: antialiased; + font-style: normal; + font-weight: normal; + line-height: 1; + -moz-osx-font-smoothing: grayscale; +} + +.glyphicon:empty { + width: 1em; +} + +.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 #000000; + border-right: 4px solid transparent; + border-bottom: 0 dotted; + 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; + font-size: 14px; + list-style: none; + background-color: #ffffff; + border: 1px solid #cccccc; + 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.428571429; + color: #333333; + white-space: nowrap; +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; +} + +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + background-color: #428bca; + outline: 0; +} + +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} + +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.open > .dropdown-menu { + display: block; +} + +.open > a { + outline: 0; +} + +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.428571429; + color: #999999; +} + +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} + +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0 dotted; + border-bottom: 4px solid #000000; + 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 { + right: 0; + left: auto; + } +} + +.btn-default .caret { + border-top-color: #333333; +} + +.btn-primary .caret, +.btn-success .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret { + border-top-color: #fff; +} + +.dropup .btn-default .caret { + border-bottom-color: #333333; +} + +.dropup .btn-primary .caret, +.dropup .btn-success .caret, +.dropup .btn-warning .caret, +.dropup .btn-danger .caret, +.dropup .btn-info .caret { + border-bottom-color: #fff; +} + +.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:before, +.btn-toolbar:after { + display: table; + content: " "; +} + +.btn-toolbar:after { + clear: both; +} + +.btn-toolbar:before, +.btn-toolbar:after { + display: table; + content: " "; +} + +.btn-toolbar:after { + clear: both; +} + +.btn-toolbar .btn-group { + float: left; +} + +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group, +.btn-toolbar > .btn-group + .btn-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-top-right-radius: 0; + border-bottom-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-top-right-radius: 0; + border-bottom-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-xs > .btn { + padding: 5px 10px; + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} + +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 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 { + display: block; + float: none; + width: 100%; + max-width: 100%; +} + +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after { + display: table; + content: " "; +} + +.btn-group-vertical > .btn-group:after { + clear: both; +} + +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after { + display: table; + content: " "; +} + +.btn-group-vertical > .btn-group:after { + clear: both; +} + +.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-top-right-radius: 0; + border-bottom-left-radius: 4px; + 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 > .btn:last-child, +.btn-group-vertical > .btn-group:first-child > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.btn-group-vertical > .btn-group:last-child > .btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +.btn-group-justified { + display: table; + width: 100%; + border-collapse: separate; + table-layout: fixed; +} + +.btn-group-justified .btn { + display: table-cell; + float: none; + width: 1%; +} + +[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.col { + float: none; + padding-right: 0; + padding-left: 0; +} + +.input-group .form-control { + width: 100%; + margin-bottom: 0; +} + +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 45px; + 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: 45px; + line-height: 45px; +} + +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.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 { + 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: #555555; + text-align: center; + background-color: #eeeeee; + border: 1px solid #cccccc; + 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 > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-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 > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.input-group-addon:last-child { + border-left: 0; +} + +.input-group-btn { + position: relative; + white-space: nowrap; +} + +.input-group-btn:first-child > .btn { + margin-right: -1px; +} + +.input-group-btn:last-child > .btn { + margin-left: -1px; +} + +.input-group-btn > .btn { + position: relative; +} + +.input-group-btn > .btn + .btn { + margin-left: -4px; +} + +.input-group-btn > .btn:hover, +.input-group-btn > .btn:active { + z-index: 2; +} + +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav:before, +.nav:after { + display: table; + content: " "; +} + +.nav:after { + clear: both; +} + +.nav:before, +.nav:after { + display: table; + content: " "; +} + +.nav:after { + clear: both; +} + +.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: #eeeeee; +} + +.nav > li.disabled > a { + color: #999999; +} + +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #999999; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} + +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eeeeee; + border-color: #428bca; +} + +.nav .open > a .caret, +.nav .open > a:hover .caret, +.nav .open > a:focus .caret { + border-top-color: #2a6496; + border-bottom-color: #2a6496; +} + +.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 #dddddd; +} + +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} + +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.428571429; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} + +.nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #dddddd; +} + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555555; + cursor: default; + background-color: #ffffff; + border: 1px solid #dddddd; + border-bottom-color: transparent; +} + +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} + +.nav-tabs.nav-justified > li { + float: none; +} + +.nav-tabs.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} + +.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 #dddddd; +} + +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #dddddd; + 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: #ffffff; + } +} + +.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: #ffffff; + background-color: #428bca; +} + +.nav-pills > li.active > a .caret, +.nav-pills > li.active > a:hover .caret, +.nav-pills > li.active > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.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 { + margin-bottom: 5px; + text-align: center; +} + +.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 #dddddd; +} + +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #dddddd; + 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: #ffffff; + } +} + +.tab-content > .tab-pane { + display: none; +} + +.tab-content > .active { + display: block; +} + +.nav .caret { + border-top-color: #428bca; + border-bottom-color: #428bca; +} + +.nav a:hover .caret { + border-top-color: #2a6496; + border-bottom-color: #2a6496; +} + +.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; +} + +.navbar:before, +.navbar:after { + display: table; + content: " "; +} + +.navbar:after { + clear: both; +} + +.navbar:before, +.navbar:after { + display: table; + content: " "; +} + +.navbar:after { + clear: both; +} + +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} + +.navbar-header:before, +.navbar-header:after { + display: table; + content: " "; +} + +.navbar-header:after { + clear: both; +} + +.navbar-header:before, +.navbar-header:after { + display: table; + content: " "; +} + +.navbar-header:after { + clear: both; +} + +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} + +.navbar-collapse { + max-height: 340px; + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; +} + +.navbar-collapse:before, +.navbar-collapse:after { + display: table; + content: " "; +} + +.navbar-collapse:after { + clear: both; +} + +.navbar-collapse:before, +.navbar-collapse:after { + display: table; + content: " "; +} + +.navbar-collapse:after { + clear: both; +} + +.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: auto; + } + .navbar-collapse .navbar-nav.navbar-left:first-child { + margin-left: -15px; + } + .navbar-collapse .navbar-nav.navbar-right:last-child { + margin-right: -15px; + } + .navbar-collapse .navbar-text:last-child { + margin-right: 0; + } +} + +.container > .navbar-header, +.container > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} + +@media (min-width: 768px) { + .container > .navbar-header, + .container > .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 15px; + font-size: 18px; + line-height: 20px; +} + +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} + +@media (min-width: 768px) { + .navbar > .container .navbar-brand { + margin-left: -15px; + } +} + +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + border: 1px solid transparent; + border-radius: 4px; +} + +.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 -15px; +} + +.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; + } +} + +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + } +} + +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + 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); +} + +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; + } +} + +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } +} + +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} + +.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-nav.pull-right > li > .dropdown-menu, +.navbar-nav > li > .dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} + +.navbar-text { + float: left; + margin-top: 15px; + margin-bottom: 15px; +} + +@media (min-width: 768px) { + .navbar-text { + margin-right: 15px; + margin-left: 15px; + } +} + +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} + +.navbar-default .navbar-brand { + color: #777777; +} + +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} + +.navbar-default .navbar-text { + color: #777777; +} + +.navbar-default .navbar-nav > li > a { + color: #777777; +} + +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333333; + background-color: transparent; +} + +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555555; + background-color: #e7e7e7; +} + +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #cccccc; + background-color: transparent; +} + +.navbar-default .navbar-toggle { + border-color: #dddddd; +} + +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #dddddd; +} + +.navbar-default .navbar-toggle .icon-bar { + background-color: #cccccc; +} + +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} + +.navbar-default .navbar-nav > .dropdown > a:hover .caret, +.navbar-default .navbar-nav > .dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} + +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555555; + background-color: #e7e7e7; +} + +.navbar-default .navbar-nav > .open > a .caret, +.navbar-default .navbar-nav > .open > a:hover .caret, +.navbar-default .navbar-nav > .open > a:focus .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.navbar-default .navbar-nav > .dropdown > a .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} + +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333333; + 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: #555555; + 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: #cccccc; + background-color: transparent; + } +} + +.navbar-default .navbar-link { + color: #777777; +} + +.navbar-default .navbar-link:hover { + color: #333333; +} + +.navbar-inverse { + background-color: #222222; + border-color: #080808; +} + +.navbar-inverse .navbar-brand { + color: #999999; +} + +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .navbar-text { + color: #999999; +} + +.navbar-inverse .navbar-nav > li > a { + color: #999999; +} + +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #ffffff; + background-color: #080808; +} + +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444444; + background-color: transparent; +} + +.navbar-inverse .navbar-toggle { + border-color: #333333; +} + +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333333; +} + +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #ffffff; +} + +.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 { + color: #ffffff; + background-color: #080808; +} + +.navbar-inverse .navbar-nav > .dropdown > a:hover .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .navbar-nav > .dropdown > a .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} + +.navbar-inverse .navbar-nav > .open > a .caret, +.navbar-inverse .navbar-nav > .open > a:hover .caret, +.navbar-inverse .navbar-nav > .open > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #999999; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #ffffff; + 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: #ffffff; + 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: #444444; + background-color: transparent; + } +} + +.navbar-inverse .navbar-link { + color: #999999; +} + +.navbar-inverse .navbar-link:hover { + color: #ffffff; +} + +.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 { + padding: 0 5px; + color: #cccccc; + content: "/\00a0"; +} + +.breadcrumb > .active { + color: #999999; +} + +.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; + margin-left: -1px; + line-height: 1.428571429; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; +} + +.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-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + background-color: #eeeeee; +} + +.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: #ffffff; + cursor: default; + background-color: #428bca; + border-color: #428bca; +} + +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #999999; + cursor: not-allowed; + background-color: #ffffff; + border-color: #dddddd; +} + +.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-top-right-radius: 6px; + border-bottom-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-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} + +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} + +.pager:before, +.pager:after { + display: table; + content: " "; +} + +.pager:after { + clear: both; +} + +.pager:before, +.pager:after { + display: table; + content: " "; +} + +.pager:after { + clear: both; +} + +.pager li { + display: inline; +} + +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 15px; +} + +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} + +.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: #999999; + cursor: not-allowed; + background-color: #ffffff; +} + +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} + +.label[href]:hover, +.label[href]:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.label:empty { + display: none; +} + +.label-default { + background-color: #999999; +} + +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #808080; +} + +.label-primary { + background-color: #428bca; +} + +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #3071a9; +} + +.label-success { + background-color: #5cb85c; +} + +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} + +.label-info { + background-color: #5bc0de; +} + +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} + +.label-warning { + background-color: #f0ad4e; +} + +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} + +.label-danger { + background-color: #d9534f; +} + +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} + +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + background-color: #999999; + border-radius: 10px; +} + +.badge:empty { + display: none; +} + +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.btn .badge { + position: relative; + top: -1px; +} + +a.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #428bca; + background-color: #ffffff; +} + +.nav-pills > li > a > .badge { + margin-left: 3px; +} + +.jumbotron { + padding: 30px; + margin-bottom: 30px; + font-size: 21px; + font-weight: 200; + line-height: 2.1428571435; + color: inherit; + background-color: #eeeeee; +} + +.jumbotron h1 { + line-height: 1; + color: inherit; +} + +.jumbotron p { + line-height: 1.4; +} + +.container .jumbotron { + border-radius: 6px; +} + +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1 { + font-size: 63px; + } +} + +.thumbnail { + display: inline-block; + display: block; + height: auto; + max-width: 100%; + padding: 4px; + margin-bottom: 20px; + line-height: 1.428571429; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +.thumbnail > img { + display: block; + height: auto; + max-width: 100%; + margin-right: auto; + margin-left: auto; +} + +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #428bca; +} + +.thumbnail .caption { + padding: 9px; + color: #333333; +} + +.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 { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.alert-success hr { + border-top-color: #c9e2b3; +} + +.alert-success .alert-link { + color: #356635; +} + +.alert-info { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.alert-info hr { + border-top-color: #a6e1ec; +} + +.alert-info .alert-link { + color: #2d6987; +} + +.alert-warning { + color: #c09853; + background-color: #fcf8e3; + border-color: #faebcc; +} + +.alert-warning hr { + border-top-color: #f7e1b5; +} + +.alert-warning .alert-link { + color: #a47e3c; +} + +.alert-danger { + color: #b94a48; + background-color: #f2dede; + border-color: #ebccd1; +} + +.alert-danger hr { + border-top-color: #e4b9c0; +} + +.alert-danger .alert-link { + color: #953b39; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + 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: #ffffff; + text-align: center; + background-color: #428bca; + -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 0.6s ease; + transition: width 0.6s ease; +} + +.progress-striped .progress-bar { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + 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: -moz-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: #5cb85c; +} + +.progress-striped .progress-bar-success { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + 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: -moz-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: #5bc0de; +} + +.progress-striped .progress-bar-info { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + 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: -moz-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: #f0ad4e; +} + +.progress-striped .progress-bar-warning { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + 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: -moz-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: #d9534f; +} + +.progress-striped .progress-bar-danger { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + 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: -moz-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 { + padding-left: 0; + margin-bottom: 20px; +} + +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #ffffff; + border: 1px solid #dddddd; +} + +.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: #555555; +} + +a.list-group-item .list-group-item-heading { + color: #333333; +} + +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: #ffffff; + background-color: #428bca; + border-color: #428bca; +} + +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: #e1edf7; +} + +.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: #ffffff; + 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-body:before, +.panel-body:after { + display: table; + content: " "; +} + +.panel-body:after { + clear: both; +} + +.panel-body:before, +.panel-body:after { + display: table; + content: " "; +} + +.panel-body:after { + clear: both; +} + +.panel > .list-group { + margin-bottom: 0; +} + +.panel > .list-group .list-group-item { + border-width: 1px 0; +} + +.panel > .list-group .list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +.panel > .list-group .list-group-item:last-child { + border-bottom: 0; +} + +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} + +.panel > .table, +.panel > .table-responsive { + margin-bottom: 0; +} + +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive { + border-top: 1px solid #dddddd; +} + +.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:last-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:last-child > th, +.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, +.panel > .table-bordered > thead > tr:last-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:last-child > td, +.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 { + border-bottom: 0; +} + +.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; +} + +.panel-title > a { + color: inherit; +} + +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #dddddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} + +.panel-group .panel { + margin-bottom: 0; + overflow: hidden; + border-radius: 4px; +} + +.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 #dddddd; +} + +.panel-group .panel-footer { + border-top: 0; +} + +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #dddddd; +} + +.panel-default { + border-color: #dddddd; +} + +.panel-default > .panel-heading { + color: #333333; + background-color: #f5f5f5; + border-color: #dddddd; +} + +.panel-default > .panel-heading + .panel-collapse .panel-body { + border-top-color: #dddddd; +} + +.panel-default > .panel-heading > .dropdown .caret { + border-color: #333333 transparent; +} + +.panel-default > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #dddddd; +} + +.panel-primary { + border-color: #428bca; +} + +.panel-primary > .panel-heading { + color: #ffffff; + background-color: #428bca; + border-color: #428bca; +} + +.panel-primary > .panel-heading + .panel-collapse .panel-body { + border-top-color: #428bca; +} + +.panel-primary > .panel-heading > .dropdown .caret { + border-color: #ffffff transparent; +} + +.panel-primary > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #428bca; +} + +.panel-success { + border-color: #d6e9c6; +} + +.panel-success > .panel-heading { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.panel-success > .panel-heading + .panel-collapse .panel-body { + border-top-color: #d6e9c6; +} + +.panel-success > .panel-heading > .dropdown .caret { + border-color: #468847 transparent; +} + +.panel-success > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #d6e9c6; +} + +.panel-warning { + border-color: #faebcc; +} + +.panel-warning > .panel-heading { + color: #c09853; + background-color: #fcf8e3; + border-color: #faebcc; +} + +.panel-warning > .panel-heading + .panel-collapse .panel-body { + border-top-color: #faebcc; +} + +.panel-warning > .panel-heading > .dropdown .caret { + border-color: #c09853 transparent; +} + +.panel-warning > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #faebcc; +} + +.panel-danger { + border-color: #ebccd1; +} + +.panel-danger > .panel-heading { + color: #b94a48; + background-color: #f2dede; + border-color: #ebccd1; +} + +.panel-danger > .panel-heading + .panel-collapse .panel-body { + border-top-color: #ebccd1; +} + +.panel-danger > .panel-heading > .dropdown .caret { + border-color: #b94a48 transparent; +} + +.panel-danger > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #ebccd1; +} + +.panel-info { + border-color: #bce8f1; +} + +.panel-info > .panel-heading { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.panel-info > .panel-heading + .panel-collapse .panel-body { + border-top-color: #bce8f1; +} + +.panel-info > .panel-heading > .dropdown .caret { + border-color: #3a87ad transparent; +} + +.panel-info > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #bce8f1; +} + +.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: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} + +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity=50); +} + +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} + +.modal-open { + overflow: hidden; +} + +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + display: none; + overflow: auto; + overflow-y: scroll; +} + +.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; + z-index: 1050; + width: auto; + padding: 10px; + margin-right: auto; + margin-left: auto; +} + +.modal-content { + position: relative; + background-color: #ffffff; + border: 1px solid #999999; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + outline: none; + -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; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; + background-color: #000000; +} + +.modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); +} + +.modal-backdrop.in { + opacity: 0.5; + filter: alpha(opacity=50); +} + +.modal-header { + min-height: 16.428571429px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} + +.modal-header .close { + margin-top: -2px; +} + +.modal-title { + margin: 0; + line-height: 1.428571429; +} + +.modal-body { + position: relative; + padding: 20px; +} + +.modal-footer { + padding: 19px 20px 20px; + margin-top: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} + +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} + +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} + +@media screen and (min-width: 768px) { + .modal-dialog { + width: 600px; + padding-top: 30px; + padding-bottom: 30px; + } + .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); + } +} + +.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 12px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} + +.tooltip.in { + opacity: 0.9; + filter: alpha(opacity=90); +} + +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} + +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} + +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} + +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} + +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + 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-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.top-left .tooltip-arrow { + bottom: 0; + left: 5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.top-right .tooltip-arrow { + right: 5px; + bottom: 0; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-right-color: #000000; + border-width: 5px 5px 5px 0; +} + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-left-color: #000000; + border-width: 5px 0 5px 5px; +} + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.tooltip.bottom-left .tooltip-arrow { + top: 0; + left: 5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.tooltip.bottom-right .tooltip-arrow { + top: 0; + right: 5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #ffffff; + border: 1px solid #cccccc; + 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); + background-clip: padding-box; +} + +.popover.top { + margin-top: -10px; +} + +.popover.right { + margin-left: 10px; +} + +.popover.bottom { + margin-top: 10px; +} + +.popover.left { + margin-left: -10px; +} + +.popover-title { + padding: 8px 14px; + margin: 0; + 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 { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999999; + border-top-color: rgba(0, 0, 0, 0.25); + border-bottom-width: 0; +} + +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-top-color: #ffffff; + border-bottom-width: 0; + content: " "; +} + +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999999; + border-right-color: rgba(0, 0, 0, 0.25); + border-left-width: 0; +} + +.popover.right .arrow:after { + bottom: -10px; + left: 1px; + border-right-color: #ffffff; + border-left-width: 0; + content: " "; +} + +.popover.bottom .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-bottom-color: #999999; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-top-width: 0; +} + +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-bottom-color: #ffffff; + border-top-width: 0; + content: " "; +} + +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-left-color: #999999; + border-left-color: rgba(0, 0, 0, 0.25); + border-right-width: 0; +} + +.popover.left .arrow:after { + right: 1px; + bottom: -10px; + border-left-color: #ffffff; + border-right-width: 0; + content: " "; +} + +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} + +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + height: auto; + max-width: 100%; + 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; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + opacity: 0.5; + filter: alpha(opacity=50); +} + +.carousel-control.left { + background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001))); + 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: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5) 0, 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 { + right: 0; + left: auto; + background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5))); + 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: -moz-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0, 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 { + color: #ffffff; + text-decoration: none; + opacity: 0.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%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} + +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #ffffff; + border-radius: 10px; +} + +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #ffffff; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #ffffff; + 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 .glyphicons-chevron-left, + .carousel-control .glyphicons-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 { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} + +.clearfix:before, +.clearfix:after { + display: table; + content: " "; +} + +.clearfix:after { + clear: both; +} + +.center-block { + display: block; + margin-right: auto; + margin-left: 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, +tr.visible-xs, +th.visible-xs, +td.visible-xs { + display: none !important; +} + +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + 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-xs.visible-sm { + display: block !important; + } + tr.visible-xs.visible-sm { + display: table-row !important; + } + th.visible-xs.visible-sm, + td.visible-xs.visible-sm { + display: table-cell !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-xs.visible-md { + display: block !important; + } + tr.visible-xs.visible-md { + display: table-row !important; + } + th.visible-xs.visible-md, + td.visible-xs.visible-md { + display: table-cell !important; + } +} + +@media (min-width: 1200px) { + .visible-xs.visible-lg { + display: block !important; + } + tr.visible-xs.visible-lg { + display: table-row !important; + } + th.visible-xs.visible-lg, + td.visible-xs.visible-lg { + display: table-cell !important; + } +} + +.visible-sm, +tr.visible-sm, +th.visible-sm, +td.visible-sm { + display: none !important; +} + +@media (max-width: 767px) { + .visible-sm.visible-xs { + display: block !important; + } + tr.visible-sm.visible-xs { + display: table-row !important; + } + th.visible-sm.visible-xs, + td.visible-sm.visible-xs { + display: table-cell !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + 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-sm.visible-md { + display: block !important; + } + tr.visible-sm.visible-md { + display: table-row !important; + } + th.visible-sm.visible-md, + td.visible-sm.visible-md { + display: table-cell !important; + } +} + +@media (min-width: 1200px) { + .visible-sm.visible-lg { + display: block !important; + } + tr.visible-sm.visible-lg { + display: table-row !important; + } + th.visible-sm.visible-lg, + td.visible-sm.visible-lg { + display: table-cell !important; + } +} + +.visible-md, +tr.visible-md, +th.visible-md, +td.visible-md { + display: none !important; +} + +@media (max-width: 767px) { + .visible-md.visible-xs { + display: block !important; + } + tr.visible-md.visible-xs { + display: table-row !important; + } + th.visible-md.visible-xs, + td.visible-md.visible-xs { + display: table-cell !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .visible-md.visible-sm { + display: block !important; + } + tr.visible-md.visible-sm { + display: table-row !important; + } + th.visible-md.visible-sm, + td.visible-md.visible-sm { + display: table-cell !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} + +@media (min-width: 1200px) { + .visible-md.visible-lg { + display: block !important; + } + tr.visible-md.visible-lg { + display: table-row !important; + } + th.visible-md.visible-lg, + td.visible-md.visible-lg { + display: table-cell !important; + } +} + +.visible-lg, +tr.visible-lg, +th.visible-lg, +td.visible-lg { + display: none !important; +} + +@media (max-width: 767px) { + .visible-lg.visible-xs { + display: block !important; + } + tr.visible-lg.visible-xs { + display: table-row !important; + } + th.visible-lg.visible-xs, + td.visible-lg.visible-xs { + display: table-cell !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .visible-lg.visible-sm { + display: block !important; + } + tr.visible-lg.visible-sm { + display: table-row !important; + } + th.visible-lg.visible-sm, + td.visible-lg.visible-sm { + display: table-cell !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-lg.visible-md { + display: block !important; + } + tr.visible-lg.visible-md { + display: table-row !important; + } + th.visible-lg.visible-md, + td.visible-lg.visible-md { + display: table-cell !important; + } +} + +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} + +.hidden-xs { + display: block !important; +} + +tr.hidden-xs { + display: table-row !important; +} + +th.hidden-xs, +td.hidden-xs { + display: table-cell !important; +} + +@media (max-width: 767px) { + .hidden-xs, + tr.hidden-xs, + th.hidden-xs, + td.hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-xs.hidden-sm, + tr.hidden-xs.hidden-sm, + th.hidden-xs.hidden-sm, + td.hidden-xs.hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-xs.hidden-md, + tr.hidden-xs.hidden-md, + th.hidden-xs.hidden-md, + td.hidden-xs.hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-xs.hidden-lg, + tr.hidden-xs.hidden-lg, + th.hidden-xs.hidden-lg, + td.hidden-xs.hidden-lg { + display: none !important; + } +} + +.hidden-sm { + display: block !important; +} + +tr.hidden-sm { + display: table-row !important; +} + +th.hidden-sm, +td.hidden-sm { + display: table-cell !important; +} + +@media (max-width: 767px) { + .hidden-sm.hidden-xs, + tr.hidden-sm.hidden-xs, + th.hidden-sm.hidden-xs, + td.hidden-sm.hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm, + tr.hidden-sm, + th.hidden-sm, + td.hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-sm.hidden-md, + tr.hidden-sm.hidden-md, + th.hidden-sm.hidden-md, + td.hidden-sm.hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-sm.hidden-lg, + tr.hidden-sm.hidden-lg, + th.hidden-sm.hidden-lg, + td.hidden-sm.hidden-lg { + display: none !important; + } +} + +.hidden-md { + display: block !important; +} + +tr.hidden-md { + display: table-row !important; +} + +th.hidden-md, +td.hidden-md { + display: table-cell !important; +} + +@media (max-width: 767px) { + .hidden-md.hidden-xs, + tr.hidden-md.hidden-xs, + th.hidden-md.hidden-xs, + td.hidden-md.hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-md.hidden-sm, + tr.hidden-md.hidden-sm, + th.hidden-md.hidden-sm, + td.hidden-md.hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md, + tr.hidden-md, + th.hidden-md, + td.hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-md.hidden-lg, + tr.hidden-md.hidden-lg, + th.hidden-md.hidden-lg, + td.hidden-md.hidden-lg { + display: none !important; + } +} + +.hidden-lg { + display: block !important; +} + +tr.hidden-lg { + display: table-row !important; +} + +th.hidden-lg, +td.hidden-lg { + display: table-cell !important; +} + +@media (max-width: 767px) { + .hidden-lg.hidden-xs, + tr.hidden-lg.hidden-xs, + th.hidden-lg.hidden-xs, + td.hidden-lg.hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-lg.hidden-sm, + tr.hidden-lg.hidden-sm, + th.hidden-lg.hidden-sm, + td.hidden-lg.hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-lg.hidden-md, + tr.hidden-lg.hidden-md, + th.hidden-lg.hidden-md, + td.hidden-lg.hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-lg, + tr.hidden-lg, + th.hidden-lg, + td.hidden-lg { + display: none !important; + } +} + +.visible-print, +tr.visible-print, +th.visible-print, +td.visible-print { + display: none !important; +} + +@media print { + .visible-print { + display: block !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } + .hidden-print, + tr.hidden-print, + th.hidden-print, + td.hidden-print { + display: none !important; + } +} \ No newline at end of file diff --git a/assets/css/bootstrap.min.css b/assets/css/bootstrap.min.css new file mode 100644 index 0000000..c547283 --- /dev/null +++ b/assets/css/bootstrap.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.0.3 (http://getbootstrap.com) + * Copyright 2013 Twitter, Inc. + * Licensed under http://www.apache.org/licenses/LICENSE-2.0 + */ + +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{margin:.67em 0;font-size:2em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}mark{color:#000;background:#ff0}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid #c0c0c0}legend{padding:0;border:0}button,input,select,textarea{margin:0;font-family:inherit;font-size:100%}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{padding:0;box-sizing:border-box}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@media print{*{color:#000!important;text-shadow:none!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}@page{margin:2cm .5cm}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}}*,*: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.428571429;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}img{vertical-align:middle}.img-responsive{display:block;height:auto;max-width:100%}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.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;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;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,h2,h3{margin-top:20px;margin-bottom:10px}h1 small,h2 small,h3 small,h1 .small,h2 .small,h3 .small{font-size:65%}h4,h5,h6{margin-top:10px;margin-bottom:10px}h4 small,h5 small,h6 small,h4 .small,h5 .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-muted{color:#999}.text-primary{color:#428bca}.text-primary:hover{color:#3071a9}.text-warning{color:#8a6d3b}.text-warning:hover{color:#66512c}.text-danger{color:#a94442}.text-danger:hover{color:#843534}.text-success{color:#3c763d}.text-success:hover{color:#2b542c}.text-info{color:#31708f}.text-info:hover{color:#245269}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.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}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}.list-inline>li:first-child{padding-left:0}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.428571429}dt{font-weight:bold}dd{margin-left:0}@media(min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}}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;border-left:5px solid #eee}blockquote p{font-size:17.5px;font-weight:300;line-height:1.25}blockquote p:last-child{margin-bottom:0}blockquote small,blockquote .small{display:block;line-height:1.428571429;color:#999}blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small,blockquote.pull-right .small{text-align:right}blockquote.pull-right small:before,blockquote.pull-right .small:before{content:''}blockquote.pull-right 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.428571429}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:4px}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;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{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}@media(min-width:768px){.container{width:750px}}@media(min-width:992px){.container{width:970px}}@media(min-width:1200px){.container{width:1170px}}.row{margin-right:-15px;margin-left:-15px}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.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-right:15px;padding-left:15px}.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.66666666666666%}.col-xs-10{width:83.33333333333334%}.col-xs-9{width:75%}.col-xs-8{width:66.66666666666666%}.col-xs-7{width:58.333333333333336%}.col-xs-6{width:50%}.col-xs-5{width:41.66666666666667%}.col-xs-4{width:33.33333333333333%}.col-xs-3{width:25%}.col-xs-2{width:16.666666666666664%}.col-xs-1{width:8.333333333333332%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666666666666%}.col-xs-pull-10{right:83.33333333333334%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666666666666%}.col-xs-pull-7{right:58.333333333333336%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666666666667%}.col-xs-pull-4{right:33.33333333333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.666666666666664%}.col-xs-pull-1{right:8.333333333333332%}.col-xs-pull-0{right:0}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666666666666%}.col-xs-push-10{left:83.33333333333334%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666666666666%}.col-xs-push-7{left:58.333333333333336%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666666666667%}.col-xs-push-4{left:33.33333333333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.666666666666664%}.col-xs-push-1{left:8.333333333333332%}.col-xs-push-0{left:0}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666666666666%}.col-xs-offset-10{margin-left:83.33333333333334%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666666666666%}.col-xs-offset-7{margin-left:58.333333333333336%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666666666667%}.col-xs-offset-4{margin-left:33.33333333333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.666666666666664%}.col-xs-offset-1{margin-left:8.333333333333332%}.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.66666666666666%}.col-sm-10{width:83.33333333333334%}.col-sm-9{width:75%}.col-sm-8{width:66.66666666666666%}.col-sm-7{width:58.333333333333336%}.col-sm-6{width:50%}.col-sm-5{width:41.66666666666667%}.col-sm-4{width:33.33333333333333%}.col-sm-3{width:25%}.col-sm-2{width:16.666666666666664%}.col-sm-1{width:8.333333333333332%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666666666666%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666666666666%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-1{margin-left:8.333333333333332%}.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.66666666666666%}.col-md-10{width:83.33333333333334%}.col-md-9{width:75%}.col-md-8{width:66.66666666666666%}.col-md-7{width:58.333333333333336%}.col-md-6{width:50%}.col-md-5{width:41.66666666666667%}.col-md-4{width:33.33333333333333%}.col-md-3{width:25%}.col-md-2{width:16.666666666666664%}.col-md-1{width:8.333333333333332%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666666666666%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666666666666%}.col-md-push-10{left:83.33333333333334%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666666666666%}.col-md-push-7{left:58.333333333333336%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666666666667%}.col-md-push-4{left:33.33333333333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.666666666666664%}.col-md-push-1{left:8.333333333333332%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666666666666%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-1{margin-left:8.333333333333332%}.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.66666666666666%}.col-lg-10{width:83.33333333333334%}.col-lg-9{width:75%}.col-lg-8{width:66.66666666666666%}.col-lg-7{width:58.333333333333336%}.col-lg-6{width:50%}.col-lg-5{width:41.66666666666667%}.col-lg-4{width:33.33333333333333%}.col-lg-3{width:25%}.col-lg-2{width:16.666666666666664%}.col-lg-1{width:8.333333333333332%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666666666666%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666666666666%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-1{margin-left:8.333333333333332%}.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.428571429;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;display:table-column;float:none}table td[class*="col-"],table th[class*="col-"]{display:table-cell;float:none}.table>thead>tr>.active,.table>tbody>tr>.active,.table>tfoot>tr>.active,.table>thead>.active>td,.table>tbody>.active>td,.table>tfoot>.active>td,.table>thead>.active>th,.table>tbody>.active>th,.table>tfoot>.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>.active:hover,.table-hover>tbody>.active:hover>td,.table-hover>tbody>.active:hover>th{background-color:#e8e8e8}.table>thead>tr>.success,.table>tbody>tr>.success,.table>tfoot>tr>.success,.table>thead>.success>td,.table>tbody>.success>td,.table>tfoot>.success>td,.table>thead>.success>th,.table>tbody>.success>th,.table>tfoot>.success>th{background-color:#dff0d8}.table-hover>tbody>tr>.success:hover,.table-hover>tbody>.success:hover>td,.table-hover>tbody>.success:hover>th{background-color:#d0e9c6}.table>thead>tr>.danger,.table>tbody>tr>.danger,.table>tfoot>tr>.danger,.table>thead>.danger>td,.table>tbody>.danger>td,.table>tfoot>.danger>td,.table>thead>.danger>th,.table>tbody>.danger>th,.table>tfoot>.danger>th{background-color:#f2dede}.table-hover>tbody>tr>.danger:hover,.table-hover>tbody>.danger:hover>td,.table-hover>tbody>.danger:hover>th{background-color:#ebcccc}.table>thead>tr>.warning,.table>tbody>tr>.warning,.table>tfoot>tr>.warning,.table>thead>.warning>td,.table>tbody>.warning>td,.table>tfoot>.warning>td,.table>thead>.warning>th,.table>tbody>.warning>th,.table>tfoot>.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>.warning:hover,.table-hover>tbody>.warning:hover>td,.table-hover>tbody>.warning:hover>th{background-color:#faf2cc}@media(max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd;-ms-overflow-style:-ms-autohiding-scrollbar;-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}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}select[multiple],select[size]{height:auto}select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}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}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{height:auto}output{display:block;padding-top:7px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle;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,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control:-moz-placeholder{color:#999}.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}textarea.form-control{height:auto}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.radio label,.checkbox label{display:inline;margin-bottom:0;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;font-weight:normal;vertical-align:middle;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{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{height:auto}.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;background-color:#fcf8e3;border-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;background-color:#f2dede;border-color:#a94442}.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;background-color:#dff0d8;border-color:#3c763d}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media(min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline select.form-control{width:auto}.form-inline .radio,.form-inline .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-control-static{padding-top:7px}@media(min-width:768px){.form-horizontal .control-label{text-align:right}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:normal;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.btn: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{background-image:none;outline:0;-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{pointer-events:none;cursor:not-allowed;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:#fff}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.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:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.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:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.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:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.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:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.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:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-link{font-weight:normal;color:#428bca;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:#2a6496;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{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left: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';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:normal;line-height:1;-moz-osx-font-smoothing:grayscale}.glyphicon:empty{width:1em}.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;font-size:14px;list-style:none;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.428571429;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.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;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left: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{right:0;left: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:0}.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:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar .btn-group{float:left}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group,.btn-toolbar>.btn-group+.btn-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-top-right-radius:0;border-bottom-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-top-right-radius:0;border-bottom-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-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left: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:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.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-top-right-radius:0;border-bottom-left-radius:4px;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>.btn:last-child,.btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;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-right:0;padding-left:0}.input-group .form-control{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{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{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>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-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>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;white-space:nowrap}.input-group-btn:first-child>.btn{margin-right:-1px}.input-group-btn:last-child>.btn{margin-left:-1px}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-4px}.input-group-btn>.btn:hover,.input-group-btn>.btn:active{z-index:2}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.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;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.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.428571429;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;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.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:#428bca}.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{margin-bottom:5px;text-align:center}.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}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}@media(min-width:768px){.navbar{border-radius:4px}}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}@media(min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.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-right:0;padding-left:0}}.container>.navbar-header,.container>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media(min-width:768px){.container>.navbar-header,.container>.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 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media(min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.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 -15px}.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:-15px}}@media(min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;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)}@media(min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form select.form-control{width:auto}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{float:none;margin-left:0}}@media(max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media(min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.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-nav.pull-right>li>.dropdown-menu,.navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.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-right:15px;margin-left:15px}.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:#ccc}.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{color:#555;background-color:#e7e7e7}@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{color:#fff;background-color:#080808}@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{padding:0 5px;color:#ccc;content:"/\00a0"}.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;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:#fff;border:1px solid #ddd}.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-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{background-color:#eee}.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;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;cursor:not-allowed;background-color:#fff;border-color:#ddd}.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-top-right-radius:6px;border-bottom-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-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.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;cursor:not-allowed;background-color:#fff}.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:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#999;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}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:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;font-size:21px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{line-height:1;color:inherit}.jumbotron p{line-height:1.4}.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-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.428571429;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{display:block;height:auto;max-width:100%;margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.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{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.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{height:20px;margin-bottom:20px;overflow:hidden;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:#428bca;-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:#5cb85c}.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:#5bc0de}.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:#f0ad4e}.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:#d9534f}.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{padding-left:0;margin-bottom:20px}.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:#428bca;border-color:#428bca}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:#e1edf7}.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-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0}.panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel>.list-group .list-group-item:last-child{border-bottom:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child th,.panel>.table>tbody: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:last-child>th,.panel>.table-responsive>.table-bordered>thead>tr:last-child>th,.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,.panel>.table-bordered>thead>tr:last-child>td,.panel>.table-responsive>.table-bordered>thead>tr:last-child>td,.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{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.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-group .panel{margin-bottom:0;overflow:hidden;border-radius:4px}.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:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.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-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}.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}.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{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:auto;overflow-y:scroll}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .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;z-index:1050;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;outline:0;-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}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.428571429}.modal-body{position:relative;padding:20px}.modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media screen and (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)}}.tooltip{position:absolute;z-index:1030;display:block;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.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-top-color:#000;border-width:5px 5px 0}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#000;border-width:0 5px 5px}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;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);background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;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{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0;content:" "}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0;content:" "}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0;content:" "}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0;content:" "}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;height:auto;max-width:100%;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;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);opacity:.5;filter:alpha(opacity=50)}.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{right:0;left:auto;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{color:#fff;text-decoration:none;outline:0;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%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;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 .glyphicons-chevron-left,.carousel-control .glyphicons-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{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.center-block{display:block;margin-right:auto;margin-left: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,tr.visible-xs,th.visible-xs,td.visible-xs{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-xs.visible-sm{display:block!important}table.visible-xs.visible-sm{display:table}tr.visible-xs.visible-sm{display:table-row!important}th.visible-xs.visible-sm,td.visible-xs.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block!important}table.visible-xs.visible-md{display:table}tr.visible-xs.visible-md{display:table-row!important}th.visible-xs.visible-md,td.visible-xs.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-xs.visible-lg{display:block!important}table.visible-xs.visible-lg{display:table}tr.visible-xs.visible-lg{display:table-row!important}th.visible-xs.visible-lg,td.visible-xs.visible-lg{display:table-cell!important}}.visible-sm,tr.visible-sm,th.visible-sm,td.visible-sm{display:none!important}@media(max-width:767px){.visible-sm.visible-xs{display:block!important}table.visible-sm.visible-xs{display:table}tr.visible-sm.visible-xs{display:table-row!important}th.visible-sm.visible-xs,td.visible-sm.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-sm.visible-md{display:block!important}table.visible-sm.visible-md{display:table}tr.visible-sm.visible-md{display:table-row!important}th.visible-sm.visible-md,td.visible-sm.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-sm.visible-lg{display:block!important}table.visible-sm.visible-lg{display:table}tr.visible-sm.visible-lg{display:table-row!important}th.visible-sm.visible-lg,td.visible-sm.visible-lg{display:table-cell!important}}.visible-md,tr.visible-md,th.visible-md,td.visible-md{display:none!important}@media(max-width:767px){.visible-md.visible-xs{display:block!important}table.visible-md.visible-xs{display:table}tr.visible-md.visible-xs{display:table-row!important}th.visible-md.visible-xs,td.visible-md.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block!important}table.visible-md.visible-sm{display:table}tr.visible-md.visible-sm{display:table-row!important}th.visible-md.visible-sm,td.visible-md.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-md.visible-lg{display:block!important}table.visible-md.visible-lg{display:table}tr.visible-md.visible-lg{display:table-row!important}th.visible-md.visible-lg,td.visible-md.visible-lg{display:table-cell!important}}.visible-lg,tr.visible-lg,th.visible-lg,td.visible-lg{display:none!important}@media(max-width:767px){.visible-lg.visible-xs{display:block!important}table.visible-lg.visible-xs{display:table}tr.visible-lg.visible-xs{display:table-row!important}th.visible-lg.visible-xs,td.visible-lg.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block!important}table.visible-lg.visible-sm{display:table}tr.visible-lg.visible-sm{display:table-row!important}th.visible-lg.visible-sm,td.visible-lg.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block!important}table.visible-lg.visible-md{display:table}tr.visible-lg.visible-md{display:table-row!important}th.visible-lg.visible-md,td.visible-lg.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}}.hidden-xs{display:block!important}table.hidden-xs{display:table}tr.hidden-xs{display:table-row!important}th.hidden-xs,td.hidden-xs{display:table-cell!important}@media(max-width:767px){.hidden-xs,tr.hidden-xs,th.hidden-xs,td.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm,tr.hidden-xs.hidden-sm,th.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md,tr.hidden-xs.hidden-md,th.hidden-xs.hidden-md,td.hidden-xs.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-xs.hidden-lg,tr.hidden-xs.hidden-lg,th.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg{display:none!important}}.hidden-sm{display:block!important}table.hidden-sm{display:table}tr.hidden-sm{display:table-row!important}th.hidden-sm,td.hidden-sm{display:table-cell!important}@media(max-width:767px){.hidden-sm.hidden-xs,tr.hidden-sm.hidden-xs,th.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-sm,tr.hidden-sm,th.hidden-sm,td.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md,tr.hidden-sm.hidden-md,th.hidden-sm.hidden-md,td.hidden-sm.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-sm.hidden-lg,tr.hidden-sm.hidden-lg,th.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg{display:none!important}}.hidden-md{display:block!important}table.hidden-md{display:table}tr.hidden-md{display:table-row!important}th.hidden-md,td.hidden-md{display:table-cell!important}@media(max-width:767px){.hidden-md.hidden-xs,tr.hidden-md.hidden-xs,th.hidden-md.hidden-xs,td.hidden-md.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-md.hidden-sm,tr.hidden-md.hidden-sm,th.hidden-md.hidden-sm,td.hidden-md.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-md,tr.hidden-md,th.hidden-md,td.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-md.hidden-lg,tr.hidden-md.hidden-lg,th.hidden-md.hidden-lg,td.hidden-md.hidden-lg{display:none!important}}.hidden-lg{display:block!important}table.hidden-lg{display:table}tr.hidden-lg{display:table-row!important}th.hidden-lg,td.hidden-lg{display:table-cell!important}@media(max-width:767px){.hidden-lg.hidden-xs,tr.hidden-lg.hidden-xs,th.hidden-lg.hidden-xs,td.hidden-lg.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-lg.hidden-sm,tr.hidden-lg.hidden-sm,th.hidden-lg.hidden-sm,td.hidden-lg.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-lg.hidden-md,tr.hidden-lg.hidden-md,th.hidden-lg.hidden-md,td.hidden-lg.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-lg,tr.hidden-lg,th.hidden-lg,td.hidden-lg{display:none!important}}.visible-print,tr.visible-print,th.visible-print,td.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}.hidden-print,tr.hidden-print,th.hidden-print,td.hidden-print{display:none!important}} \ No newline at end of file diff --git a/assets/css/prettify.css b/assets/css/prettify.css new file mode 100644 index 0000000..1eaf049 --- /dev/null +++ b/assets/css/prettify.css @@ -0,0 +1,55 @@ +.com { + color: #93a1a1; +} + +.lit { + color: #195f91; +} + +.pun, .opn, .clo { + color: #93a1a1; +} + +.fun { + color: #dc322f; +} + +.str, .atv { + color: #D14; +} + +.kwd, .linenums .tag { + color: #1e347b; +} + +.typ, .atn, .dec, .var { + color: teal; +} + +.pln { + color: #48484c; +} + +.prettyprint { + padding: 8px; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} + +.prettyprint.linenums { + -webkit-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; + -moz-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; + box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; +} + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin: 0 0 0 33px; /* IE indents via margin-left */ +} + +ol.linenums li { + padding-left: 12px; + color: #bebec5; + line-height: 18px; + text-shadow: 0 1px 0 #fff; +} \ No newline at end of file diff --git a/assets/css/style.css b/assets/css/style.css new file mode 100644 index 0000000..07e6bae --- /dev/null +++ b/assets/css/style.css @@ -0,0 +1,129 @@ +/* =Global rules +-----------------------------------------------------------------------------*/ +[ng-app].ng-cloak, +[ng-app][ng-cloak] { + display: block !important; + opacity: 0; +} + +[ng-app] { + opacity: 1; + -webkit-transition: opacity 1s ease-out; + -moz-transition: opacity 1s ease-out; + transition: opacity 1s ease-out; +} + +body{ + padding-top: 50px; + min-width: 768px; +} + +/* =TWBS Header +-----------------------------------------------------------------------------*/ + +/* Page headers */ +.bs-header { + padding: 30px 15px 40px; /* side padding builds on .container 15px, so 30px */ + font-size: 16px; + text-align: center; + text-shadow: 0 1px 0 rgba(0,0,0,.15); + color: #cdbfe3; + background-color: #563d7c; + background-image: url('../img/header.png'); +} +.bs-header a { + color: #fff; + font-weight: normal; +} +.bs-header h1 { + color: #fff; +} +.bs-header p { + font-weight: 200; + line-height: 1.4; +} +.bs-header .container { + position: relative; +} + + +@media (min-width: 768px) { + .bs-header { + font-size: 21px; + text-align: left; + } + .bs-header h1 { + font-size: 60px; + line-height: 1; + } +} + +@media (min-width: 992px) { + .bs-header h1, + .bs-header p { + margin-right: 380px; + } +} + +.bs-social { + margin-top: 20px; + margin-bottom: 20px; + text-align: center; +} + +@media (min-width: 768px) { + + .bs-social { + text-align: left; + } + +} + + +/* + * Button Inverse + * + * Buttons in the masthead. + */ + + .btn-outline-inverse { + color: #fff; + background-color: transparent; + border-color: #cdbfe3; + margin: 10px; +} + +@media (min-width: 768px) { + + .btn-outline-inverse { + width: auto; + margin: 20px 5px 20px 0; + padding: 18px 24px; + font-size: 21px; + } + +} + +.btn-outline-inverse:hover, .btn-outline-inverse:focus, .btn-outline-inverse:active { + color: #563d7c; + text-shadow: none; + background-color: #fff; + border-color: #fff; +} + +/* =PRETTYPRINT TABS +-----------------------------------------------------------------------------*/ +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + background-color: #f8f8f8; +} + +.prettyprint { + border-top: none; +} \ No newline at end of file diff --git a/assets/fonts/glyphicons-halflings-regular.eot b/assets/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000..423bd5d Binary files /dev/null and b/assets/fonts/glyphicons-halflings-regular.eot differ diff --git a/assets/fonts/glyphicons-halflings-regular.svg b/assets/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 0000000..4469488 --- /dev/null +++ b/assets/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/fonts/glyphicons-halflings-regular.ttf b/assets/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000..a498ef4 Binary files /dev/null and b/assets/fonts/glyphicons-halflings-regular.ttf differ diff --git a/assets/fonts/glyphicons-halflings-regular.woff b/assets/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 0000000..d83c539 Binary files /dev/null and b/assets/fonts/glyphicons-halflings-regular.woff differ diff --git a/assets/img/header.png b/assets/img/header.png new file mode 100644 index 0000000..785dd10 Binary files /dev/null and b/assets/img/header.png differ diff --git a/assets/vendor/angular.min.js b/assets/vendor/angular.min.js new file mode 100644 index 0000000..06d5d76 --- /dev/null +++ b/assets/vendor/angular.min.js @@ -0,0 +1,250 @@ +/* + AngularJS v1.3.8 + (c) 2010-2014 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(M,Y,t){'use strict';function T(b){return function(){var a=arguments[0],c;c="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.3.8/"+(b?b+"/":"")+a;for(a=1;a").append(b).html();try{return b[0].nodeType===pb?Q(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+Q(b)})}catch(d){return Q(c)}}function pc(b){try{return decodeURIComponent(b)}catch(a){}}function qc(b){var a={},c,d;s((b||"").split("&"),function(b){b&& +(c=b.replace(/\+/g,"%20").split("="),d=pc(c[0]),y(d)&&(b=y(c[1])?pc(c[1]):!0,rc.call(a,d)?x(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Nb(b){var a=[];s(b,function(b,d){x(b)?s(b,function(b){a.push(Fa(d,!0)+(!0===b?"":"="+Fa(b,!0)))}):a.push(Fa(d,!0)+(!0===b?"":"="+Fa(b,!0)))});return a.length?a.join("&"):""}function qb(b){return Fa(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Fa(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi, +":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%20/g,a?"%20":"+")}function Id(b,a){var c,d,e=rb.length;b=B(b);for(d=0;d/,">"));}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);c.debugInfoEnabled&&a.push(["$compileProvider",function(a){a.debugInfoEnabled(!0)}]);a.unshift("ng");d=Ob(a,c.strictDi);d.invoke(["$rootScope","$rootElement","$compile","$injector",function(a,b,c,d){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return d}, +e=/^NG_ENABLE_DEBUG_INFO!/,f=/^NG_DEFER_BOOTSTRAP!/;M&&e.test(M.name)&&(c.debugInfoEnabled=!0,M.name=M.name.replace(e,""));if(M&&!f.test(M.name))return d();M.name=M.name.replace(f,"");ga.resumeBootstrap=function(b){s(b,function(b){a.push(b)});d()}}function Kd(){M.name="NG_ENABLE_DEBUG_INFO!"+M.name;M.location.reload()}function Ld(b){b=ga.element(b).injector();if(!b)throw Ka("test");return b.get("$$testability")}function tc(b,a){a=a||"_";return b.replace(Md,function(b,d){return(d?a:"")+b.toLowerCase()})} +function Nd(){var b;uc||((ra=M.jQuery)&&ra.fn.on?(B=ra,z(ra.fn,{scope:La.scope,isolateScope:La.isolateScope,controller:La.controller,injector:La.injector,inheritedData:La.inheritedData}),b=ra.cleanData,ra.cleanData=function(a){var c;if(Pb)Pb=!1;else for(var d=0,e;null!=(e=a[d]);d++)(c=ra._data(e,"events"))&&c.$destroy&&ra(e).triggerHandler("$destroy");b(a)}):B=R,ga.element=B,uc=!0)}function Qb(b,a,c){if(!b)throw Ka("areq",a||"?",c||"required");return b}function sb(b,a,c){c&&x(b)&&(b=b[b.length-1]); +Qb(G(b),a,"not a function, got "+(b&&"object"===typeof b?b.constructor.name||"Object":typeof b));return b}function Ma(b,a){if("hasOwnProperty"===b)throw Ka("badname",a);}function vc(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,f=a.length,g=0;g")+d[2];for(d=d[0];d--;)c=c.lastChild;f=Ya(f,c.childNodes);c=e.firstChild;c.textContent=""}else f.push(a.createTextNode(b));e.textContent="";e.innerHTML="";s(f,function(a){e.appendChild(a)});return e}function R(b){if(b instanceof +R)return b;var a;F(b)&&(b=U(b),a=!0);if(!(this instanceof R)){if(a&&"<"!=b.charAt(0))throw Sb("nosel");return new R(b)}if(a){a=Y;var c;b=(c=gf.exec(b))?[a.createElement(c[1])]:(c=Fc(b,a))?c.childNodes:[]}Gc(this,b)}function Tb(b){return b.cloneNode(!0)}function wb(b,a){a||xb(b);if(b.querySelectorAll)for(var c=b.querySelectorAll("*"),d=0,e=c.length;d 4096 bytes)!"));else{if(p.cookie!==y)for(y=p.cookie,d=y.split("; "),ea={},f=0;fk&&this.remove(q.key), +b},get:function(a){if(k").parent()[0])});var f=S(a,b,a,c,d,e);E.$$addScopeClass(a);var g=null;return function(b,c,d){Qb(b,"scope");d=d||{};var e=d.parentBoundTranscludeFn,h=d.transcludeControllers;d=d.futureParentElement;e&&e.$$boundTransclude&&(e=e.$$boundTransclude);g||(g=(d=d&&d[0])?"foreignobject"!==ua(d)&&d.toString().match(/SVG/)?"svg":"html":"html");d="html"!==g?B(Wb(g,B("
").append(a).html())): +c?La.clone.call(a):a;if(h)for(var l in h)d.data("$"+l+"Controller",h[l].instance);E.$$addScopeInfo(d,b);c&&c(d,b);f&&f(b,d,d,e);return d}}function S(a,b,c,d,e,f){function g(a,c,d,e){var f,l,k,q,p,n,w;if(r)for(w=Array(c.length),q=0;qK.priority)break;if(N=K.scope)K.templateUrl||(H(N)?(Oa("new/isolated scope",S||P,K,aa),S=K):Oa("new/isolated scope",S,K,aa)),P=P||K;z=K.name;!K.templateUrl&&K.controller&&(N=K.controller,J=J||{},Oa("'"+z+"' controller",J[z], +K,aa),J[z]=K);if(N=K.transclude)ca=!0,K.$$tlb||(Oa("transclusion",ea,K,aa),ea=K),"element"==N?(C=!0,A=K.priority,N=aa,aa=e.$$element=B(Y.createComment(" "+z+": "+e[z]+" ")),d=aa[0],V(g,Za.call(N,0),d),Aa=E(N,f,A,l&&l.name,{nonTlbTranscludeDirective:ea})):(N=B(Tb(d)).contents(),aa.empty(),Aa=E(N,f));if(K.template)if(D=!0,Oa("template",ka,K,aa),ka=K,N=G(K.template)?K.template(aa,e):K.template,N=Sc(N),K.replace){l=K;N=Rb.test(N)?Tc(Wb(K.templateNamespace,U(N))):[];d=N[0];if(1!=N.length||d.nodeType!== +na)throw ja("tplrt",z,"");V(g,aa,d);R={$attr:{}};N=W(d,[],R);var ba=a.splice(M+1,a.length-(M+1));S&&y(N);a=a.concat(N).concat(ba);Qc(e,R);R=a.length}else aa.html(N);if(K.templateUrl)D=!0,Oa("template",ka,K,aa),ka=K,K.replace&&(l=K),v=T(a.splice(M,a.length-M),aa,e,g,ca&&Aa,k,p,{controllerDirectives:J,newIsolateScopeDirective:S,templateDirective:ka,nonTlbTranscludeDirective:ea}),R=a.length;else if(K.compile)try{Q=K.compile(aa,e,Aa),G(Q)?w(null,Q,Pa,fb):Q&&w(Q.pre,Q.post,Pa,fb)}catch(qf){c(qf,va(aa))}K.terminal&& +(v.terminal=!0,A=Math.max(A,K.priority))}v.scope=P&&!0===P.scope;v.transcludeOnThisElement=ca;v.elementTranscludeOnThisElement=C;v.templateOnThisElement=D;v.transclude=Aa;r.hasElementTranscludeDirective=C;return v}function y(a){for(var b=0,c=a.length;bq.priority)&&-1!= +q.restrict.indexOf(f)){if(l){var w={$$start:l,$$end:k};q=z(Object.create(q),w)}b.push(q);h=q}}catch(O){c(O)}}return h}function D(b){if(d.hasOwnProperty(b))for(var c=a.get(b+"Directive"),e=0,f=c.length;e"+b+"";return c.childNodes[0].childNodes;default:return b}}function R(a,b){if("srcdoc"==b)return L.HTML;var c=ua(a);if("xlinkHref"==b||"form"==c&&"action"==b||"img"!=c&&("src"==b||"ngSrc"==b))return L.RESOURCE_URL}function Pa(a,c,d,e,f){var h=R(a,e);f=g[e]||f;var k=b(d,!0,h,f);if(k){if("multiple"===e&&"select"===ua(a))throw ja("selmulti", +va(a));c.push({priority:100,compile:function(){return{pre:function(a,c,g){c=g.$$observers||(g.$$observers={});if(l.test(e))throw ja("nodomevents");var p=g[e];p!==d&&(k=p&&b(p,!0,h,f),d=p);k&&(g[e]=k(a),(c[e]||(c[e]=[])).$$inter=!0,(g.$$observers&&g.$$observers[e].$$scope||a).$watch(k,function(a,b){"class"===e&&a!=b?g.$updateClass(a,b):g.$set(e,a)}))}}}})}}function V(a,b,c){var d=b[0],e=b.length,f=d.parentNode,g,h;if(a)for(g=0,h=a.length;g=a)return b;for(;a--;)8===b[a].nodeType&&rf.call(b,a,1);return b}function Fe(){var b={},a=!1,c=/^(\S+)(\s+as\s+(\w+))?$/;this.register=function(a,c){Ma(a,"controller");H(a)?z(b,a):b[a]=c};this.allowGlobals=function(){a=!0};this.$get=["$injector","$window",function(d,e){function f(a,b,c,d){if(!a||!H(a.$scope))throw T("$controller")("noscp",d,b);a.$scope[b]=c}return function(g,h,l,k){var m,p,q;l=!0===l;k&&F(k)&&(q=k);F(g)&& +(k=g.match(c),p=k[1],q=q||k[3],g=b.hasOwnProperty(p)?b[p]:vc(h.$scope,p,!0)||(a?vc(e,p,!0):t),sb(g,p,!0));if(l)return l=(x(g)?g[g.length-1]:g).prototype,m=Object.create(l),q&&f(h,q,m,p||g.name),z(function(){d.invoke(g,m,h,p);return m},{instance:m,identifier:q});m=d.instantiate(g,h,p);q&&f(h,q,m,p||g.name);return m}}]}function Ge(){this.$get=["$window",function(b){return B(b.document)}]}function He(){this.$get=["$log",function(b){return function(a,c){b.error.apply(b,arguments)}}]}function Yb(b,a){if(F(b)){var c= +b.replace(sf,"").trim();if(c){var d=a("Content-Type");(d=d&&0===d.indexOf(Vc))||(d=(d=c.match(tf))&&uf[d[0]].test(c));d&&(b=oc(c))}}return b}function Wc(b){var a=ha(),c,d,e;if(!b)return a;s(b.split("\n"),function(b){e=b.indexOf(":");c=Q(U(b.substr(0,e)));d=U(b.substr(e+1));c&&(a[c]=a[c]?a[c]+", "+d:d)});return a}function Xc(b){var a=H(b)?b:t;return function(c){a||(a=Wc(b));return c?(c=a[Q(c)],void 0===c&&(c=null),c):a}}function Yc(b,a,c,d){if(G(d))return d(b,a,c);s(d,function(d){b=d(b,a,c)});return b} +function Ke(){var b=this.defaults={transformResponse:[Yb],transformRequest:[function(a){return H(a)&&"[object File]"!==Da.call(a)&&"[object Blob]"!==Da.call(a)&&"[object FormData]"!==Da.call(a)?$a(a):a}],headers:{common:{Accept:"application/json, text/plain, */*"},post:qa(Zb),put:qa(Zb),patch:qa(Zb)},xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN"},a=!1;this.useApplyAsync=function(b){return y(b)?(a=!!b,this):a};var c=this.interceptors=[];this.$get=["$httpBackend","$browser","$cacheFactory", +"$rootScope","$q","$injector",function(d,e,f,g,h,l){function k(a){function c(a){var b=z({},a);b.data=a.data?Yc(a.data,a.headers,a.status,e.transformResponse):a.data;a=a.status;return 200<=a&&300>a?b:h.reject(b)}function d(a){var b,c={};s(a,function(a,d){G(a)?(b=a(),null!=b&&(c[d]=b)):c[d]=a});return c}if(!ga.isObject(a))throw T("$http")("badreq",a);var e=z({method:"get",transformRequest:b.transformRequest,transformResponse:b.transformResponse},a);e.headers=function(a){var c=b.headers,e=z({},a.headers), +f,g,c=z({},c.common,c[Q(a.method)]);a:for(f in c){a=Q(f);for(g in e)if(Q(g)===a)continue a;e[f]=c[f]}return d(e)}(a);e.method=ub(e.method);var f=[function(a){var d=a.headers,e=Yc(a.data,Xc(d),t,a.transformRequest);D(e)&&s(d,function(a,b){"content-type"===Q(b)&&delete d[b]});D(a.withCredentials)&&!D(b.withCredentials)&&(a.withCredentials=b.withCredentials);return m(a,e).then(c,c)},t],g=h.when(e);for(s(u,function(a){(a.request||a.requestError)&&f.unshift(a.request,a.requestError);(a.response||a.responseError)&& +f.push(a.response,a.responseError)});f.length;){a=f.shift();var l=f.shift(),g=g.then(a,l)}g.success=function(a){g.then(function(b){a(b.data,b.status,b.headers,e)});return g};g.error=function(a){g.then(null,function(b){a(b.data,b.status,b.headers,e)});return g};return g}function m(c,f){function l(b,c,d,e){function f(){m(c,b,d,e)}P&&(200<=b&&300>b?P.put(X,[b,c,Wc(d),e]):P.remove(X));a?g.$applyAsync(f):(f(),g.$$phase||g.$apply())}function m(a,b,d,e){b=Math.max(b,0);(200<=b&&300>b?J.resolve:J.reject)({data:a, +status:b,headers:Xc(d),config:c,statusText:e})}function w(a){m(a.data,a.status,qa(a.headers()),a.statusText)}function u(){var a=k.pendingRequests.indexOf(c);-1!==a&&k.pendingRequests.splice(a,1)}var J=h.defer(),A=J.promise,P,E,s=c.headers,X=p(c.url,c.params);k.pendingRequests.push(c);A.then(u,u);!c.cache&&!b.cache||!1===c.cache||"GET"!==c.method&&"JSONP"!==c.method||(P=H(c.cache)?c.cache:H(b.cache)?b.cache:q);P&&(E=P.get(X),y(E)?E&&G(E.then)?E.then(w,w):x(E)?m(E[1],E[0],qa(E[2]),E[3]):m(E,200,{}, +"OK"):P.put(X,A));D(E)&&((E=Zc(c.url)?e.cookies()[c.xsrfCookieName||b.xsrfCookieName]:t)&&(s[c.xsrfHeaderName||b.xsrfHeaderName]=E),d(c.method,X,f,l,s,c.timeout,c.withCredentials,c.responseType));return A}function p(a,b){if(!b)return a;var c=[];Ed(b,function(a,b){null===a||D(a)||(x(a)||(a=[a]),s(a,function(a){H(a)&&(a=pa(a)?a.toISOString():$a(a));c.push(Fa(b)+"="+Fa(a))}))});0=l&&(r.resolve(q),p(O.$$intervalId),delete f[O.$$intervalId]);u||b.$apply()},h);f[O.$$intervalId]=r;return O}var f={};e.cancel=function(b){return b&&b.$$intervalId in f?(f[b.$$intervalId].reject("canceled"),a.clearInterval(b.$$intervalId),delete f[b.$$intervalId],!0):!1};return e}]}function Rd(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2, +maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "),SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y", +longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function ac(b){b=b.split("/");for(var a=b.length;a--;)b[a]=qb(b[a]);return b.join("/")}function $c(b,a){var c=Ba(b);a.$$protocol=c.protocol;a.$$host=c.hostname;a.$$port=ba(c.port)||xf[c.protocol]||null}function ad(b,a){var c="/"!==b.charAt(0);c&&(b="/"+b);var d=Ba(b);a.$$path=decodeURIComponent(c&&"/"===d.pathname.charAt(0)?d.pathname.substring(1): +d.pathname);a.$$search=qc(d.search);a.$$hash=decodeURIComponent(d.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function za(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function Ha(b){var a=b.indexOf("#");return-1==a?b:b.substr(0,a)}function bd(b){return b.replace(/(#.+)|#$/,"$1")}function bc(b){return b.substr(0,Ha(b).lastIndexOf("/")+1)}function cc(b,a){this.$$html5=!0;a=a||"";var c=bc(b);$c(b,this);this.$$parse=function(a){var b=za(c,a);if(!F(b))throw Fb("ipthprfx",a,c); +ad(b,this);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Nb(this.$$search),b=this.$$hash?"#"+qb(this.$$hash):"";this.$$url=ac(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$parseLinkUrl=function(d,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;(f=za(b,d))!==t?(g=f,g=(f=za(a,f))!==t?c+(za("/",f)||f):b+g):(f=za(c,d))!==t?g=c+f:c==d+"/"&&(g=c);g&&this.$$parse(g);return!!g}}function dc(b,a){var c=bc(b);$c(b,this);this.$$parse=function(d){d= +za(b,d)||za(c,d);var e;"#"===d.charAt(0)?(e=za(a,d),D(e)&&(e=d)):e=this.$$html5?d:"";ad(e,this);d=this.$$path;var f=/^\/[A-Z]:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));f.exec(e)||(d=(e=f.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Nb(this.$$search),e=this.$$hash?"#"+qb(this.$$hash):"";this.$$url=ac(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+(this.$$url?a+this.$$url:"")};this.$$parseLinkUrl=function(a,c){return Ha(b)==Ha(a)?(this.$$parse(a),!0):!1}}function cd(b, +a){this.$$html5=!0;dc.apply(this,arguments);var c=bc(b);this.$$parseLinkUrl=function(d,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;b==Ha(d)?f=d:(g=za(c,d))?f=b+a+g:c===d+"/"&&(f=c);f&&this.$$parse(f);return!!f};this.$$compose=function(){var c=Nb(this.$$search),e=this.$$hash?"#"+qb(this.$$hash):"";this.$$url=ac(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+a+this.$$url}}function Gb(b){return function(){return this[b]}}function dd(b,a){return function(c){if(D(c))return this[b];this[b]= +a(c);this.$$compose();return this}}function Me(){var b="",a={enabled:!1,requireBase:!0,rewriteLinks:!0};this.hashPrefix=function(a){return y(a)?(b=a,this):b};this.html5Mode=function(b){return Wa(b)?(a.enabled=b,this):H(b)?(Wa(b.enabled)&&(a.enabled=b.enabled),Wa(b.requireBase)&&(a.requireBase=b.requireBase),Wa(b.rewriteLinks)&&(a.rewriteLinks=b.rewriteLinks),this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement","$window",function(c,d,e,f,g){function h(a,b,c){var e=k.url(),f=k.$$state; +try{d.url(a,b,c),k.$$state=d.state()}catch(g){throw k.url(e),k.$$state=f,g;}}function l(a,b){c.$broadcast("$locationChangeSuccess",k.absUrl(),a,k.$$state,b)}var k,m;m=d.baseHref();var p=d.url(),q;if(a.enabled){if(!m&&a.requireBase)throw Fb("nobase");q=p.substring(0,p.indexOf("/",p.indexOf("//")+2))+(m||"/");m=e.history?cc:cd}else q=Ha(p),m=dc;k=new m(q,"#"+b);k.$$parseLinkUrl(p,p);k.$$state=d.state();var u=/^\s*(javascript|mailto):/i;f.on("click",function(b){if(a.rewriteLinks&&!b.ctrlKey&&!b.metaKey&& +2!=b.which){for(var e=B(b.target);"a"!==ua(e[0]);)if(e[0]===f[0]||!(e=e.parent())[0])return;var h=e.prop("href"),l=e.attr("href")||e.attr("xlink:href");H(h)&&"[object SVGAnimatedString]"===h.toString()&&(h=Ba(h.animVal).href);u.test(h)||!h||e.attr("target")||b.isDefaultPrevented()||!k.$$parseLinkUrl(h,l)||(b.preventDefault(),k.absUrl()!=d.url()&&(c.$apply(),g.angular["ff-684208-preventDefault"]=!0))}});k.absUrl()!=p&&d.url(k.absUrl(),!0);var r=!0;d.onUrlChange(function(a,b){c.$evalAsync(function(){var d= +k.absUrl(),e=k.$$state,f;k.$$parse(a);k.$$state=b;f=c.$broadcast("$locationChangeStart",a,d,b,e).defaultPrevented;k.absUrl()===a&&(f?(k.$$parse(d),k.$$state=e,h(d,!1,e)):(r=!1,l(d,e)))});c.$$phase||c.$digest()});c.$watch(function(){var a=bd(d.url()),b=bd(k.absUrl()),f=d.state(),g=k.$$replace,q=a!==b||k.$$html5&&e.history&&f!==k.$$state;if(r||q)r=!1,c.$evalAsync(function(){var b=k.absUrl(),d=c.$broadcast("$locationChangeStart",b,a,k.$$state,f).defaultPrevented;k.absUrl()===b&&(d?(k.$$parse(a),k.$$state= +f):(q&&h(b,g,f===k.$$state?null:k.$$state),l(a,f)))});k.$$replace=!1});return k}]}function Ne(){var b=!0,a=this;this.debugEnabled=function(a){return y(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=c.console||{},e=b[a]||b.log||C;a=!1;try{a=!!e.apply}catch(l){}return a?function(){var a= +[];s(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function sa(b,a){if("__defineGetter__"===b||"__defineSetter__"===b||"__lookupGetter__"===b||"__lookupSetter__"===b||"__proto__"===b)throw la("isecfld",a);return b}function ta(b,a){if(b){if(b.constructor===b)throw la("isecfn",a);if(b.window===b)throw la("isecwindow", +a);if(b.children&&(b.nodeName||b.prop&&b.attr&&b.find))throw la("isecdom",a);if(b===Object)throw la("isecobj",a);}return b}function ec(b){return b.constant}function gb(b,a,c,d){ta(b,d);a=a.split(".");for(var e,f=0;1h?ed(g[0],g[1],g[2],g[3],g[4], +c,d):function(a,b){var e=0,f;do f=ed(g[e++],g[e++],g[e++],g[e++],g[e++],c,d)(a,b),b=t,a=f;while(e=this.promise.$$state.status&& +d&&d.length&&b(function(){for(var b,e,f=0,g=d.length;fa)for(b in k++,f)e.hasOwnProperty(b)||(u--,delete f[b])}else f!==e&&(f=e,k++);return k}}c.$stateful=!0;var d=this,e,f,h,l=1s&&(y=4-s,W[y]||(W[y]=[]),W[y].push({msg:G(e.exp)? +"fn: "+(e.exp.name||e.exp.toString()):e.exp,newVal:g,oldVal:l}));else if(e===c){v=!1;break a}}catch(D){f(D)}if(!(m=t.$$childHead||t!==this&&t.$$nextSibling))for(;t!==this&&!(m=t.$$nextSibling);)t=t.$parent}while(t=m);if((v||O.length)&&!s--)throw r.$$phase=null,a("infdig",b,W);}while(v||O.length);for(r.$$phase=null;n.length;)try{n.shift()()}catch(ca){f(ca)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;if(this!==r){for(var b in this.$$listenerCount)m(this, +this.$$listenerCount[b],b);a.$$childHead==this&&(a.$$childHead=this.$$nextSibling);a.$$childTail==this&&(a.$$childTail=this.$$prevSibling);this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling);this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling);this.$destroy=this.$digest=this.$apply=this.$evalAsync=this.$applyAsync=C;this.$on=this.$watch=this.$watchGroup=function(){return C};this.$$listeners={};this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead= +this.$$childTail=this.$root=this.$$watchers=null}}},$eval:function(a,b){return g(a)(this,b)},$evalAsync:function(a,b){r.$$phase||O.length||h.defer(function(){O.length&&r.$digest()});O.push({scope:this,expression:a,locals:b})},$$postDigest:function(a){n.push(a)},$apply:function(a){try{return k("$apply"),this.$eval(a)}catch(b){f(b)}finally{r.$$phase=null;try{r.$digest()}catch(c){throw f(c),c;}}},$applyAsync:function(a){function b(){c.$eval(a)}var c=this;a&&v.push(b);u()},$on:function(a,b){var c=this.$$listeners[a]; +c||(this.$$listeners[a]=c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent);var e=this;return function(){var d=c.indexOf(b);-1!==d&&(c[d]=null,m(e,1,a))}},$emit:function(a,b){var c=[],d,e=this,g=!1,h={name:a,targetScope:e,stopPropagation:function(){g=!0},preventDefault:function(){h.defaultPrevented=!0},defaultPrevented:!1},l=Ya([h],arguments,1),k,p;do{d=e.$$listeners[a]||c;h.currentScope=e;k=0;for(p=d.length;kRa)throw Ca("iequirks");var d=qa(ma);d.isEnabled=function(){return b};d.trustAs= +c.trustAs;d.getTrusted=c.getTrusted;d.valueOf=c.valueOf;b||(d.trustAs=d.getTrusted=function(a,b){return b},d.valueOf=oa);d.parseAs=function(b,c){var e=a(c);return e.literal&&e.constant?e:a(c,function(a){return d.getTrusted(b,a)})};var e=d.parseAs,f=d.getTrusted,g=d.trustAs;s(ma,function(a,b){var c=Q(b);d[cb("parse_as_"+c)]=function(b){return e(a,b)};d[cb("get_trusted_"+c)]=function(b){return f(a,b)};d[cb("trust_as_"+c)]=function(b){return g(a,b)}});return d}]}function Ue(){this.$get=["$window","$document", +function(b,a){var c={},d=ba((/android (\d+)/.exec(Q((b.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator||{}).userAgent),f=a[0]||{},g,h=/^(Moz|webkit|ms)(?=[A-Z])/,l=f.body&&f.body.style,k=!1,m=!1;if(l){for(var p in l)if(k=h.exec(p)){g=k[0];g=g.substr(0,1).toUpperCase()+g.substr(1);break}g||(g="WebkitOpacity"in l&&"webkit");k=!!("transition"in l||g+"Transition"in l);m=!!("animation"in l||g+"Animation"in l);!d||k&&m||(k=F(f.body.style.webkitTransition),m=F(f.body.style.webkitAnimation))}return{history:!(!b.history|| +!b.history.pushState||4>d||e),hasEvent:function(a){if("input"===a&&11>=Ra)return!1;if(D(c[a])){var b=f.createElement("div");c[a]="on"+a in b}return c[a]},csp:ab(),vendorPrefix:g,transitions:k,animations:m,android:d}}]}function We(){this.$get=["$templateCache","$http","$q",function(b,a,c){function d(e,f){d.totalPendingRequests++;var g=a.defaults&&a.defaults.transformResponse;x(g)?g=g.filter(function(a){return a!==Yb}):g===Yb&&(g=null);return a.get(e,{cache:b,transformResponse:g}).then(function(a){d.totalPendingRequests--; +return a.data},function(a){d.totalPendingRequests--;if(!f)throw ja("tpload",e);return c.reject(a)})}d.totalPendingRequests=0;return d}]}function Xe(){this.$get=["$rootScope","$browser","$location",function(b,a,c){return{findBindings:function(a,b,c){a=a.getElementsByClassName("ng-binding");var g=[];s(a,function(a){var d=ga.element(a).data("$binding");d&&s(d,function(d){c?(new RegExp("(^|\\s)"+gd(b)+"(\\s|\\||$)")).test(d)&&g.push(a):-1!=d.indexOf(b)&&g.push(a)})});return g},findModels:function(a,b, +c){for(var g=["ng-","data-ng-","ng\\:"],h=0;hb;b=Math.abs(b);var g=b+"",h="",l=[],k=!1;if(-1!==g.indexOf("e")){var m=g.match(/([\d\.]+)e(-?)(\d+)/);m&&"-"==m[2]&&m[3]>e+1?b=0:(h=g,k=!0)}if(k)0b&&(h=b.toFixed(e),b=parseFloat(h));else{g= +(g.split(od)[1]||"").length;D(e)&&(e=Math.min(Math.max(a.minFrac,g),a.maxFrac));b=+(Math.round(+(b.toString()+"e"+e)).toString()+"e"+-e);var g=(""+b).split(od),k=g[0],g=g[1]||"",p=0,q=a.lgSize,u=a.gSize;if(k.length>=q+u)for(p=k.length-q,m=0;mb&&(d="-",b=-b);for(b=""+b;b.length-c)e+=c;0===e&&-12==c&&(e=12);return Hb(e,a,d)}}function Ib(b,a){return function(c,d){var e=c["get"+b](),f=ub(a?"SHORT"+b:b);return d[f][e]}}function pd(b){var a=(new Date(b,0,1)).getDay();return new Date(b,0,(4>=a?5:12)-a)}function qd(b){return function(a){var c=pd(a.getFullYear());a=+new Date(a.getFullYear(),a.getMonth(), +a.getDate()+(4-a.getDay()))-+c;a=1+Math.round(a/6048E5);return Hb(a,b)}}function kd(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var f=0,g=0,h=b[8]?a.setUTCFullYear:a.setFullYear,l=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=ba(b[9]+b[10]),g=ba(b[9]+b[11]));h.call(a,ba(b[1]),ba(b[2])-1,ba(b[3]));f=ba(b[4]||0)-f;g=ba(b[5]||0)-g;h=ba(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));l.call(a,f,g,h,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/; +return function(c,e,f){var g="",h=[],l,k;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;F(c)&&(c=Kf.test(c)?ba(c):a(c));V(c)&&(c=new Date(c));if(!pa(c))return c;for(;e;)(k=Lf.exec(e))?(h=Ya(h,k,1),e=h.pop()):(h.push(e),e=null);f&&"UTC"===f&&(c=new Date(c.getTime()),c.setMinutes(c.getMinutes()+c.getTimezoneOffset()));s(h,function(a){l=Mf[a];g+=l?l(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function Ff(){return function(b,a){D(a)&&(a=2);return $a(b,a)}}function Gf(){return function(b, +a){V(b)&&(b=b.toString());if(!x(b)&&!F(b))return b;a=Infinity===Math.abs(Number(a))?Number(a):ba(a);if(F(b))return a?0<=a?b.slice(0,a):b.slice(a,b.length):"";var c,d;a>b.length?a=b.length:a<-b.length&&(a=-b.length);if(0b||37<=b&&40>=b||m(a,this,this.value)});if(e.hasEvent("paste"))a.on("paste cut",m)}a.on("change",l);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)?"":d.$viewValue)}}function Lb(b,a){return function(c,d){var e,f;if(pa(c))return c;if(F(c)){'"'==c.charAt(0)&&'"'==c.charAt(c.length-1)&&(c=c.substring(1, +c.length-1));if(Nf.test(c))return new Date(c);b.lastIndex=0;if(e=b.exec(c))return e.shift(),f=d?{yyyy:d.getFullYear(),MM:d.getMonth()+1,dd:d.getDate(),HH:d.getHours(),mm:d.getMinutes(),ss:d.getSeconds(),sss:d.getMilliseconds()/1E3}:{yyyy:1970,MM:1,dd:1,HH:0,mm:0,ss:0,sss:0},s(e,function(b,c){c=s};g.$observe("min",function(a){s=q(a);h.$validate()})}if(y(g.max)||g.ngMax){var n;h.$validators.max=function(a){return!p(a)||D(n)||c(a)<=n};g.$observe("max",function(a){n=q(a);h.$validate()})}}}function td(b,a,c,d){(d.$$hasNativeValidators=H(a[0].validity))&&d.$parsers.push(function(b){var c=a.prop("validity")||{};return c.badInput&&!c.typeMismatch?t:b})}function ud(b,a,c,d,e){if(y(d)){b=b(d);if(!b.constant)throw T("ngModel")("constexpr",c,d);return b(a)}return e} +function sd(b){function a(a,b){b&&!f[a]?(k.addClass(e,a),f[a]=!0):!b&&f[a]&&(k.removeClass(e,a),f[a]=!1)}function c(b,c){b=b?"-"+tc(b,"-"):"";a(kb+b,!0===c);a(vd+b,!1===c)}var d=b.ctrl,e=b.$element,f={},g=b.set,h=b.unset,l=b.parentForm,k=b.$animate;f[vd]=!(f[kb]=e.hasClass(kb));d.$setValidity=function(b,e,f){e===t?(d.$pending||(d.$pending={}),g(d.$pending,b,f)):(d.$pending&&h(d.$pending,b,f),wd(d.$pending)&&(d.$pending=t));Wa(e)?e?(h(d.$error,b,f),g(d.$$success,b,f)):(g(d.$error,b,f),h(d.$$success, +b,f)):(h(d.$error,b,f),h(d.$$success,b,f));d.$pending?(a(xd,!0),d.$valid=d.$invalid=t,c("",null)):(a(xd,!1),d.$valid=wd(d.$error),d.$invalid=!d.$valid,c("",d.$valid));e=d.$pending&&d.$pending[b]?t:d.$error[b]?!1:d.$$success[b]?!0:null;c(b,e);l.$setValidity(b,e,d)}}function wd(b){if(b)for(var a in b)return!1;return!0}function ic(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;d(?:<\/\1>|)$/,Rb=/<|&#?\w+;/,ef=/<([\w:]+)/,ff=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ia={option:[1,'"],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ia.optgroup=ia.option;ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead;ia.th=ia.td;var La=R.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===Y.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),R(M).on("load",a))},toString:function(){var b=[];s(this,function(a){b.push(""+ +a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?B(this[b]):B(this[this.length+b])},length:0,push:Pf,sort:[].sort,splice:[].splice},Eb={};s("multiple selected checked disabled readOnly required open".split(" "),function(b){Eb[Q(b)]=b});var Mc={};s("input select option textarea button form details".split(" "),function(b){Mc[b]=!0});var Nc={ngMinlength:"minlength",ngMaxlength:"maxlength",ngMin:"min",ngMax:"max",ngPattern:"pattern"};s({data:Ub,removeData:xb},function(b,a){R[a]=b});s({data:Ub, +inheritedData:Db,scope:function(b){return B.data(b,"$scope")||Db(b.parentNode||b,["$isolateScope","$scope"])},isolateScope:function(b){return B.data(b,"$isolateScope")||B.data(b,"$isolateScopeNoTemplate")},controller:Ic,injector:function(b){return Db(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Ab,css:function(b,a,c){a=cb(a);if(y(c))b.style[a]=c;else return b.style[a]},attr:function(b,a,c){var d=Q(a);if(Eb[d])if(y(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d)); +else return b[a]||(b.attributes.getNamedItem(a)||C).specified?d:t;else if(y(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?t:b},prop:function(b,a,c){if(y(c))b[a]=c;else return b[a]},text:function(){function b(a,b){if(D(b)){var d=a.nodeType;return d===na||d===pb?a.textContent:""}a.textContent=b}b.$dv="";return b}(),val:function(b,a){if(D(a)){if(b.multiple&&"select"===ua(b)){var c=[];s(b.options,function(a){a.selected&&c.push(a.value||a.text)});return 0===c.length? +null:c}return b.value}b.value=a},html:function(b,a){if(D(a))return b.innerHTML;wb(b,!0);b.innerHTML=a},empty:Jc},function(b,a){R.prototype[a]=function(a,d){var e,f,g=this.length;if(b!==Jc&&(2==b.length&&b!==Ab&&b!==Ic?a:d)===t){if(H(a)){for(e=0;e":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a, +c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"!":function(a,c,d){return!d(a,c)},"=":!0,"|":!0}),Xf={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'},gc=function(a){this.options=a};gc.prototype={constructor:gc,lex:function(a){this.text=a;this.index=0;for(this.tokens=[];this.index=a&&"string"===typeof a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=y(c)?"s "+c+"-"+this.index+" ["+this.text.substring(c, +d)+"]":" "+d;throw la("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.indexa){a=this.tokens[a];var g=a.text;if(g===c||g===d||g===e||g===f||!(c||d||e||f))return a}return!1},expect:function(a,c,d,e){return(a=this.peek(a,c,d,e))?(this.tokens.shift(),a):!1},consume:function(a){if(0===this.tokens.length)throw la("ueoe",this.text);var c=this.expect(a);c||this.throwError("is unexpected, expecting ["+a+"]",this.peek());return c},unaryFn:function(a,c){var d=mb[a];return z(function(a,f){return d(a,f,c)},{constant:c.constant,inputs:[c]})},binaryFn:function(a, +c,d,e){var f=mb[c];return z(function(c,e){return f(c,e,a,d)},{constant:a.constant&&d.constant,inputs:!e&&[a,d]})},identifier:function(){for(var a=this.consume().text;this.peek(".")&&this.peekAhead(1).identifier&&!this.peekAhead(2,"(");)a+=this.consume().text+this.consume().text;return zf(a,this.options,this.text)},constant:function(){var a=this.consume().value;return z(function(){return a},{constant:!0,literal:!0})},statements:function(){for(var a=[];;)if(0","<=",">=");)a=this.binaryFn(a,c.text,this.additive());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.text,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.text,this.unary());return a},unary:function(){var a;return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn(hb.ZERO, +a.text,this.unary()):(a=this.expect("!"))?this.unaryFn(a.text,this.unary()):this.primary()},fieldAccess:function(a){var c=this.identifier();return z(function(d,e,f){d=f||a(d,e);return null==d?t:c(d)},{assign:function(d,e,f){(f=a(d,f))||a.assign(d,f={});return c.assign(f,e)}})},objectIndex:function(a){var c=this.text,d=this.expression();this.consume("]");return z(function(e,f){var g=a(e,f),h=d(e,f);sa(h,c);return g?ta(g[h],c):t},{assign:function(e,f,g){var h=sa(d(e,g),c);(g=ta(a(e,g),c))||a.assign(e, +g={});return g[h]=f}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this.text,f=d.length?[]:null;return function(g,h){var l=c?c(g,h):y(c)?t:g,k=a(g,h,l)||C;if(f)for(var m=d.length;m--;)f[m]=ta(d[m](g,h),e);ta(l,e);if(k){if(k.constructor===k)throw la("isecfn",e);if(k===Uf||k===Vf||k===Wf)throw la("isecff",e);}l=k.apply?k.apply(l,f):k(f[0],f[1],f[2],f[3],f[4]);return ta(l,e)}},arrayDeclaration:function(){var a= +[];if("]"!==this.peekToken().text){do{if(this.peek("]"))break;a.push(this.expression())}while(this.expect(","))}this.consume("]");return z(function(c,d){for(var e=[],f=0,g=a.length;fa.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Hb(Math[0=h};d.$observe("min",function(a){y(a)&&!V(a)&&(a=parseFloat(a,10));h=V(a)&&!isNaN(a)?a:t;e.$validate()})}if(d.max||d.ngMax){var l;e.$validators.max=function(a){return e.$isEmpty(a)|| +D(l)||a<=l};d.$observe("max",function(a){y(a)&&!V(a)&&(a=parseFloat(a,10));l=V(a)&&!isNaN(a)?a:t;e.$validate()})}},url:function(a,c,d,e,f,g){ib(a,c,d,e,f,g);hc(e);e.$$parserName="url";e.$validators.url=function(a,c){var d=a||c;return e.$isEmpty(d)||Yf.test(d)}},email:function(a,c,d,e,f,g){ib(a,c,d,e,f,g);hc(e);e.$$parserName="email";e.$validators.email=function(a,c){var d=a||c;return e.$isEmpty(d)||Zf.test(d)}},radio:function(a,c,d,e){D(d.name)&&c.attr("name",++nb);c.on("click",function(a){c[0].checked&& +e.$setViewValue(d.value,a&&a.type)});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e,f,g,h,l){var k=ud(l,a,"ngTrueValue",d.ngTrueValue,!0),m=ud(l,a,"ngFalseValue",d.ngFalseValue,!1);c.on("click",function(a){e.$setViewValue(c[0].checked,a&&a.type)});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return!1===a};e.$formatters.push(function(a){return fa(a,k)});e.$parsers.push(function(a){return a?k:m})},hidden:C, +button:C,submit:C,reset:C,file:C},xc=["$browser","$sniffer","$filter","$parse",function(a,c,d,e){return{restrict:"E",require:["?ngModel"],link:{pre:function(f,g,h,l){l[0]&&(Dd[Q(h.type)]||Dd.text)(f,g,h,l[0],c,a,d,e)}}}}],kb="ng-valid",vd="ng-invalid",Sa="ng-pristine",Kb="ng-dirty",xd="ng-pending",bg=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate","$timeout","$rootScope","$q","$interpolate",function(a,c,d,e,f,g,h,l,k,m){this.$modelValue=this.$viewValue=Number.NaN;this.$$rawModelValue= +t;this.$validators={};this.$asyncValidators={};this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$untouched=!0;this.$touched=!1;this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$error={};this.$$success={};this.$pending=t;this.$name=m(d.name||"",!1)(a);var p=f(d.ngModel),q=p.assign,u=p,r=q,O=null,n=this;this.$$setOptions=function(a){if((n.$options=a)&&a.getterSetter){var c=f(d.ngModel+"()"),g=f(d.ngModel+"($$$p)");u=function(a){var d=p(a);G(d)&&(d=c(a));return d}; +r=function(a,c){G(p(a))?g(a,{$$$p:n.$modelValue}):q(a,n.$modelValue)}}else if(!p.assign)throw Mb("nonassign",d.ngModel,va(e));};this.$render=C;this.$isEmpty=function(a){return D(a)||""===a||null===a||a!==a};var v=e.inheritedData("$formController")||Jb,w=0;sd({ctrl:this,$element:e,set:function(a,c){a[c]=!0},unset:function(a,c){delete a[c]},parentForm:v,$animate:g});this.$setPristine=function(){n.$dirty=!1;n.$pristine=!0;g.removeClass(e,Kb);g.addClass(e,Sa)};this.$setDirty=function(){n.$dirty=!0;n.$pristine= +!1;g.removeClass(e,Sa);g.addClass(e,Kb);v.$setDirty()};this.$setUntouched=function(){n.$touched=!1;n.$untouched=!0;g.setClass(e,"ng-untouched","ng-touched")};this.$setTouched=function(){n.$touched=!0;n.$untouched=!1;g.setClass(e,"ng-touched","ng-untouched")};this.$rollbackViewValue=function(){h.cancel(O);n.$viewValue=n.$$lastCommittedViewValue;n.$render()};this.$validate=function(){if(!V(n.$modelValue)||!isNaN(n.$modelValue)){var a=n.$$rawModelValue,c=n.$valid,d=n.$modelValue,e=n.$options&&n.$options.allowInvalid; +n.$$runValidators(n.$error[n.$$parserName||"parse"]?!1:t,a,n.$$lastCommittedViewValue,function(f){e||c===f||(n.$modelValue=f?a:t,n.$modelValue!==d&&n.$$writeModelToScope())})}};this.$$runValidators=function(a,c,d,e){function f(){var a=!0;s(n.$validators,function(e,f){var g=e(c,d);a=a&&g;h(f,g)});return a?!0:(s(n.$asyncValidators,function(a,c){h(c,null)}),!1)}function g(){var a=[],e=!0;s(n.$asyncValidators,function(f,g){var l=f(c,d);if(!l||!G(l.then))throw Mb("$asyncValidators",l);h(g,t);a.push(l.then(function(){h(g, +!0)},function(a){e=!1;h(g,!1)}))});a.length?k.all(a).then(function(){l(e)},C):l(!0)}function h(a,c){m===w&&n.$setValidity(a,c)}function l(a){m===w&&e(a)}w++;var m=w;(function(a){var c=n.$$parserName||"parse";if(a===t)h(c,null);else if(h(c,a),!a)return s(n.$validators,function(a,c){h(c,null)}),s(n.$asyncValidators,function(a,c){h(c,null)}),!1;return!0})(a)?f()?g():l(!1):l(!1)};this.$commitViewValue=function(){var a=n.$viewValue;h.cancel(O);if(n.$$lastCommittedViewValue!==a||""===a&&n.$$hasNativeValidators)n.$$lastCommittedViewValue= +a,n.$pristine&&this.$setDirty(),this.$$parseAndValidate()};this.$$parseAndValidate=function(){var c=n.$$lastCommittedViewValue,d=D(c)?t:!0;if(d)for(var e=0;ef||e.$isEmpty(a)||c.length<=f}}}}},Ac=function(){return{restrict:"A",require:"?ngModel",link:function(a,c,d,e){if(e){var f=0;d.$observe("minlength", +function(a){f=ba(a)||0;e.$validate()});e.$validators.minlength=function(a,c){return e.$isEmpty(c)||c.length>=f}}}}},we=function(){return{restrict:"A",priority:100,require:"ngModel",link:function(a,c,d,e){var f=c.attr(d.$attr.ngList)||", ",g="false"!==d.ngTrim,h=g?U(f):f;e.$parsers.push(function(a){if(!D(a)){var c=[];a&&s(a.split(h),function(a){a&&c.push(g?U(a):a)});return c}});e.$formatters.push(function(a){return x(a)?a.join(f):t});e.$isEmpty=function(a){return!a||!a.length}}}},cg=/^(true|false|\d+)$/, +ye=function(){return{restrict:"A",priority:100,compile:function(a,c){return cg.test(c.ngValue)?function(a,c,f){f.$set("value",a.$eval(f.ngValue))}:function(a,c,f){a.$watch(f.ngValue,function(a){f.$set("value",a)})}}}},ze=function(){return{restrict:"A",controller:["$scope","$attrs",function(a,c){var d=this;this.$options=a.$eval(c.ngModelOptions);this.$options.updateOn!==t?(this.$options.updateOnDefault=!1,this.$options.updateOn=U(this.$options.updateOn.replace(ag,function(){d.$options.updateOnDefault= +!0;return" "}))):this.$options.updateOnDefault=!0}]}},Zd=["$compile",function(a){return{restrict:"AC",compile:function(c){a.$$addBindingClass(c);return function(c,e,f){a.$$addBindingInfo(e,f.ngBind);e=e[0];c.$watch(f.ngBind,function(a){e.textContent=a===t?"":a})}}}}],ae=["$interpolate","$compile",function(a,c){return{compile:function(d){c.$$addBindingClass(d);return function(d,f,g){d=a(f.attr(g.$attr.ngBindTemplate));c.$$addBindingInfo(f,d.expressions);f=f[0];g.$observe("ngBindTemplate",function(a){f.textContent= +a===t?"":a})}}}}],$d=["$sce","$parse","$compile",function(a,c,d){return{restrict:"A",compile:function(e,f){var g=c(f.ngBindHtml),h=c(f.ngBindHtml,function(a){return(a||"").toString()});d.$$addBindingClass(e);return function(c,e,f){d.$$addBindingInfo(e,f.ngBindHtml);c.$watch(h,function(){e.html(a.getTrustedHtml(g(c))||"")})}}}}],be=ic("",!0),de=ic("Odd",0),ce=ic("Even",1),ee=Ja({compile:function(a,c){c.$set("ngCloak",t);a.removeClass("ng-cloak")}}),fe=[function(){return{restrict:"A",scope:!0,controller:"@", +priority:500}}],Cc={},dg={blur:!0,focus:!0};s("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var c=ya("ng-"+a);Cc[c]=["$parse","$rootScope",function(d,e){return{restrict:"A",compile:function(f,g){var h=d(g[c],null,!0);return function(c,d){d.on(a,function(d){var f=function(){h(c,{$event:d})};dg[a]&&e.$$phase?c.$evalAsync(f):c.$apply(f)})}}}}]});var ie=["$animate",function(a){return{multiElement:!0, +transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(c,d,e,f,g){var h,l,k;c.$watch(e.ngIf,function(c){c?l||g(function(c,f){l=f;c[c.length++]=Y.createComment(" end ngIf: "+e.ngIf+" ");h={clone:c};a.enter(c,d.parent(),d)}):(k&&(k.remove(),k=null),l&&(l.$destroy(),l=null),h&&(k=tb(h.clone),a.leave(k).then(function(){k=null}),h=null))})}}}],je=["$templateRequest","$anchorScroll","$animate","$sce",function(a,c,d,e){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element", +controller:ga.noop,compile:function(f,g){var h=g.ngInclude||g.src,l=g.onload||"",k=g.autoscroll;return function(f,g,q,s,r){var t=0,n,v,w,L=function(){v&&(v.remove(),v=null);n&&(n.$destroy(),n=null);w&&(d.leave(w).then(function(){v=null}),v=w,w=null)};f.$watch(e.parseAsResourceUrl(h),function(e){var h=function(){!y(k)||k&&!f.$eval(k)||c()},q=++t;e?(a(e,!0).then(function(a){if(q===t){var c=f.$new();s.template=a;a=r(c,function(a){L();d.enter(a,null,g).then(h)});n=c;w=a;n.$emit("$includeContentLoaded", +e);f.$eval(l)}},function(){q===t&&(L(),f.$emit("$includeContentError",e))}),f.$emit("$includeContentRequested",e)):(L(),s.template=null)})}}}}],Ae=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(c,d,e,f){/SVG/.test(d[0].toString())?(d.empty(),a(Fc(f.template,Y).childNodes)(c,function(a){d.append(a)},{futureParentElement:d})):(d.html(f.template),a(d.contents())(c))}}}],ke=Ja({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}), +le=Ja({terminal:!0,priority:1E3}),me=["$locale","$interpolate",function(a,c){var d=/{}/g,e=/^when(Minus)?(.+)$/;return{restrict:"EA",link:function(f,g,h){function l(a){g.text(a||"")}var k=h.count,m=h.$attr.when&&g.attr(h.$attr.when),p=h.offset||0,q=f.$eval(m)||{},u={},m=c.startSymbol(),r=c.endSymbol(),t=m+k+"-"+p+r,n=ga.noop,v;s(h,function(a,c){var d=e.exec(c);d&&(d=(d[1]?"-":"")+Q(d[2]),q[d]=g.attr(h.$attr[c]))});s(q,function(a,e){u[e]=c(a.replace(d,t))});f.$watch(k,function(c){c=parseFloat(c);var d= +isNaN(c);d||c in q||(c=a.pluralCat(c-p));c===v||d&&isNaN(v)||(n(),n=f.$watch(u[c],l),v=c)})}}}],ne=["$parse","$animate",function(a,c){var d=T("ngRepeat"),e=function(a,c,d,e,k,m,p){a[d]=e;k&&(a[k]=m);a.$index=c;a.$first=0===c;a.$last=c===p-1;a.$middle=!(a.$first||a.$last);a.$odd=!(a.$even=0===(c&1))};return{restrict:"A",multiElement:!0,transclude:"element",priority:1E3,terminal:!0,$$tlb:!0,compile:function(f,g){var h=g.ngRepeat,l=Y.createComment(" end ngRepeat: "+h+" "),k=h.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/); +if(!k)throw d("iexp",h);var m=k[1],p=k[2],q=k[3],u=k[4],k=m.match(/^(?:(\s*[\$\w]+)|\(\s*([\$\w]+)\s*,\s*([\$\w]+)\s*\))$/);if(!k)throw d("iidexp",m);var r=k[3]||k[1],y=k[2];if(q&&(!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(q)||/^(null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent)$/.test(q)))throw d("badident",q);var n,v,w,D,z={$id:Na};u?n=a(u):(w=function(a,c){return Na(c)},D=function(a){return a});return function(a,f,g,k,m){n&&(v=function(c,d,e){y&&(z[y]=c);z[r]=d;z.$index=e;return n(a, +z)});var u=ha();a.$watchCollection(p,function(g){var k,p,n=f[0],E,z=ha(),C,S,N,G,J,x,H;q&&(a[q]=g);if(Ta(g))J=g,p=v||w;else{p=v||D;J=[];for(H in g)g.hasOwnProperty(H)&&"$"!=H.charAt(0)&&J.push(H);J.sort()}C=J.length;H=Array(C);for(k=0;kF;)d=r.pop(),m(N,d.label,!1),d.element.remove()}for(;R.length>x;){l=R.pop(); +for(F=1;Fa&&q.removeOption(c)})}var n;if(!(n=r.match(d)))throw eg("iexp",r,va(f));var C=c(n[2]||n[1]),A=n[4]||n[6],D=/ as /.test(n[0])&&n[1],B=D?c(D):null,H=n[5],J=c(n[3]||""),F=c(n[2]?n[1]:A),P=c(n[7]),M=n[8]?c(n[8]):null,Q={},R=[[{element:f,label:""}]],T={};z&&(a(z)(e),z.removeClass("ng-scope"),z.remove());f.empty();f.on("change",function(){e.$apply(function(){var a=P(e)||[],c;if(u)c=[],s(f.val(),function(d){d= +M?Q[d]:d;c.push("?"===d?t:""===d?null:h(B?B:F,d,a[d]))});else{var d=M?Q[f.val()]:f.val();c="?"===d?t:""===d?null:h(B?B:F,d,a[d])}g.$setViewValue(c);p()})});g.$render=p;e.$watchCollection(P,l);e.$watchCollection(function(){var a=P(e),c;if(a&&x(a)){c=Array(a.length);for(var d=0,f=a.length;d@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\:form{display:block;}'); +//# sourceMappingURL=angular.min.js.map diff --git a/assets/vendor/prettify.js b/assets/vendor/prettify.js new file mode 100644 index 0000000..018b859 --- /dev/null +++ b/assets/vendor/prettify.js @@ -0,0 +1,1538 @@ +// Copyright (C) 2006 Google Inc. +// +// 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. + + +/** + * @fileoverview + * some functions for browser-side pretty printing of code contained in html. + * + *

+ * For a fairly comprehensive set of languages see the + * README + * file that came with this source. At a minimum, the lexer should work on a + * number of languages including C and friends, Java, Python, Bash, SQL, HTML, + * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk + * and a subset of Perl, but, because of commenting conventions, doesn't work on + * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. + *

+ * Usage:

    + *
  1. include this source file in an html page via + * {@code } + *
  2. define style rules. See the example page for examples. + *
  3. mark the {@code
    } and {@code } tags in your source with
    + *    {@code class=prettyprint.}
    + *    You can also use the (html deprecated) {@code } tag, but the pretty
    + *    printer needs to do more substantial DOM manipulations to support that, so
    + *    some css styles may not be preserved.
    + * </ol>
    + * That's it.  I wanted to keep the API as simple as possible, so there's no
    + * need to specify which language the code is in, but if you wish, you can add
    + * another class to the {@code <pre>} or {@code <code>} element to specify the
    + * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
    + * starts with "lang-" followed by a file extension, specifies the file type.
    + * See the "lang-*.js" files in this directory for code that implements
    + * per-language file handlers.
    + * <p>
    + * Change log:<br>
    + * cbeust, 2006/08/22
    + * <blockquote>
    + *   Java annotations (start with "@") are now captured as literals ("lit")
    + * </blockquote>
    + * @requires console
    + */
    +
    +// JSLint declarations
    +/*global console, document, navigator, setTimeout, window, define */
    +
    +/**
    + * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
    + * UI events.
    + * If set to {@code false}, {@code prettyPrint()} is synchronous.
    + */
    +window['PR_SHOULD_USE_CONTINUATION'] = true;
    +
    +/**
    + * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    + * {@code class=prettyprint} and prettify them.
    + *
    + * @param {Function?} opt_whenDone if specified, called when the last entry
    + *     has been finished.
    + */
    +var prettyPrintOne;
    +/**
    + * Pretty print a chunk of code.
    + *
    + * @param {string} sourceCodeHtml code as html
    + * @return {string} code as html, but prettier
    + */
    +var prettyPrint;
    +
    +
    +(function () {
    +  var win = window;
    +  // Keyword lists for various languages.
    +  // We use things that coerce to strings to make them compact when minified
    +  // and to defeat aggressive optimizers that fold large string constants.
    +  var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
    +  var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
    +    "double,enum,extern,float,goto,int,long,register,short,signed,sizeof," +
    +    "static,struct,switch,typedef,union,unsigned,void,volatile"];
    +  var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
    +    "new,operator,private,protected,public,this,throw,true,try,typeof"];
    +  var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
    +    "concept,concept_map,const_cast,constexpr,decltype," +
    +    "dynamic_cast,explicit,export,friend,inline,late_check," +
    +    "mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast," +
    +    "template,typeid,typename,using,virtual,where"];
    +  var JAVA_KEYWORDS = [COMMON_KEYWORDS,
    +    "abstract,boolean,byte,extends,final,finally,implements,import," +
    +      "instanceof,null,native,package,strictfp,super,synchronized,throws," +
    +      "transient"];
    +  var CSHARP_KEYWORDS = [JAVA_KEYWORDS,
    +    "as,base,by,checked,decimal,delegate,descending,dynamic,event," +
    +      "fixed,foreach,from,group,implicit,in,interface,internal,into,is,let," +
    +      "lock,object,out,override,orderby,params,partial,readonly,ref,sbyte," +
    +      "sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort," +
    +      "var,virtual,where"];
    +  var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
    +    "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
    +    "throw,true,try,unless,until,when,while,yes";
    +  var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
    +    "debugger,eval,export,function,get,null,set,undefined,var,with," +
    +      "Infinity,NaN"];
    +  var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
    +    "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
    +    "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
    +  var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
    +    "elif,except,exec,finally,from,global,import,in,is,lambda," +
    +    "nonlocal,not,or,pass,print,raise,try,with,yield," +
    +    "False,True,None"];
    +  var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
    +    "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
    +    "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
    +    "BEGIN,END"];
    +  var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
    +    "function,in,local,set,then,until"];
    +  var ALL_KEYWORDS = [
    +    CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS +
    +      PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
    +  var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
    +
    +  // token style names.  correspond to css classes
    +  /**
    +   * token style for a string literal
    +   * @const
    +   */
    +  var PR_STRING = 'str';
    +  /**
    +   * token style for a keyword
    +   * @const
    +   */
    +  var PR_KEYWORD = 'kwd';
    +  /**
    +   * token style for a comment
    +   * @const
    +   */
    +  var PR_COMMENT = 'com';
    +  /**
    +   * token style for a type
    +   * @const
    +   */
    +  var PR_TYPE = 'typ';
    +  /**
    +   * token style for a literal value.  e.g. 1, null, true.
    +   * @const
    +   */
    +  var PR_LITERAL = 'lit';
    +  /**
    +   * token style for a punctuation string.
    +   * @const
    +   */
    +  var PR_PUNCTUATION = 'pun';
    +  /**
    +   * token style for plain text.
    +   * @const
    +   */
    +  var PR_PLAIN = 'pln';
    +
    +  /**
    +   * token style for an sgml tag.
    +   * @const
    +   */
    +  var PR_TAG = 'tag';
    +  /**
    +   * token style for a markup declaration such as a DOCTYPE.
    +   * @const
    +   */
    +  var PR_DECLARATION = 'dec';
    +  /**
    +   * token style for embedded source.
    +   * @const
    +   */
    +  var PR_SOURCE = 'src';
    +  /**
    +   * token style for an sgml attribute name.
    +   * @const
    +   */
    +  var PR_ATTRIB_NAME = 'atn';
    +  /**
    +   * token style for an sgml attribute value.
    +   * @const
    +   */
    +  var PR_ATTRIB_VALUE = 'atv';
    +
    +  /**
    +   * A class that indicates a section of markup that is not code, e.g. to allow
    +   * embedding of line numbers within code listings.
    +   * @const
    +   */
    +  var PR_NOCODE = 'nocode';
    +
    +
    +
    +  /**
    +   * A set of tokens that can precede a regular expression literal in
    +   * javascript
    +   * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
    +   * has the full list, but I've removed ones that might be problematic when
    +   * seen in languages that don't support regular expression literals.
    +   *
    +   * <p>Specifically, I've removed any keywords that can't precede a regexp
    +   * literal in a syntactically legal javascript program, and I've removed the
    +   * "in" keyword since it's not a keyword in many languages, and might be used
    +   * as a count of inches.
    +   *
    +   * <p>The link above does not accurately describe EcmaScript rules since
    +   * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
    +   * very well in practice.
    +   *
    +   * @private
    +   * @const
    +   */
    +  var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
    +
    +// CAVEAT: this does not properly handle the case where a regular
    +// expression immediately follows another since a regular expression may
    +// have flags for case-sensitivity and the like.  Having regexp tokens
    +// adjacent is not valid in any language I'm aware of, so I'm punting.
    +// TODO: maybe style special characters inside a regexp as punctuation.
    +
    +
    +  /**
    +   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
    +   * matches the union of the sets of strings matched by the input RegExp.
    +   * Since it matches globally, if the input strings have a start-of-input
    +   * anchor (/^.../), it is ignored for the purposes of unioning.
    +   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
    +   * @return {RegExp} a global regex.
    +   */
    +  function combinePrefixPatterns(regexs) {
    +    var capturedGroupIndex = 0;
    +
    +    var needToFoldCase = false;
    +    var ignoreCase = false;
    +    for (var i = 0, n = regexs.length; i < n; ++i) {
    +      var regex = regexs[i];
    +      if (regex.ignoreCase) {
    +        ignoreCase = true;
    +      } else if (/[a-z]/i.test(regex.source.replace(
    +        /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
    +        needToFoldCase = true;
    +        ignoreCase = false;
    +        break;
    +      }
    +    }
    +
    +    var escapeCharToCodeUnit = {
    +      'b': 8,
    +      't': 9,
    +      'n': 0xa,
    +      'v': 0xb,
    +      'f': 0xc,
    +      'r': 0xd
    +    };
    +
    +    function decodeEscape(charsetPart) {
    +      var cc0 = charsetPart.charCodeAt(0);
    +      if (cc0 !== 92 /* \\ */) {
    +        return cc0;
    +      }
    +      var c1 = charsetPart.charAt(1);
    +      cc0 = escapeCharToCodeUnit[c1];
    +      if (cc0) {
    +        return cc0;
    +      } else if ('0' <= c1 && c1 <= '7') {
    +        return parseInt(charsetPart.substring(1), 8);
    +      } else if (c1 === 'u' || c1 === 'x') {
    +        return parseInt(charsetPart.substring(2), 16);
    +      } else {
    +        return charsetPart.charCodeAt(1);
    +      }
    +    }
    +
    +    function encodeEscape(charCode) {
    +      if (charCode < 0x20) {
    +        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
    +      }
    +      var ch = String.fromCharCode(charCode);
    +      return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
    +        ? "\\" + ch : ch;
    +    }
    +
    +    function caseFoldCharset(charSet) {
    +      var charsetParts = charSet.substring(1, charSet.length - 1).match(
    +        new RegExp(
    +          '\\\\u[0-9A-Fa-f]{4}'
    +            + '|\\\\x[0-9A-Fa-f]{2}'
    +            + '|\\\\[0-3][0-7]{0,2}'
    +            + '|\\\\[0-7]{1,2}'
    +            + '|\\\\[\\s\\S]'
    +            + '|-'
    +            + '|[^-\\\\]',
    +          'g'));
    +      var ranges = [];
    +      var inverse = charsetParts[0] === '^';
    +
    +      var out = ['['];
    +      if (inverse) { out.push('^'); }
    +
    +      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
    +        var p = charsetParts[i];
    +        if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
    +          out.push(p);
    +        } else {
    +          var start = decodeEscape(p);
    +          var end;
    +          if (i + 2 < n && '-' === charsetParts[i + 1]) {
    +            end = decodeEscape(charsetParts[i + 2]);
    +            i += 2;
    +          } else {
    +            end = start;
    +          }
    +          ranges.push([start, end]);
    +          // If the range might intersect letters, then expand it.
    +          // This case handling is too simplistic.
    +          // It does not deal with non-latin case folding.
    +          // It works for latin source code identifiers though.
    +          if (!(end < 65 || start > 122)) {
    +            if (!(end < 65 || start > 90)) {
    +              ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
    +            }
    +            if (!(end < 97 || start > 122)) {
    +              ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
    +            }
    +          }
    +        }
    +      }
    +
    +      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
    +      // -> [[1, 12], [14, 14], [16, 17]]
    +      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
    +      var consolidatedRanges = [];
    +      var lastRange = [];
    +      for (var i = 0; i < ranges.length; ++i) {
    +        var range = ranges[i];
    +        if (range[0] <= lastRange[1] + 1) {
    +          lastRange[1] = Math.max(lastRange[1], range[1]);
    +        } else {
    +          consolidatedRanges.push(lastRange = range);
    +        }
    +      }
    +
    +      for (var i = 0; i < consolidatedRanges.length; ++i) {
    +        var range = consolidatedRanges[i];
    +        out.push(encodeEscape(range[0]));
    +        if (range[1] > range[0]) {
    +          if (range[1] + 1 > range[0]) { out.push('-'); }
    +          out.push(encodeEscape(range[1]));
    +        }
    +      }
    +      out.push(']');
    +      return out.join('');
    +    }
    +
    +    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
    +      // Split into character sets, escape sequences, punctuation strings
    +      // like ('(', '(?:', ')', '^'), and runs of characters that do not
    +      // include any of the above.
    +      var parts = regex.source.match(
    +        new RegExp(
    +          '(?:'
    +            + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
    +            + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
    +            + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
    +            + '|\\\\[0-9]+'  // a back-reference or octal escape
    +            + '|\\\\[^ux0-9]'  // other escape sequence
    +            + '|\\(\\?[:!=]'  // start of a non-capturing group
    +            + '|[\\(\\)\\^]'  // start/end of a group, or line start
    +            + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
    +            + ')',
    +          'g'));
    +      var n = parts.length;
    +
    +      // Maps captured group numbers to the number they will occupy in
    +      // the output or to -1 if that has not been determined, or to
    +      // undefined if they need not be capturing in the output.
    +      var capturedGroups = [];
    +
    +      // Walk over and identify back references to build the capturedGroups
    +      // mapping.
    +      for (var i = 0, groupIndex = 0; i < n; ++i) {
    +        var p = parts[i];
    +        if (p === '(') {
    +          // groups are 1-indexed, so max group index is count of '('
    +          ++groupIndex;
    +        } else if ('\\' === p.charAt(0)) {
    +          var decimalValue = +p.substring(1);
    +          if (decimalValue) {
    +            if (decimalValue <= groupIndex) {
    +              capturedGroups[decimalValue] = -1;
    +            } else {
    +              // Replace with an unambiguous escape sequence so that
    +              // an octal escape sequence does not turn into a backreference
    +              // to a capturing group from an earlier regex.
    +              parts[i] = encodeEscape(decimalValue);
    +            }
    +          }
    +        }
    +      }
    +
    +      // Renumber groups and reduce capturing groups to non-capturing groups
    +      // where possible.
    +      for (var i = 1; i < capturedGroups.length; ++i) {
    +        if (-1 === capturedGroups[i]) {
    +          capturedGroups[i] = ++capturedGroupIndex;
    +        }
    +      }
    +      for (var i = 0, groupIndex = 0; i < n; ++i) {
    +        var p = parts[i];
    +        if (p === '(') {
    +          ++groupIndex;
    +          if (!capturedGroups[groupIndex]) {
    +            parts[i] = '(?:';
    +          }
    +        } else if ('\\' === p.charAt(0)) {
    +          var decimalValue = +p.substring(1);
    +          if (decimalValue && decimalValue <= groupIndex) {
    +            parts[i] = '\\' + capturedGroups[decimalValue];
    +          }
    +        }
    +      }
    +
    +      // Remove any prefix anchors so that the output will match anywhere.
    +      // ^^ really does mean an anchored match though.
    +      for (var i = 0; i < n; ++i) {
    +        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
    +      }
    +
    +      // Expand letters to groups to handle mixing of case-sensitive and
    +      // case-insensitive patterns if necessary.
    +      if (regex.ignoreCase && needToFoldCase) {
    +        for (var i = 0; i < n; ++i) {
    +          var p = parts[i];
    +          var ch0 = p.charAt(0);
    +          if (p.length >= 2 && ch0 === '[') {
    +            parts[i] = caseFoldCharset(p);
    +          } else if (ch0 !== '\\') {
    +            // TODO: handle letters in numeric escapes.
    +            parts[i] = p.replace(
    +              /[a-zA-Z]/g,
    +              function (ch) {
    +                var cc = ch.charCodeAt(0);
    +                return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
    +              });
    +          }
    +        }
    +      }
    +
    +      return parts.join('');
    +    }
    +
    +    var rewritten = [];
    +    for (var i = 0, n = regexs.length; i < n; ++i) {
    +      var regex = regexs[i];
    +      if (regex.global || regex.multiline) { throw new Error('' + regex); }
    +      rewritten.push(
    +        '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
    +    }
    +
    +    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
    +  }
    +
    +
    +  /**
    +   * Split markup into a string of source code and an array mapping ranges in
    +   * that string to the text nodes in which they appear.
    +   *
    +   * <p>
    +   * The HTML DOM structure:</p>
    +   * <pre>
    +   * (Element   "p"
    +   *   (Element "b"
    +   *     (Text  "print "))       ; #1
    +   *   (Text    "'Hello '")      ; #2
    +   *   (Element "br")            ; #3
    +   *   (Text    "  + 'World';")) ; #4
    +   * </pre>
    +   * <p>
    +   * corresponds to the HTML
    +   * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
    +   *
    +   * <p>
    +   * It will produce the output:</p>
    +   * <pre>
    +   * {
    +   *   sourceCode: "print 'Hello '\n  + 'World';",
    +   *   //                     1          2
    +   *   //           012345678901234 5678901234567
    +   *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
    +   * }
    +   * </pre>
    +   * <p>
    +   * where #1 is a reference to the {@code "print "} text node above, and so
    +   * on for the other text nodes.
    +   * </p>
    +   *
    +   * <p>
    +   * The {@code} spans array is an array of pairs.  Even elements are the start
    +   * indices of substrings, and odd elements are the text nodes (or BR elements)
    +   * that contain the text for those substrings.
    +   * Substrings continue until the next index or the end of the source.
    +   * </p>
    +   *
    +   * @param {Node} node an HTML DOM subtree containing source-code.
    +   * @param {boolean} isPreformatted true if white-space in text nodes should
    +   *    be considered significant.
    +   * @return {Object} source code and the text nodes in which they occur.
    +   */
    +  function extractSourceSpans(node, isPreformatted) {
    +    var nocode = /(?:^|\s)nocode(?:\s|$)/;
    +
    +    var chunks = [];
    +    var length = 0;
    +    var spans = [];
    +    var k = 0;
    +
    +    function walk(node) {
    +      switch (node.nodeType) {
    +        case 1:  // Element
    +          if (nocode.test(node.className)) { return; }
    +          for (var child = node.firstChild; child; child = child.nextSibling) {
    +            walk(child);
    +          }
    +          var nodeName = node.nodeName.toLowerCase();
    +          if ('br' === nodeName || 'li' === nodeName) {
    +            chunks[k] = '\n';
    +            spans[k << 1] = length++;
    +            spans[(k++ << 1) | 1] = node;
    +          }
    +          break;
    +        case 3: case 4:  // Text
    +        var text = node.nodeValue;
    +        if (text.length) {
    +          if (!isPreformatted) {
    +            text = text.replace(/[ \t\r\n]+/g, ' ');
    +          } else {
    +            text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
    +          }
    +          // TODO: handle tabs here?
    +          chunks[k] = text;
    +          spans[k << 1] = length;
    +          length += text.length;
    +          spans[(k++ << 1) | 1] = node;
    +        }
    +        break;
    +      }
    +    }
    +
    +    walk(node);
    +
    +    return {
    +      sourceCode: chunks.join('').replace(/\n$/, ''),
    +      spans: spans
    +    };
    +  }
    +
    +
    +  /**
    +   * Apply the given language handler to sourceCode and add the resulting
    +   * decorations to out.
    +   * @param {number} basePos the index of sourceCode within the chunk of source
    +   *    whose decorations are already present on out.
    +   */
    +  function appendDecorations(basePos, sourceCode, langHandler, out) {
    +    if (!sourceCode) { return; }
    +    var job = {
    +      sourceCode: sourceCode,
    +      basePos: basePos
    +    };
    +    langHandler(job);
    +    out.push.apply(out, job.decorations);
    +  }
    +
    +  var notWs = /\S/;
    +
    +  /**
    +   * Given an element, if it contains only one child element and any text nodes
    +   * it contains contain only space characters, return the sole child element.
    +   * Otherwise returns undefined.
    +   * <p>
    +   * This is meant to return the CODE element in {@code <pre><code ...>} when
    +   * there is a single child element that contains all the non-space textual
    +   * content, but not to return anything where there are multiple child elements
    +   * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
    +   * is textual content.
    +   */
    +  function childContentWrapper(element) {
    +    var wrapper = undefined;
    +    for (var c = element.firstChild; c; c = c.nextSibling) {
    +      var type = c.nodeType;
    +      wrapper = (type === 1)  // Element Node
    +        ? (wrapper ? element : c)
    +        : (type === 3)  // Text Node
    +        ? (notWs.test(c.nodeValue) ? element : wrapper)
    +        : wrapper;
    +    }
    +    return wrapper === element ? undefined : wrapper;
    +  }
    +
    +  /** Given triples of [style, pattern, context] returns a lexing function,
    +   * The lexing function interprets the patterns to find token boundaries and
    +   * returns a decoration list of the form
    +   * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
    +   * where index_n is an index into the sourceCode, and style_n is a style
    +   * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
    +   * all characters in sourceCode[index_n-1:index_n].
    +   *
    +   * The stylePatterns is a list whose elements have the form
    +   * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
    +   *
    +   * Style is a style constant like PR_PLAIN, or can be a string of the
    +   * form 'lang-FOO', where FOO is a language extension describing the
    +   * language of the portion of the token in $1 after pattern executes.
    +   * E.g., if style is 'lang-lisp', and group 1 contains the text
    +   * '(hello (world))', then that portion of the token will be passed to the
    +   * registered lisp handler for formatting.
    +   * The text before and after group 1 will be restyled using this decorator
    +   * so decorators should take care that this doesn't result in infinite
    +   * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
    +   * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
    +   * '<script>foo()<\/script>', which would cause the current decorator to
    +   * be called with '<script>' which would not match the same rule since
    +   * group 1 must not be empty, so it would be instead styled as PR_TAG by
    +   * the generic tag rule.  The handler registered for the 'js' extension would
    +   * then be called with 'foo()', and finally, the current decorator would
    +   * be called with '<\/script>' which would not match the original rule and
    +   * so the generic tag rule would identify it as a tag.
    +   *
    +   * Pattern must only match prefixes, and if it matches a prefix, then that
    +   * match is considered a token with the same style.
    +   *
    +   * Context is applied to the last non-whitespace, non-comment token
    +   * recognized.
    +   *
    +   * Shortcut is an optional string of characters, any of which, if the first
    +   * character, guarantee that this pattern and only this pattern matches.
    +   *
    +   * @param {Array} shortcutStylePatterns patterns that always start with
    +   *   a known character.  Must have a shortcut string.
    +   * @param {Array} fallthroughStylePatterns patterns that will be tried in
    +   *   order if the shortcut ones fail.  May have shortcuts.
    +   *
    +   * @return {function (Object)} a
    +   *   function that takes source code and returns a list of decorations.
    +   */
    +  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
    +    var shortcuts = {};
    +    var tokenizer;
    +    (function () {
    +      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
    +      var allRegexs = [];
    +      var regexKeys = {};
    +      for (var i = 0, n = allPatterns.length; i < n; ++i) {
    +        var patternParts = allPatterns[i];
    +        var shortcutChars = patternParts[3];
    +        if (shortcutChars) {
    +          for (var c = shortcutChars.length; --c >= 0;) {
    +            shortcuts[shortcutChars.charAt(c)] = patternParts;
    +          }
    +        }
    +        var regex = patternParts[1];
    +        var k = '' + regex;
    +        if (!regexKeys.hasOwnProperty(k)) {
    +          allRegexs.push(regex);
    +          regexKeys[k] = null;
    +        }
    +      }
    +      allRegexs.push(/[\0-\uffff]/);
    +      tokenizer = combinePrefixPatterns(allRegexs);
    +    })();
    +
    +    var nPatterns = fallthroughStylePatterns.length;
    +
    +    /**
    +     * Lexes job.sourceCode and produces an output array job.decorations of
    +     * style classes preceded by the position at which they start in
    +     * job.sourceCode in order.
    +     *
    +     * @param {Object} job an object like <pre>{
    +     *    sourceCode: {string} sourceText plain text,
    +     *    basePos: {int} position of job.sourceCode in the larger chunk of
    +     *        sourceCode.
    +     * }</pre>
    +     */
    +    var decorate = function (job) {
    +      var sourceCode = job.sourceCode, basePos = job.basePos;
    +      /** Even entries are positions in source in ascending order.  Odd enties
    +       * are style markers (e.g., PR_COMMENT) that run from that position until
    +       * the end.
    +       * @type {Array.<number|string>}
    +       */
    +      var decorations = [basePos, PR_PLAIN];
    +      var pos = 0;  // index into sourceCode
    +      var tokens = sourceCode.match(tokenizer) || [];
    +      var styleCache = {};
    +
    +      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
    +        var token = tokens[ti];
    +        var style = styleCache[token];
    +        var match = void 0;
    +
    +        var isEmbedded;
    +        if (typeof style === 'string') {
    +          isEmbedded = false;
    +        } else {
    +          var patternParts = shortcuts[token.charAt(0)];
    +          if (patternParts) {
    +            match = token.match(patternParts[1]);
    +            style = patternParts[0];
    +          } else {
    +            for (var i = 0; i < nPatterns; ++i) {
    +              patternParts = fallthroughStylePatterns[i];
    +              match = token.match(patternParts[1]);
    +              if (match) {
    +                style = patternParts[0];
    +                break;
    +              }
    +            }
    +
    +            if (!match) {  // make sure that we make progress
    +              style = PR_PLAIN;
    +            }
    +          }
    +
    +          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
    +          if (isEmbedded && !(match && typeof match[1] === 'string')) {
    +            isEmbedded = false;
    +            style = PR_SOURCE;
    +          }
    +
    +          if (!isEmbedded) { styleCache[token] = style; }
    +        }
    +
    +        var tokenStart = pos;
    +        pos += token.length;
    +
    +        if (!isEmbedded) {
    +          decorations.push(basePos + tokenStart, style);
    +        } else {  // Treat group 1 as an embedded block of source code.
    +          var embeddedSource = match[1];
    +          var embeddedSourceStart = token.indexOf(embeddedSource);
    +          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
    +          if (match[2]) {
    +            // If embeddedSource can be blank, then it would match at the
    +            // beginning which would cause us to infinitely recurse on the
    +            // entire token, so we catch the right context in match[2].
    +            embeddedSourceEnd = token.length - match[2].length;
    +            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
    +          }
    +          var lang = style.substring(5);
    +          // Decorate the left of the embedded source
    +          appendDecorations(
    +            basePos + tokenStart,
    +            token.substring(0, embeddedSourceStart),
    +            decorate, decorations);
    +          // Decorate the embedded source
    +          appendDecorations(
    +            basePos + tokenStart + embeddedSourceStart,
    +            embeddedSource,
    +            langHandlerForExtension(lang, embeddedSource),
    +            decorations);
    +          // Decorate the right of the embedded section
    +          appendDecorations(
    +            basePos + tokenStart + embeddedSourceEnd,
    +            token.substring(embeddedSourceEnd),
    +            decorate, decorations);
    +        }
    +      }
    +      job.decorations = decorations;
    +    };
    +    return decorate;
    +  }
    +
    +  /** returns a function that produces a list of decorations from source text.
    +   *
    +   * This code treats ", ', and ` as string delimiters, and \ as a string
    +   * escape.  It does not recognize perl's qq() style strings.
    +   * It has no special handling for double delimiter escapes as in basic, or
    +   * the tripled delimiters used in python, but should work on those regardless
    +   * although in those cases a single string literal may be broken up into
    +   * multiple adjacent string literals.
    +   *
    +   * It recognizes C, C++, and shell style comments.
    +   *
    +   * @param {Object} options a set of optional parameters.
    +   * @return {function (Object)} a function that examines the source code
    +   *     in the input job and builds the decoration list.
    +   */
    +  function sourceDecorator(options) {
    +    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
    +    if (options['tripleQuotedStrings']) {
    +      // '''multi-line-string''', 'single-line-string', and double-quoted
    +      shortcutStylePatterns.push(
    +        [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
    +          null, '\'"']);
    +    } else if (options['multiLineStrings']) {
    +      // 'multi-line-string', "multi-line-string"
    +      shortcutStylePatterns.push(
    +        [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
    +          null, '\'"`']);
    +    } else {
    +      // 'single-line-string', "single-line-string"
    +      shortcutStylePatterns.push(
    +        [PR_STRING,
    +          /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
    +          null, '"\'']);
    +    }
    +    if (options['verbatimStrings']) {
    +      // verbatim-string-literal production from the C# grammar.  See issue 93.
    +      fallthroughStylePatterns.push(
    +        [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
    +    }
    +    var hc = options['hashComments'];
    +    if (hc) {
    +      if (options['cStyleComments']) {
    +        if (hc > 1) {  // multiline hash comments
    +          shortcutStylePatterns.push(
    +            [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
    +        } else {
    +          // Stop C preprocessor declarations at an unclosed open comment
    +          shortcutStylePatterns.push(
    +            [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,
    +              null, '#']);
    +        }
    +        // #include <stdio.h>
    +        fallthroughStylePatterns.push(
    +          [PR_STRING,
    +            /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
    +            null]);
    +      } else {
    +        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
    +      }
    +    }
    +    if (options['cStyleComments']) {
    +      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
    +      fallthroughStylePatterns.push(
    +        [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
    +    }
    +    if (options['regexLiterals']) {
    +      /**
    +       * @const
    +       */
    +      var REGEX_LITERAL = (
    +        // A regular expression literal starts with a slash that is
    +        // not followed by * or / so that it is not confused with
    +        // comments.
    +        '/(?=[^/*])'
    +          // and then contains any number of raw characters,
    +          + '(?:[^/\\x5B\\x5C]'
    +          // escape sequences (\x5C),
    +          +    '|\\x5C[\\s\\S]'
    +          // or non-nesting character sets (\x5B\x5D);
    +          +    '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
    +          // finally closed by a /.
    +          + '/');
    +      fallthroughStylePatterns.push(
    +        ['lang-regex',
    +          new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
    +        ]);
    +    }
    +
    +    var types = options['types'];
    +    if (types) {
    +      fallthroughStylePatterns.push([PR_TYPE, types]);
    +    }
    +
    +    var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
    +    if (keywords.length) {
    +      fallthroughStylePatterns.push(
    +        [PR_KEYWORD,
    +          new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
    +          null]);
    +    }
    +
    +    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
    +    fallthroughStylePatterns.push(
    +      // TODO(mikesamuel): recognize non-latin letters and numerals in idents
    +      [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
    +      [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
    +      [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
    +      [PR_LITERAL,
    +        new RegExp(
    +          '^(?:'
    +            // A hex number
    +            + '0x[a-f0-9]+'
    +            // or an octal or decimal number,
    +            + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
    +            // possibly in scientific notation
    +            + '(?:e[+\\-]?\\d+)?'
    +            + ')'
    +            // with an optional modifier like UL for unsigned long
    +            + '[a-z]*', 'i'),
    +        null, '0123456789'],
    +      // Don't treat escaped quotes in bash as starting strings.  See issue 144.
    +      [PR_PLAIN,       /^\\[\s\S]?/, null],
    +      [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#\\]*/, null]);
    +
    +    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
    +  }
    +
    +  var decorateSource = sourceDecorator({
    +    'keywords': ALL_KEYWORDS,
    +    'hashComments': true,
    +    'cStyleComments': true,
    +    'multiLineStrings': true,
    +    'regexLiterals': true
    +  });
    +
    +  /**
    +   * Given a DOM subtree, wraps it in a list, and puts each line into its own
    +   * list item.
    +   *
    +   * @param {Node} node modified in place.  Its content is pulled into an
    +   *     HTMLOListElement, and each line is moved into a separate list item.
    +   *     This requires cloning elements, so the input might not have unique
    +   *     IDs after numbering.
    +   * @param {boolean} isPreformatted true iff white-space in text nodes should
    +   *     be treated as significant.
    +   */
    +  function numberLines(node, opt_startLineNum, isPreformatted) {
    +    var nocode = /(?:^|\s)nocode(?:\s|$)/;
    +    var lineBreak = /\r\n?|\n/;
    +
    +    var document = node.ownerDocument;
    +
    +    var li = document.createElement('li');
    +    while (node.firstChild) {
    +      li.appendChild(node.firstChild);
    +    }
    +    // An array of lines.  We split below, so this is initialized to one
    +    // un-split line.
    +    var listItems = [li];
    +
    +    function walk(node) {
    +      switch (node.nodeType) {
    +        case 1:  // Element
    +          if (nocode.test(node.className)) { break; }
    +          if ('br' === node.nodeName) {
    +            breakAfter(node);
    +            // Discard the <BR> since it is now flush against a </LI>.
    +            if (node.parentNode) {
    +              node.parentNode.removeChild(node);
    +            }
    +          } else {
    +            for (var child = node.firstChild; child; child = child.nextSibling) {
    +              walk(child);
    +            }
    +          }
    +          break;
    +        case 3: case 4:  // Text
    +        if (isPreformatted) {
    +          var text = node.nodeValue;
    +          var match = text.match(lineBreak);
    +          if (match) {
    +            var firstLine = text.substring(0, match.index);
    +            node.nodeValue = firstLine;
    +            var tail = text.substring(match.index + match[0].length);
    +            if (tail) {
    +              var parent = node.parentNode;
    +              parent.insertBefore(
    +                document.createTextNode(tail), node.nextSibling);
    +            }
    +            breakAfter(node);
    +            if (!firstLine) {
    +              // Don't leave blank text nodes in the DOM.
    +              node.parentNode.removeChild(node);
    +            }
    +          }
    +        }
    +        break;
    +      }
    +    }
    +
    +    // Split a line after the given node.
    +    function breakAfter(lineEndNode) {
    +      // If there's nothing to the right, then we can skip ending the line
    +      // here, and move root-wards since splitting just before an end-tag
    +      // would require us to create a bunch of empty copies.
    +      while (!lineEndNode.nextSibling) {
    +        lineEndNode = lineEndNode.parentNode;
    +        if (!lineEndNode) { return; }
    +      }
    +
    +      function breakLeftOf(limit, copy) {
    +        // Clone shallowly if this node needs to be on both sides of the break.
    +        var rightSide = copy ? limit.cloneNode(false) : limit;
    +        var parent = limit.parentNode;
    +        if (parent) {
    +          // We clone the parent chain.
    +          // This helps us resurrect important styling elements that cross lines.
    +          // E.g. in <i>Foo<br>Bar</i>
    +          // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
    +          var parentClone = breakLeftOf(parent, 1);
    +          // Move the clone and everything to the right of the original
    +          // onto the cloned parent.
    +          var next = limit.nextSibling;
    +          parentClone.appendChild(rightSide);
    +          for (var sibling = next; sibling; sibling = next) {
    +            next = sibling.nextSibling;
    +            parentClone.appendChild(sibling);
    +          }
    +        }
    +        return rightSide;
    +      }
    +
    +      var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
    +
    +      // Walk the parent chain until we reach an unattached LI.
    +      for (var parent;
    +        // Check nodeType since IE invents document fragments.
    +           (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
    +        copiedListItem = parent;
    +      }
    +      // Put it on the list of lines for later processing.
    +      listItems.push(copiedListItem);
    +    }
    +
    +    // Split lines while there are lines left to split.
    +    for (var i = 0;  // Number of lines that have been split so far.
    +         i < listItems.length;  // length updated by breakAfter calls.
    +         ++i) {
    +      walk(listItems[i]);
    +    }
    +
    +    // Make sure numeric indices show correctly.
    +    if (opt_startLineNum === (opt_startLineNum|0)) {
    +      listItems[0].setAttribute('value', opt_startLineNum);
    +    }
    +
    +    var ol = document.createElement('ol');
    +    ol.className = 'linenums';
    +    var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
    +    for (var i = 0, n = listItems.length; i < n; ++i) {
    +      li = listItems[i];
    +      // Stick a class on the LIs so that stylesheets can
    +      // color odd/even rows, or any other row pattern that
    +      // is co-prime with 10.
    +      li.className = 'L' + ((i + offset) % 10);
    +      if (!li.firstChild) {
    +        li.appendChild(document.createTextNode('\xA0'));
    +      }
    +      ol.appendChild(li);
    +    }
    +
    +    node.appendChild(ol);
    +  }
    +
    +  /**
    +   * Breaks {@code job.sourceCode} around style boundaries in
    +   * {@code job.decorations} and modifies {@code job.sourceNode} in place.
    +   * @param {Object} job like <pre>{
    +   *    sourceCode: {string} source as plain text,
    +   *    spans: {Array.<number|Node>} alternating span start indices into source
    +   *       and the text node or element (e.g. {@code <BR>}) corresponding to that
    +   *       span.
    +   *    decorations: {Array.<number|string} an array of style classes preceded
    +   *       by the position at which they start in job.sourceCode in order
    +   * }</pre>
    +   * @private
    +   */
    +  function recombineTagsAndDecorations(job) {
    +    var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
    +    isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
    +    var newlineRe = /\n/g;
    +
    +    var source = job.sourceCode;
    +    var sourceLength = source.length;
    +    // Index into source after the last code-unit recombined.
    +    var sourceIndex = 0;
    +
    +    var spans = job.spans;
    +    var nSpans = spans.length;
    +    // Index into spans after the last span which ends at or before sourceIndex.
    +    var spanIndex = 0;
    +
    +    var decorations = job.decorations;
    +    var nDecorations = decorations.length;
    +    // Index into decorations after the last decoration which ends at or before
    +    // sourceIndex.
    +    var decorationIndex = 0;
    +
    +    // Remove all zero-length decorations.
    +    decorations[nDecorations] = sourceLength;
    +    var decPos, i;
    +    for (i = decPos = 0; i < nDecorations;) {
    +      if (decorations[i] !== decorations[i + 2]) {
    +        decorations[decPos++] = decorations[i++];
    +        decorations[decPos++] = decorations[i++];
    +      } else {
    +        i += 2;
    +      }
    +    }
    +    nDecorations = decPos;
    +
    +    // Simplify decorations.
    +    for (i = decPos = 0; i < nDecorations;) {
    +      var startPos = decorations[i];
    +      // Conflate all adjacent decorations that use the same style.
    +      var startDec = decorations[i + 1];
    +      var end = i + 2;
    +      while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
    +        end += 2;
    +      }
    +      decorations[decPos++] = startPos;
    +      decorations[decPos++] = startDec;
    +      i = end;
    +    }
    +
    +    nDecorations = decorations.length = decPos;
    +
    +    var sourceNode = job.sourceNode;
    +    var oldDisplay;
    +    if (sourceNode) {
    +      oldDisplay = sourceNode.style.display;
    +      sourceNode.style.display = 'none';
    +    }
    +    try {
    +      var decoration = null;
    +      while (spanIndex < nSpans) {
    +        var spanStart = spans[spanIndex];
    +        var spanEnd = spans[spanIndex + 2] || sourceLength;
    +
    +        var decEnd = decorations[decorationIndex + 2] || sourceLength;
    +
    +        var end = Math.min(spanEnd, decEnd);
    +
    +        var textNode = spans[spanIndex + 1];
    +        var styledText;
    +        if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
    +          // Don't introduce spans around empty text nodes.
    +          && (styledText = source.substring(sourceIndex, end))) {
    +          // This may seem bizarre, and it is.  Emitting LF on IE causes the
    +          // code to display with spaces instead of line breaks.
    +          // Emitting Windows standard issue linebreaks (CRLF) causes a blank
    +          // space to appear at the beginning of every line but the first.
    +          // Emitting an old Mac OS 9 line separator makes everything spiffy.
    +          if (isIE8OrEarlier) {
    +            styledText = styledText.replace(newlineRe, '\r');
    +          }
    +          textNode.nodeValue = styledText;
    +          var document = textNode.ownerDocument;
    +          var span = document.createElement('span');
    +          span.className = decorations[decorationIndex + 1];
    +          var parentNode = textNode.parentNode;
    +          parentNode.replaceChild(span, textNode);
    +          span.appendChild(textNode);
    +          if (sourceIndex < spanEnd) {  // Split off a text node.
    +            spans[spanIndex + 1] = textNode
    +              // TODO: Possibly optimize by using '' if there's no flicker.
    +              = document.createTextNode(source.substring(end, spanEnd));
    +            parentNode.insertBefore(textNode, span.nextSibling);
    +          }
    +        }
    +
    +        sourceIndex = end;
    +
    +        if (sourceIndex >= spanEnd) {
    +          spanIndex += 2;
    +        }
    +        if (sourceIndex >= decEnd) {
    +          decorationIndex += 2;
    +        }
    +      }
    +    } finally {
    +      if (sourceNode) {
    +        sourceNode.style.display = oldDisplay;
    +      }
    +    }
    +  }
    +
    +
    +  /** Maps language-specific file extensions to handlers. */
    +  var langHandlerRegistry = {};
    +  /** Register a language handler for the given file extensions.
    +   * @param {function (Object)} handler a function from source code to a list
    +   *      of decorations.  Takes a single argument job which describes the
    +   *      state of the computation.   The single parameter has the form
    +   *      {@code {
    +    *        sourceCode: {string} as plain text.
    +    *        decorations: {Array.<number|string>} an array of style classes
    +    *                     preceded by the position at which they start in
    +    *                     job.sourceCode in order.
    +    *                     The language handler should assigned this field.
    +    *        basePos: {int} the position of source in the larger source chunk.
    +    *                 All positions in the output decorations array are relative
    +    *                 to the larger source chunk.
    +    *      } }
    +   * @param {Array.<string>} fileExtensions
    +   */
    +  function registerLangHandler(handler, fileExtensions) {
    +    for (var i = fileExtensions.length; --i >= 0;) {
    +      var ext = fileExtensions[i];
    +      if (!langHandlerRegistry.hasOwnProperty(ext)) {
    +        langHandlerRegistry[ext] = handler;
    +      } else if (win['console']) {
    +        console['warn']('cannot override language handler %s', ext);
    +      }
    +    }
    +  }
    +  function langHandlerForExtension(extension, source) {
    +    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
    +      // Treat it as markup if the first non whitespace character is a < and
    +      // the last non-whitespace character is a >.
    +      extension = /^\s*</.test(source)
    +        ? 'default-markup'
    +        : 'default-code';
    +    }
    +    return langHandlerRegistry[extension];
    +  }
    +  registerLangHandler(decorateSource, ['default-code']);
    +  registerLangHandler(
    +    createSimpleLexer(
    +      [],
    +      [
    +        [PR_PLAIN,       /^[^<?]+/],
    +        [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
    +        [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
    +        // Unescaped content in an unknown language
    +        ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
    +        ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
    +        [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
    +        ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
    +        // Unescaped content in javascript.  (Or possibly vbscript).
    +        ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
    +        // Contains unescaped stylesheet content
    +        ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
    +        ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
    +      ]),
    +    ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
    +  registerLangHandler(
    +    createSimpleLexer(
    +      [
    +        [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
    +        [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
    +      ],
    +      [
    +        [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
    +        [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
    +        ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
    +        [PR_PUNCTUATION,  /^[=<>\/]+/],
    +        ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
    +        ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
    +        ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
    +        ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
    +        ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
    +        ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
    +      ]),
    +    ['in.tag']);
    +  registerLangHandler(
    +    createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
    +  registerLangHandler(sourceDecorator({
    +    'keywords': CPP_KEYWORDS,
    +    'hashComments': true,
    +    'cStyleComments': true,
    +    'types': C_TYPES
    +  }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
    +  registerLangHandler(sourceDecorator({
    +    'keywords': 'null,true,false'
    +  }), ['json']);
    +  registerLangHandler(sourceDecorator({
    +    'keywords': CSHARP_KEYWORDS,
    +    'hashComments': true,
    +    'cStyleComments': true,
    +    'verbatimStrings': true,
    +    'types': C_TYPES
    +  }), ['cs']);
    +  registerLangHandler(sourceDecorator({
    +    'keywords': JAVA_KEYWORDS,
    +    'cStyleComments': true
    +  }), ['java']);
    +  registerLangHandler(sourceDecorator({
    +    'keywords': SH_KEYWORDS,
    +    'hashComments': true,
    +    'multiLineStrings': true
    +  }), ['bsh', 'csh', 'sh']);
    +  registerLangHandler(sourceDecorator({
    +    'keywords': PYTHON_KEYWORDS,
    +    'hashComments': true,
    +    'multiLineStrings': true,
    +    'tripleQuotedStrings': true
    +  }), ['cv', 'py']);
    +  registerLangHandler(sourceDecorator({
    +    'keywords': PERL_KEYWORDS,
    +    'hashComments': true,
    +    'multiLineStrings': true,
    +    'regexLiterals': true
    +  }), ['perl', 'pl', 'pm']);
    +  registerLangHandler(sourceDecorator({
    +    'keywords': RUBY_KEYWORDS,
    +    'hashComments': true,
    +    'multiLineStrings': true,
    +    'regexLiterals': true
    +  }), ['rb']);
    +  registerLangHandler(sourceDecorator({
    +    'keywords': JSCRIPT_KEYWORDS,
    +    'cStyleComments': true,
    +    'regexLiterals': true
    +  }), ['js']);
    +  registerLangHandler(sourceDecorator({
    +    'keywords': COFFEE_KEYWORDS,
    +    'hashComments': 3,  // ### style block comments
    +    'cStyleComments': true,
    +    'multilineStrings': true,
    +    'tripleQuotedStrings': true,
    +    'regexLiterals': true
    +  }), ['coffee']);
    +  registerLangHandler(
    +    createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
    +
    +  function applyDecorator(job) {
    +    var opt_langExtension = job.langExtension;
    +
    +    try {
    +      // Extract tags, and convert the source code to plain text.
    +      var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
    +      /** Plain text. @type {string} */
    +      var source = sourceAndSpans.sourceCode;
    +      job.sourceCode = source;
    +      job.spans = sourceAndSpans.spans;
    +      job.basePos = 0;
    +
    +      // Apply the appropriate language handler
    +      langHandlerForExtension(opt_langExtension, source)(job);
    +
    +      // Integrate the decorations and tags back into the source code,
    +      // modifying the sourceNode in place.
    +      recombineTagsAndDecorations(job);
    +    } catch (e) {
    +      if (win['console']) {
    +        console['log'](e && e['stack'] ? e['stack'] : e);
    +      }
    +    }
    +  }
    +
    +  /**
    +   * @param sourceCodeHtml {string} The HTML to pretty print.
    +   * @param opt_langExtension {string} The language name to use.
    +   *     Typically, a filename extension like 'cpp' or 'java'.
    +   * @param opt_numberLines {number|boolean} True to number lines,
    +   *     or the 1-indexed number of the first line in sourceCodeHtml.
    +   */
    +  function prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
    +    // PATCHED: http://code.google.com/p/google-code-prettify/issues/detail?id=213
    +    var container = document.createElement('div');
    +    // This could cause images to load and onload listeners to fire.
    +    // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
    +    // We assume that the inner HTML is from a trusted source.
    +    container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';
    +    container = container.firstChild;
    +    if (opt_numberLines) {
    +      numberLines(container, opt_numberLines, true);
    +    }
    +
    +    var job = {
    +      langExtension: opt_langExtension,
    +      numberLines: opt_numberLines,
    +      sourceNode: container,
    +      pre: 1
    +    };
    +    applyDecorator(job);
    +    return container.innerHTML;
    +  }
    +
    +  function prettyPrint(opt_whenDone) {
    +    function byTagName(tn) { return document.getElementsByTagName(tn); }
    +    // fetch a list of nodes to rewrite
    +    var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
    +    var elements = [];
    +    for (var i = 0; i < codeSegments.length; ++i) {
    +      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
    +        elements.push(codeSegments[i][j]);
    +      }
    +    }
    +    codeSegments = null;
    +
    +    var clock = Date;
    +    if (!clock['now']) {
    +      clock = { 'now': function () { return +(new Date); } };
    +    }
    +
    +    // The loop is broken into a series of continuations to make sure that we
    +    // don't make the browser unresponsive when rewriting a large page.
    +    var k = 0;
    +    var prettyPrintingJob;
    +
    +    var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
    +    var prettyPrintRe = /\bprettyprint\b/;
    +    var prettyPrintedRe = /\bprettyprinted\b/;
    +    var preformattedTagNameRe = /pre|xmp/i;
    +    var codeRe = /^code$/i;
    +    var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
    +
    +    function doWork() {
    +      var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
    +        clock['now']() + 250 /* ms */ :
    +        Infinity);
    +      for (; k < elements.length && clock['now']() < endTime; k++) {
    +        var cs = elements[k];
    +        var className = cs.className;
    +        if (prettyPrintRe.test(className)
    +          // Don't redo this if we've already done it.
    +          // This allows recalling pretty print to just prettyprint elements
    +          // that have been added to the page since last call.
    +          && !prettyPrintedRe.test(className)) {
    +
    +          // make sure this is not nested in an already prettified element
    +          var nested = false;
    +          for (var p = cs.parentNode; p; p = p.parentNode) {
    +            var tn = p.tagName;
    +            if (preCodeXmpRe.test(tn)
    +              && p.className && prettyPrintRe.test(p.className)) {
    +              nested = true;
    +              break;
    +            }
    +          }
    +          if (!nested) {
    +            // Mark done.  If we fail to prettyprint for whatever reason,
    +            // we shouldn't try again.
    +            cs.className += ' prettyprinted';
    +
    +            // If the classes includes a language extensions, use it.
    +            // Language extensions can be specified like
    +            //     <pre class="prettyprint lang-cpp">
    +            // the language extension "cpp" is used to find a language handler
    +            // as passed to PR.registerLangHandler.
    +            // HTML5 recommends that a language be specified using "language-"
    +            // as the prefix instead.  Google Code Prettify supports both.
    +            // http://dev.w3.org/html5/spec-author-view/the-code-element.html
    +            var langExtension = className.match(langExtensionRe);
    +            // Support <pre class="prettyprint"><code class="language-c">
    +            var wrapper;
    +            if (!langExtension && (wrapper = childContentWrapper(cs))
    +              && codeRe.test(wrapper.tagName)) {
    +              langExtension = wrapper.className.match(langExtensionRe);
    +            }
    +
    +            if (langExtension) { langExtension = langExtension[1]; }
    +
    +            var preformatted;
    +            if (preformattedTagNameRe.test(cs.tagName)) {
    +              preformatted = 1;
    +            } else {
    +              var currentStyle = cs['currentStyle'];
    +              var whitespace = (
    +                currentStyle
    +                  ? currentStyle['whiteSpace']
    +                  : (document.defaultView
    +                  && document.defaultView.getComputedStyle)
    +                  ? document.defaultView.getComputedStyle(cs, null)
    +                  .getPropertyValue('white-space')
    +                  : 0);
    +              preformatted = whitespace
    +                && 'pre' === whitespace.substring(0, 3);
    +            }
    +
    +            // Look for a class like linenums or linenums:<n> where <n> is the
    +            // 1-indexed number of the first line.
    +            var lineNums = cs.className.match(/\blinenums\b(?::(\d+))?/);
    +            lineNums = lineNums
    +              ? lineNums[1] && lineNums[1].length ? +lineNums[1] : true
    +              : false;
    +            if (lineNums) { numberLines(cs, lineNums, preformatted); }
    +
    +            // do the pretty printing
    +            prettyPrintingJob = {
    +              langExtension: langExtension,
    +              sourceNode: cs,
    +              numberLines: lineNums,
    +              pre: preformatted
    +            };
    +            applyDecorator(prettyPrintingJob);
    +          }
    +        }
    +      }
    +      if (k < elements.length) {
    +        // finish up in a continuation
    +        setTimeout(doWork, 250);
    +      } else if (opt_whenDone) {
    +        opt_whenDone();
    +      }
    +    }
    +
    +    doWork();
    +  }
    +
    +  /**
    +   * Contains functions for creating and registering new language handlers.
    +   * @type {Object}
    +   */
    +  var PR = win['PR'] = {
    +    'createSimpleLexer': createSimpleLexer,
    +    'registerLangHandler': registerLangHandler,
    +    'sourceDecorator': sourceDecorator,
    +    'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
    +    'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
    +    'PR_COMMENT': PR_COMMENT,
    +    'PR_DECLARATION': PR_DECLARATION,
    +    'PR_KEYWORD': PR_KEYWORD,
    +    'PR_LITERAL': PR_LITERAL,
    +    'PR_NOCODE': PR_NOCODE,
    +    'PR_PLAIN': PR_PLAIN,
    +    'PR_PUNCTUATION': PR_PUNCTUATION,
    +    'PR_SOURCE': PR_SOURCE,
    +    'PR_STRING': PR_STRING,
    +    'PR_TAG': PR_TAG,
    +    'PR_TYPE': PR_TYPE,
    +    'prettyPrintOne': win['prettyPrintOne'] = prettyPrintOne,
    +    'prettyPrint': win['prettyPrint'] = prettyPrint
    +  };
    +
    +  // Make PR available via the Asynchronous Module Definition (AMD) API.
    +  // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
    +  // The Asynchronous Module Definition (AMD) API specifies a
    +  // mechanism for defining modules such that the module and its
    +  // dependencies can be asynchronously loaded.
    +  // ...
    +  // To allow a clear indicator that a global define function (as
    +  // needed for script src browser loading) conforms to the AMD API,
    +  // any global define function SHOULD have a property called "amd"
    +  // whose value is an object. This helps avoid conflict with any
    +  // other existing JavaScript code that could have defined a define()
    +  // function that does not conform to the AMD API.
    +  if (typeof define === "function" && define['amd']) {
    +    define("google-code-prettify", [], function () {
    +      return PR;
    +    });
    +  }
    +})();
    \ No newline at end of file
    diff --git a/assets/vendor/ui-bootstrap-tpls.min.js b/assets/vendor/ui-bootstrap-tpls.min.js
    new file mode 100644
    index 0000000..da950fb
    --- /dev/null
    +++ b/assets/vendor/ui-bootstrap-tpls.min.js
    @@ -0,0 +1,2 @@
    +angular.module("ui.bootstrap",["ui.bootstrap.tpls","ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdownToggle","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]),angular.module("ui.bootstrap.tpls",["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/carousel/carousel.html","template/carousel/slide.html","template/datepicker/datepicker.html","template/datepicker/popup.html","template/modal/backdrop.html","template/modal/window.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/popover/popover.html","template/progressbar/bar.html","template/progressbar/progress.html","template/progressbar/progressbar.html","template/rating/rating.html","template/tabs/tab.html","template/tabs/tabset.html","template/timepicker/timepicker.html","template/typeahead/typeahead-match.html","template/typeahead/typeahead-popup.html"]),angular.module("ui.bootstrap.transition",[]).factory("$transition",["$q","$timeout","$rootScope",function(a,b,c){function d(a){for(var b in a)if(void 0!==f.style[b])return a[b]}var e=function(d,f,g){g=g||{};var h=a.defer(),i=e[g.animation?"animationEndEventName":"transitionEndEventName"],j=function(){c.$apply(function(){d.unbind(i,j),h.resolve(d)})};return i&&d.bind(i,j),b(function(){angular.isString(f)?d.addClass(f):angular.isFunction(f)?f(d):angular.isObject(f)&&d.css(f),i||h.resolve(d)}),h.promise.cancel=function(){i&&d.unbind(i,j),h.reject("Transition cancelled")},h.promise},f=document.createElement("trans"),g={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",transition:"transitionend"},h={WebkitTransition:"webkitAnimationEnd",MozTransition:"animationend",OTransition:"oAnimationEnd",transition:"animationend"};return e.transitionEndEventName=d(g),e.animationEndEventName=d(h),e}]),angular.module("ui.bootstrap.collapse",["ui.bootstrap.transition"]).directive("collapse",["$transition",function(a){return{link:function(b,c,d){function e(b){function d(){j===e&&(j=void 0)}var e=a(c,b);return j&&j.cancel(),j=e,e.then(d,d),e}function f(){k?(k=!1,g()):(c.removeClass("collapse").addClass("collapsing"),e({height:c[0].scrollHeight+"px"}).then(g))}function g(){c.removeClass("collapsing"),c.addClass("collapse in"),c.css({height:"auto"})}function h(){if(k)k=!1,i(),c.css({height:0});else{c.css({height:c[0].scrollHeight+"px"});{c[0].offsetWidth}c.removeClass("collapse in").addClass("collapsing"),e({height:0}).then(i)}}function i(){c.removeClass("collapsing"),c.addClass("collapse")}var j,k=!0;b.$watch(d.collapse,function(a){a?h():f()})}}}]),angular.module("ui.bootstrap.accordion",["ui.bootstrap.collapse"]).constant("accordionConfig",{closeOthers:!0}).controller("AccordionController",["$scope","$attrs","accordionConfig",function(a,b,c){this.groups=[],this.closeOthers=function(d){var e=angular.isDefined(b.closeOthers)?a.$eval(b.closeOthers):c.closeOthers;e&&angular.forEach(this.groups,function(a){a!==d&&(a.isOpen=!1)})},this.addGroup=function(a){var b=this;this.groups.push(a),a.$on("$destroy",function(){b.removeGroup(a)})},this.removeGroup=function(a){var b=this.groups.indexOf(a);-1!==b&&this.groups.splice(this.groups.indexOf(a),1)}}]).directive("accordion",function(){return{restrict:"EA",controller:"AccordionController",transclude:!0,replace:!1,templateUrl:"template/accordion/accordion.html"}}).directive("accordionGroup",["$parse",function(a){return{require:"^accordion",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/accordion/accordion-group.html",scope:{heading:"@"},controller:function(){this.setHeading=function(a){this.heading=a}},link:function(b,c,d,e){var f,g;e.addGroup(b),b.isOpen=!1,d.isOpen&&(f=a(d.isOpen),g=f.assign,b.$parent.$watch(f,function(a){b.isOpen=!!a})),b.$watch("isOpen",function(a){a&&e.closeOthers(b),g&&g(b.$parent,a)})}}}]).directive("accordionHeading",function(){return{restrict:"EA",transclude:!0,template:"",replace:!0,require:"^accordionGroup",compile:function(a,b,c){return function(a,b,d,e){e.setHeading(c(a,function(){}))}}}}).directive("accordionTransclude",function(){return{require:"^accordionGroup",link:function(a,b,c,d){a.$watch(function(){return d[c.accordionTransclude]},function(a){a&&(b.html(""),b.append(a))})}}}),angular.module("ui.bootstrap.alert",[]).controller("AlertController",["$scope","$attrs",function(a,b){a.closeable="close"in b}]).directive("alert",function(){return{restrict:"EA",controller:"AlertController",templateUrl:"template/alert/alert.html",transclude:!0,replace:!0,scope:{type:"=",close:"&"}}}),angular.module("ui.bootstrap.bindHtml",[]).directive("bindHtmlUnsafe",function(){return function(a,b,c){b.addClass("ng-binding").data("$binding",c.bindHtmlUnsafe),a.$watch(c.bindHtmlUnsafe,function(a){b.html(a||"")})}}),angular.module("ui.bootstrap.buttons",[]).constant("buttonConfig",{activeClass:"active",toggleEvent:"click"}).controller("ButtonsController",["buttonConfig",function(a){this.activeClass=a.activeClass||"active",this.toggleEvent=a.toggleEvent||"click"}]).directive("btnRadio",function(){return{require:["btnRadio","ngModel"],controller:"ButtonsController",link:function(a,b,c,d){var e=d[0],f=d[1];f.$render=function(){b.toggleClass(e.activeClass,angular.equals(f.$modelValue,a.$eval(c.btnRadio)))},b.bind(e.toggleEvent,function(){b.hasClass(e.activeClass)||a.$apply(function(){f.$setViewValue(a.$eval(c.btnRadio)),f.$render()})})}}}).directive("btnCheckbox",function(){return{require:["btnCheckbox","ngModel"],controller:"ButtonsController",link:function(a,b,c,d){function e(){return g(c.btnCheckboxTrue,!0)}function f(){return g(c.btnCheckboxFalse,!1)}function g(b,c){var d=a.$eval(b);return angular.isDefined(d)?d:c}var h=d[0],i=d[1];i.$render=function(){b.toggleClass(h.activeClass,angular.equals(i.$modelValue,e()))},b.bind(h.toggleEvent,function(){a.$apply(function(){i.$setViewValue(b.hasClass(h.activeClass)?f():e()),i.$render()})})}}}),angular.module("ui.bootstrap.carousel",["ui.bootstrap.transition"]).controller("CarouselController",["$scope","$timeout","$transition","$q",function(a,b,c){function d(){e();var c=+a.interval;!isNaN(c)&&c>=0&&(g=b(f,c))}function e(){g&&(b.cancel(g),g=null)}function f(){h?(a.next(),d()):a.pause()}var g,h,i=this,j=i.slides=[],k=-1;i.currentSlide=null;var l=!1;i.select=function(e,f){function g(){if(!l){if(i.currentSlide&&angular.isString(f)&&!a.noTransition&&e.$element){e.$element.addClass(f);{e.$element[0].offsetWidth}angular.forEach(j,function(a){angular.extend(a,{direction:"",entering:!1,leaving:!1,active:!1})}),angular.extend(e,{direction:f,active:!0,entering:!0}),angular.extend(i.currentSlide||{},{direction:f,leaving:!0}),a.$currentTransition=c(e.$element,{}),function(b,c){a.$currentTransition.then(function(){h(b,c)},function(){h(b,c)})}(e,i.currentSlide)}else h(e,i.currentSlide);i.currentSlide=e,k=m,d()}}function h(b,c){angular.extend(b,{direction:"",active:!0,leaving:!1,entering:!1}),angular.extend(c||{},{direction:"",active:!1,leaving:!1,entering:!1}),a.$currentTransition=null}var m=j.indexOf(e);void 0===f&&(f=m>k?"next":"prev"),e&&e!==i.currentSlide&&(a.$currentTransition?(a.$currentTransition.cancel(),b(g)):g())},a.$on("$destroy",function(){l=!0}),i.indexOfSlide=function(a){return j.indexOf(a)},a.next=function(){var b=(k+1)%j.length;return a.$currentTransition?void 0:i.select(j[b],"next")},a.prev=function(){var b=0>k-1?j.length-1:k-1;return a.$currentTransition?void 0:i.select(j[b],"prev")},a.select=function(a){i.select(a)},a.isActive=function(a){return i.currentSlide===a},a.slides=function(){return j},a.$watch("interval",d),a.$on("$destroy",e),a.play=function(){h||(h=!0,d())},a.pause=function(){a.noPause||(h=!1,e())},i.addSlide=function(b,c){b.$element=c,j.push(b),1===j.length||b.active?(i.select(j[j.length-1]),1==j.length&&a.play()):b.active=!1},i.removeSlide=function(a){var b=j.indexOf(a);j.splice(b,1),j.length>0&&a.active?b>=j.length?i.select(j[b-1]):i.select(j[b]):k>b&&k--}}]).directive("carousel",[function(){return{restrict:"EA",transclude:!0,replace:!0,controller:"CarouselController",require:"carousel",templateUrl:"template/carousel/carousel.html",scope:{interval:"=",noTransition:"=",noPause:"="}}}]).directive("slide",["$parse",function(a){return{require:"^carousel",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/carousel/slide.html",scope:{},link:function(b,c,d,e){if(d.active){var f=a(d.active),g=f.assign,h=b.active=f(b.$parent);b.$watch(function(){var a=f(b.$parent);return a!==b.active&&(a!==h?h=b.active=a:g(b.$parent,a=h=b.active)),a})}e.addSlide(b,c),b.$on("$destroy",function(){e.removeSlide(b)}),b.$watch("active",function(a){a&&e.select(b)})}}}]),angular.module("ui.bootstrap.position",[]).factory("$position",["$document","$window",function(a,b){function c(a,c){return a.currentStyle?a.currentStyle[c]:b.getComputedStyle?b.getComputedStyle(a)[c]:a.style[c]}function d(a){return"static"===(c(a,"position")||"static")}var e=function(b){for(var c=a[0],e=b.offsetParent||c;e&&e!==c&&d(e);)e=e.offsetParent;return e||c};return{position:function(b){var c=this.offset(b),d={top:0,left:0},f=e(b[0]);f!=a[0]&&(d=this.offset(angular.element(f)),d.top+=f.clientTop-f.scrollTop,d.left+=f.clientLeft-f.scrollLeft);var g=b[0].getBoundingClientRect();return{width:g.width||b.prop("offsetWidth"),height:g.height||b.prop("offsetHeight"),top:c.top-d.top,left:c.left-d.left}},offset:function(c){var d=c[0].getBoundingClientRect();return{width:d.width||c.prop("offsetWidth"),height:d.height||c.prop("offsetHeight"),top:d.top+(b.pageYOffset||a[0].body.scrollTop||a[0].documentElement.scrollTop),left:d.left+(b.pageXOffset||a[0].body.scrollLeft||a[0].documentElement.scrollLeft)}}}}]),angular.module("ui.bootstrap.datepicker",["ui.bootstrap.position"]).constant("datepickerConfig",{dayFormat:"dd",monthFormat:"MMMM",yearFormat:"yyyy",dayHeaderFormat:"EEE",dayTitleFormat:"MMMM yyyy",monthTitleFormat:"yyyy",showWeeks:!0,startingDay:0,yearRange:20,minDate:null,maxDate:null}).controller("DatepickerController",["$scope","$attrs","dateFilter","datepickerConfig",function(a,b,c,d){function e(b,c){return angular.isDefined(b)?a.$parent.$eval(b):c}function f(a,b){return new Date(a,b,0).getDate()}function g(a,b){for(var c=new Array(b),d=a,e=0;b>e;)c[e++]=new Date(d),d.setDate(d.getDate()+1);return c}function h(a,b,d,e){return{date:a,label:c(a,b),selected:!!d,secondary:!!e}}var i={day:e(b.dayFormat,d.dayFormat),month:e(b.monthFormat,d.monthFormat),year:e(b.yearFormat,d.yearFormat),dayHeader:e(b.dayHeaderFormat,d.dayHeaderFormat),dayTitle:e(b.dayTitleFormat,d.dayTitleFormat),monthTitle:e(b.monthTitleFormat,d.monthTitleFormat)},j=e(b.startingDay,d.startingDay),k=e(b.yearRange,d.yearRange);this.minDate=d.minDate?new Date(d.minDate):null,this.maxDate=d.maxDate?new Date(d.maxDate):null,this.modes=[{name:"day",getVisibleDates:function(a,b){var d=a.getFullYear(),e=a.getMonth(),k=new Date(d,e,1),l=j-k.getDay(),m=l>0?7-l:-l,n=new Date(k),o=0;m>0&&(n.setDate(-m+1),o+=m),o+=f(d,e+1),o+=(7-o%7)%7;for(var p=g(n,o),q=new Array(7),r=0;o>r;r++){var s=new Date(p[r]);p[r]=h(s,i.day,b&&b.getDate()===s.getDate()&&b.getMonth()===s.getMonth()&&b.getFullYear()===s.getFullYear(),s.getMonth()!==e)}for(var t=0;7>t;t++)q[t]=c(p[t].date,i.dayHeader);return{objects:p,title:c(a,i.dayTitle),labels:q}},compare:function(a,b){return new Date(a.getFullYear(),a.getMonth(),a.getDate())-new Date(b.getFullYear(),b.getMonth(),b.getDate())},split:7,step:{months:1}},{name:"month",getVisibleDates:function(a,b){for(var d=new Array(12),e=a.getFullYear(),f=0;12>f;f++){var g=new Date(e,f,1);d[f]=h(g,i.month,b&&b.getMonth()===f&&b.getFullYear()===e)}return{objects:d,title:c(a,i.monthTitle)}},compare:function(a,b){return new Date(a.getFullYear(),a.getMonth())-new Date(b.getFullYear(),b.getMonth())},split:3,step:{years:1}},{name:"year",getVisibleDates:function(a,b){for(var c=new Array(k),d=a.getFullYear(),e=parseInt((d-1)/k,10)*k+1,f=0;k>f;f++){var g=new Date(e+f,0,1);c[f]=h(g,i.year,b&&b.getFullYear()===g.getFullYear())}return{objects:c,title:[c[0].label,c[k-1].label].join(" - ")}},compare:function(a,b){return a.getFullYear()-b.getFullYear()},split:5,step:{years:k}}],this.isDisabled=function(b,c){var d=this.modes[c||0];return this.minDate&&d.compare(b,this.minDate)<0||this.maxDate&&d.compare(b,this.maxDate)>0||a.dateDisabled&&a.dateDisabled({date:b,mode:d.name})}}]).directive("datepicker",["dateFilter","$parse","datepickerConfig","$log",function(a,b,c,d){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/datepicker.html",scope:{dateDisabled:"&"},require:["datepicker","?^ngModel"],controller:"DatepickerController",link:function(a,e,f,g){function h(){a.showWeekNumbers=0===o&&q}function i(a,b){for(var c=[];a.length>0;)c.push(a.splice(0,b));return c}function j(b){var c=null,e=!0;n.$modelValue&&(c=new Date(n.$modelValue),isNaN(c)?(e=!1,d.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.')):b&&(p=c)),n.$setValidity("date",e);var f=m.modes[o],g=f.getVisibleDates(p,c);angular.forEach(g.objects,function(a){a.disabled=m.isDisabled(a.date,o)}),n.$setValidity("date-disabled",!c||!m.isDisabled(c)),a.rows=i(g.objects,f.split),a.labels=g.labels||[],a.title=g.title}function k(a){o=a,h(),j()}function l(a){var b=new Date(a);b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();return b.setMonth(0),b.setDate(1),Math.floor(Math.round((c-b)/864e5)/7)+1}var m=g[0],n=g[1];if(n){var o=0,p=new Date,q=c.showWeeks;f.showWeeks?a.$parent.$watch(b(f.showWeeks),function(a){q=!!a,h()}):h(),f.min&&a.$parent.$watch(b(f.min),function(a){m.minDate=a?new Date(a):null,j()}),f.max&&a.$parent.$watch(b(f.max),function(a){m.maxDate=a?new Date(a):null,j()}),n.$render=function(){j(!0)},a.select=function(a){if(0===o){var b=n.$modelValue?new Date(n.$modelValue):new Date(0,0,0,0,0,0,0);b.setFullYear(a.getFullYear(),a.getMonth(),a.getDate()),n.$setViewValue(b),j(!0)}else p=a,k(o-1)},a.move=function(a){var b=m.modes[o].step;p.setMonth(p.getMonth()+a*(b.months||0)),p.setFullYear(p.getFullYear()+a*(b.years||0)),j()},a.toggleMode=function(){k((o+1)%m.modes.length)},a.getWeekNumber=function(b){return 0===o&&a.showWeekNumbers&&7===b.length?l(b[0].date):null}}}}}]).constant("datepickerPopupConfig",{dateFormat:"yyyy-MM-dd",currentText:"Today",toggleWeeksText:"Weeks",clearText:"Clear",closeText:"Done",closeOnDateSelection:!0,appendToBody:!1,showButtonBar:!0}).directive("datepickerPopup",["$compile","$parse","$document","$position","dateFilter","datepickerPopupConfig","datepickerConfig",function(a,b,c,d,e,f,g){return{restrict:"EA",require:"ngModel",link:function(h,i,j,k){function l(a){u?u(h,!!a):q.isOpen=!!a}function m(a){if(a){if(angular.isDate(a))return k.$setValidity("date",!0),a;if(angular.isString(a)){var b=new Date(a);return isNaN(b)?(k.$setValidity("date",!1),void 0):(k.$setValidity("date",!0),b)}return k.$setValidity("date",!1),void 0}return k.$setValidity("date",!0),null}function n(a,c,d){a&&(h.$watch(b(a),function(a){q[c]=a}),y.attr(d||c,c))}function o(){q.position=s?d.offset(i):d.position(i),q.position.top=q.position.top+i.prop("offsetHeight")}var p,q=h.$new(),r=angular.isDefined(j.closeOnDateSelection)?h.$eval(j.closeOnDateSelection):f.closeOnDateSelection,s=angular.isDefined(j.datepickerAppendToBody)?h.$eval(j.datepickerAppendToBody):f.appendToBody;j.$observe("datepickerPopup",function(a){p=a||f.dateFormat,k.$render()}),q.showButtonBar=angular.isDefined(j.showButtonBar)?h.$eval(j.showButtonBar):f.showButtonBar,h.$on("$destroy",function(){B.remove(),q.$destroy()}),j.$observe("currentText",function(a){q.currentText=angular.isDefined(a)?a:f.currentText}),j.$observe("toggleWeeksText",function(a){q.toggleWeeksText=angular.isDefined(a)?a:f.toggleWeeksText}),j.$observe("clearText",function(a){q.clearText=angular.isDefined(a)?a:f.clearText}),j.$observe("closeText",function(a){q.closeText=angular.isDefined(a)?a:f.closeText});var t,u;j.isOpen&&(t=b(j.isOpen),u=t.assign,h.$watch(t,function(a){q.isOpen=!!a})),q.isOpen=t?t(h):!1;var v=function(a){q.isOpen&&a.target!==i[0]&&q.$apply(function(){l(!1)})},w=function(){q.$apply(function(){l(!0)})},x=angular.element("<div datepicker-popup-wrap><div datepicker></div></div>");x.attr({"ng-model":"date","ng-change":"dateSelection()"});var y=angular.element(x.children()[0]);j.datepickerOptions&&y.attr(angular.extend({},h.$eval(j.datepickerOptions))),k.$parsers.unshift(m),q.dateSelection=function(a){angular.isDefined(a)&&(q.date=a),k.$setViewValue(q.date),k.$render(),r&&l(!1)},i.bind("input change keyup",function(){q.$apply(function(){q.date=k.$modelValue})}),k.$render=function(){var a=k.$viewValue?e(k.$viewValue,p):"";i.val(a),q.date=k.$modelValue},n(j.min,"min"),n(j.max,"max"),j.showWeeks?n(j.showWeeks,"showWeeks","show-weeks"):(q.showWeeks=g.showWeeks,y.attr("show-weeks","showWeeks")),j.dateDisabled&&y.attr("date-disabled",j.dateDisabled);var z=!1,A=!1;q.$watch("isOpen",function(a){a?(o(),c.bind("click",v),A&&i.unbind("focus",w),i[0].focus(),z=!0):(z&&c.unbind("click",v),i.bind("focus",w),A=!0),u&&u(h,a)}),q.today=function(){q.dateSelection(new Date)},q.clear=function(){q.dateSelection(null)};var B=a(x)(q);s?c.find("body").append(B):i.after(B)}}}]).directive("datepickerPopupWrap",function(){return{restrict:"EA",replace:!0,transclude:!0,templateUrl:"template/datepicker/popup.html",link:function(a,b){b.bind("click",function(a){a.preventDefault(),a.stopPropagation()})}}}),angular.module("ui.bootstrap.dropdownToggle",[]).directive("dropdownToggle",["$document","$location",function(a){var b=null,c=angular.noop;return{restrict:"CA",link:function(d,e){d.$watch("$location.path",function(){c()}),e.parent().bind("click",function(){c()}),e.bind("click",function(d){var f=e===b;d.preventDefault(),d.stopPropagation(),b&&c(),f||e.hasClass("disabled")||e.prop("disabled")||(e.parent().addClass("open"),b=e,c=function(d){d&&(d.preventDefault(),d.stopPropagation()),a.unbind("click",c),e.parent().removeClass("open"),c=angular.noop,b=null},a.bind("click",c))})}}}]),angular.module("ui.bootstrap.modal",[]).factory("$$stackedMap",function(){return{createNew:function(){var a=[];return{add:function(b,c){a.push({key:b,value:c})},get:function(b){for(var c=0;c<a.length;c++)if(b==a[c].key)return a[c]},keys:function(){for(var b=[],c=0;c<a.length;c++)b.push(a[c].key);return b},top:function(){return a[a.length-1]},remove:function(b){for(var c=-1,d=0;d<a.length;d++)if(b==a[d].key){c=d;break}return a.splice(c,1)[0]},removeTop:function(){return a.splice(a.length-1,1)[0]},length:function(){return a.length}}}}}).directive("modalBackdrop",["$timeout",function(a){return{restrict:"EA",replace:!0,templateUrl:"template/modal/backdrop.html",link:function(b){b.animate=!1,a(function(){b.animate=!0})}}}]).directive("modalWindow",["$modalStack","$timeout",function(a,b){return{restrict:"EA",scope:{index:"@"},replace:!0,transclude:!0,templateUrl:"template/modal/window.html",link:function(c,d,e){c.windowClass=e.windowClass||"",b(function(){c.animate=!0,d[0].focus()}),c.close=function(b){var c=a.getTop();c&&c.value.backdrop&&"static"!=c.value.backdrop&&b.target===b.currentTarget&&(b.preventDefault(),b.stopPropagation(),a.dismiss(c.key,"backdrop click"))}}}}]).factory("$modalStack",["$document","$compile","$rootScope","$$stackedMap",function(a,b,c,d){function e(){for(var a=-1,b=k.keys(),c=0;c<b.length;c++)k.get(b[c]).value.backdrop&&(a=c);return a}function f(b){var c=a.find("body").eq(0),d=k.get(b).value;k.remove(b),d.modalDomEl.remove(),c.toggleClass(i,k.length()>0),h&&-1==e()&&(h.remove(),h=void 0),d.modalScope.$destroy()}var g,h,i="modal-open",j=c.$new(!0),k=d.createNew(),l={};return c.$watch(e,function(a){j.index=a}),a.bind("keydown",function(a){var b;27===a.which&&(b=k.top(),b&&b.value.keyboard&&c.$apply(function(){l.dismiss(b.key)}))}),l.open=function(c,d){k.add(c,{deferred:d.deferred,modalScope:d.scope,backdrop:d.backdrop,keyboard:d.keyboard});var f=a.find("body").eq(0);e()>=0&&!h&&(g=angular.element("<div modal-backdrop></div>"),h=b(g)(j),f.append(h));var l=angular.element("<div modal-window></div>");l.attr("window-class",d.windowClass),l.attr("index",k.length()-1),l.html(d.content);var m=b(l)(d.scope);k.top().value.modalDomEl=m,f.append(m),f.addClass(i)},l.close=function(a,b){var c=k.get(a).value;c&&(c.deferred.resolve(b),f(a))},l.dismiss=function(a,b){var c=k.get(a).value;c&&(c.deferred.reject(b),f(a))},l.getTop=function(){return k.top()},l}]).provider("$modal",function(){var a={options:{backdrop:!0,keyboard:!0},$get:["$injector","$rootScope","$q","$http","$templateCache","$controller","$modalStack",function(b,c,d,e,f,g,h){function i(a){return a.template?d.when(a.template):e.get(a.templateUrl,{cache:f}).then(function(a){return a.data})}function j(a){var c=[];return angular.forEach(a,function(a){(angular.isFunction(a)||angular.isArray(a))&&c.push(d.when(b.invoke(a)))}),c}var k={};return k.open=function(b){var e=d.defer(),f=d.defer(),k={result:e.promise,opened:f.promise,close:function(a){h.close(k,a)},dismiss:function(a){h.dismiss(k,a)}};if(b=angular.extend({},a.options,b),b.resolve=b.resolve||{},!b.template&&!b.templateUrl)throw new Error("One of template or templateUrl options is required.");var l=d.all([i(b)].concat(j(b.resolve)));return l.then(function(a){var d=(b.scope||c).$new();d.$close=k.close,d.$dismiss=k.dismiss;var f,i={},j=1;b.controller&&(i.$scope=d,i.$modalInstance=k,angular.forEach(b.resolve,function(b,c){i[c]=a[j++]}),f=g(b.controller,i)),h.open(k,{scope:d,deferred:e,content:a[0],backdrop:b.backdrop,keyboard:b.keyboard,windowClass:b.windowClass})},function(a){e.reject(a)}),l.then(function(){f.resolve(!0)},function(){f.reject(!1)}),k},k}]};return a}),angular.module("ui.bootstrap.pagination",[]).controller("PaginationController",["$scope","$attrs","$parse","$interpolate",function(a,b,c,d){var e=this,f=b.numPages?c(b.numPages).assign:angular.noop;this.init=function(d){b.itemsPerPage?a.$parent.$watch(c(b.itemsPerPage),function(b){e.itemsPerPage=parseInt(b,10),a.totalPages=e.calculateTotalPages()}):this.itemsPerPage=d},this.noPrevious=function(){return 1===this.page},this.noNext=function(){return this.page===a.totalPages},this.isActive=function(a){return this.page===a},this.calculateTotalPages=function(){var b=this.itemsPerPage<1?1:Math.ceil(a.totalItems/this.itemsPerPage);return Math.max(b||0,1)},this.getAttributeValue=function(b,c,e){return angular.isDefined(b)?e?d(b)(a.$parent):a.$parent.$eval(b):c},this.render=function(){this.page=parseInt(a.page,10)||1,this.page>0&&this.page<=a.totalPages&&(a.pages=this.getPages(this.page,a.totalPages))},a.selectPage=function(b){!e.isActive(b)&&b>0&&b<=a.totalPages&&(a.page=b,a.onSelectPage({page:b}))},a.$watch("page",function(){e.render()}),a.$watch("totalItems",function(){a.totalPages=e.calculateTotalPages()}),a.$watch("totalPages",function(b){f(a.$parent,b),e.page>b?a.selectPage(b):e.render()})}]).constant("paginationConfig",{itemsPerPage:10,boundaryLinks:!1,directionLinks:!0,firstText:"First",previousText:"Previous",nextText:"Next",lastText:"Last",rotate:!0}).directive("pagination",["$parse","paginationConfig",function(a,b){return{restrict:"EA",scope:{page:"=",totalItems:"=",onSelectPage:" &"},controller:"PaginationController",templateUrl:"template/pagination/pagination.html",replace:!0,link:function(c,d,e,f){function g(a,b,c,d){return{number:a,text:b,active:c,disabled:d}}var h,i=f.getAttributeValue(e.boundaryLinks,b.boundaryLinks),j=f.getAttributeValue(e.directionLinks,b.directionLinks),k=f.getAttributeValue(e.firstText,b.firstText,!0),l=f.getAttributeValue(e.previousText,b.previousText,!0),m=f.getAttributeValue(e.nextText,b.nextText,!0),n=f.getAttributeValue(e.lastText,b.lastText,!0),o=f.getAttributeValue(e.rotate,b.rotate);f.init(b.itemsPerPage),e.maxSize&&c.$parent.$watch(a(e.maxSize),function(a){h=parseInt(a,10),f.render()}),f.getPages=function(a,b){var c=[],d=1,e=b,p=angular.isDefined(h)&&b>h;p&&(o?(d=Math.max(a-Math.floor(h/2),1),e=d+h-1,e>b&&(e=b,d=e-h+1)):(d=(Math.ceil(a/h)-1)*h+1,e=Math.min(d+h-1,b)));for(var q=d;e>=q;q++){var r=g(q,q,f.isActive(q),!1);c.push(r)}if(p&&!o){if(d>1){var s=g(d-1,"...",!1,!1);c.unshift(s)}if(b>e){var t=g(e+1,"...",!1,!1);c.push(t)}}if(j){var u=g(a-1,l,!1,f.noPrevious());c.unshift(u);var v=g(a+1,m,!1,f.noNext());c.push(v)}if(i){var w=g(1,k,!1,f.noPrevious());c.unshift(w);var x=g(b,n,!1,f.noNext());c.push(x)}return c}}}}]).constant("pagerConfig",{itemsPerPage:10,previousText:"« Previous",nextText:"Next »",align:!0}).directive("pager",["pagerConfig",function(a){return{restrict:"EA",scope:{page:"=",totalItems:"=",onSelectPage:" &"},controller:"PaginationController",templateUrl:"template/pagination/pager.html",replace:!0,link:function(b,c,d,e){function f(a,b,c,d,e){return{number:a,text:b,disabled:c,previous:i&&d,next:i&&e}}var g=e.getAttributeValue(d.previousText,a.previousText,!0),h=e.getAttributeValue(d.nextText,a.nextText,!0),i=e.getAttributeValue(d.align,a.align);e.init(a.itemsPerPage),e.getPages=function(a){return[f(a-1,g,e.noPrevious(),!0,!1),f(a+1,h,e.noNext(),!1,!0)]}}}}]),angular.module("ui.bootstrap.tooltip",["ui.bootstrap.position","ui.bootstrap.bindHtml"]).provider("$tooltip",function(){function a(a){var b=/[A-Z]/g,c="-";return a.replace(b,function(a,b){return(b?c:"")+a.toLowerCase()})}var b={placement:"top",animation:!0,popupDelay:0},c={mouseenter:"mouseleave",click:"click",focus:"blur"},d={};this.options=function(a){angular.extend(d,a)},this.setTriggers=function(a){angular.extend(c,a)},this.$get=["$window","$compile","$timeout","$parse","$document","$position","$interpolate",function(e,f,g,h,i,j,k){return function(e,l,m){function n(a){var b=a||o.trigger||m,d=c[b]||b;return{show:b,hide:d}}var o=angular.extend({},b,d),p=a(e),q=k.startSymbol(),r=k.endSymbol(),s="<div "+p+'-popup title="'+q+"tt_title"+r+'" content="'+q+"tt_content"+r+'" placement="'+q+"tt_placement"+r+'" animation="tt_animation" is-open="tt_isOpen"></div>';return{restrict:"EA",scope:!0,link:function(a,b,c){function d(){a.tt_isOpen?m():k()}function k(){(!y||a.$eval(c[l+"Enable"]))&&(a.tt_popupDelay?(t=g(p,a.tt_popupDelay),t.then(function(a){a()})):a.$apply(p)())}function m(){a.$apply(function(){q()})}function p(){return a.tt_content?(r&&g.cancel(r),u.css({top:0,left:0,display:"block"}),v?i.find("body").append(u):b.after(u),z(),a.tt_isOpen=!0,z):angular.noop}function q(){a.tt_isOpen=!1,g.cancel(t),a.tt_animation?r=g(function(){u.remove()},500):u.remove()}var r,t,u=f(s)(a),v=angular.isDefined(o.appendToBody)?o.appendToBody:!1,w=n(void 0),x=!1,y=angular.isDefined(c[l+"Enable"]),z=function(){var c,d,e,f;switch(c=v?j.offset(b):j.position(b),d=u.prop("offsetWidth"),e=u.prop("offsetHeight"),a.tt_placement){case"right":f={top:c.top+c.height/2-e/2,left:c.left+c.width};break;case"bottom":f={top:c.top+c.height,left:c.left+c.width/2-d/2};break;case"left":f={top:c.top+c.height/2-e/2,left:c.left-d};break;default:f={top:c.top-e,left:c.left+c.width/2-d/2}}f.top+="px",f.left+="px",u.css(f)};a.tt_isOpen=!1,c.$observe(e,function(b){a.tt_content=b,!b&&a.tt_isOpen&&q()}),c.$observe(l+"Title",function(b){a.tt_title=b}),c.$observe(l+"Placement",function(b){a.tt_placement=angular.isDefined(b)?b:o.placement}),c.$observe(l+"PopupDelay",function(b){var c=parseInt(b,10);a.tt_popupDelay=isNaN(c)?o.popupDelay:c});var A=function(){x&&(b.unbind(w.show,k),b.unbind(w.hide,m))};c.$observe(l+"Trigger",function(a){A(),w=n(a),w.show===w.hide?b.bind(w.show,d):(b.bind(w.show,k),b.bind(w.hide,m)),x=!0});var B=a.$eval(c[l+"Animation"]);a.tt_animation=angular.isDefined(B)?!!B:o.animation,c.$observe(l+"AppendToBody",function(b){v=angular.isDefined(b)?h(b)(a):v}),v&&a.$on("$locationChangeSuccess",function(){a.tt_isOpen&&q()}),a.$on("$destroy",function(){g.cancel(r),g.cancel(t),A(),u.remove(),u.unbind(),u=null})}}}}]}).directive("tooltipPopup",function(){return{restrict:"EA",replace:!0,scope:{content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-popup.html"}}).directive("tooltip",["$tooltip",function(a){return a("tooltip","tooltip","mouseenter")}]).directive("tooltipHtmlUnsafePopup",function(){return{restrict:"EA",replace:!0,scope:{content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-html-unsafe-popup.html"}}).directive("tooltipHtmlUnsafe",["$tooltip",function(a){return a("tooltipHtmlUnsafe","tooltip","mouseenter")}]),angular.module("ui.bootstrap.popover",["ui.bootstrap.tooltip"]).directive("popoverPopup",function(){return{restrict:"EA",replace:!0,scope:{title:"@",content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/popover/popover.html"}}).directive("popover",["$compile","$timeout","$parse","$window","$tooltip",function(a,b,c,d,e){return e("popover","popover","click")}]),angular.module("ui.bootstrap.progressbar",["ui.bootstrap.transition"]).constant("progressConfig",{animate:!0,max:100}).controller("ProgressController",["$scope","$attrs","progressConfig","$transition",function(a,b,c,d){var e=this,f=[],g=angular.isDefined(b.max)?a.$parent.$eval(b.max):c.max,h=angular.isDefined(b.animate)?a.$parent.$eval(b.animate):c.animate;this.addBar=function(a,b){var c=0,d=a.$parent.$index;angular.isDefined(d)&&f[d]&&(c=f[d].value),f.push(a),this.update(b,a.value,c),a.$watch("value",function(a,c){a!==c&&e.update(b,a,c)}),a.$on("$destroy",function(){e.removeBar(a)})},this.update=function(a,b,c){var e=this.getPercentage(b);h?(a.css("width",this.getPercentage(c)+"%"),d(a,{width:e+"%"})):a.css({transition:"none",width:e+"%"})},this.removeBar=function(a){f.splice(f.indexOf(a),1)},this.getPercentage=function(a){return Math.round(100*a/g)}}]).directive("progress",function(){return{restrict:"EA",replace:!0,transclude:!0,controller:"ProgressController",require:"progress",scope:{},template:'<div class="progress" ng-transclude></div>'}}).directive("bar",function(){return{restrict:"EA",replace:!0,transclude:!0,require:"^progress",scope:{value:"=",type:"@"},templateUrl:"template/progressbar/bar.html",link:function(a,b,c,d){d.addBar(a,b)}}}).directive("progressbar",function(){return{restrict:"EA",replace:!0,transclude:!0,controller:"ProgressController",scope:{value:"=",type:"@"},templateUrl:"template/progressbar/progressbar.html",link:function(a,b,c,d){d.addBar(a,angular.element(b.children()[0]))}}}),angular.module("ui.bootstrap.rating",[]).constant("ratingConfig",{max:5,stateOn:null,stateOff:null}).controller("RatingController",["$scope","$attrs","$parse","ratingConfig",function(a,b,c,d){this.maxRange=angular.isDefined(b.max)?a.$parent.$eval(b.max):d.max,this.stateOn=angular.isDefined(b.stateOn)?a.$parent.$eval(b.stateOn):d.stateOn,this.stateOff=angular.isDefined(b.stateOff)?a.$parent.$eval(b.stateOff):d.stateOff,this.createRateObjects=function(a){for(var b={stateOn:this.stateOn,stateOff:this.stateOff},c=0,d=a.length;d>c;c++)a[c]=angular.extend({index:c},b,a[c]);return a},a.range=angular.isDefined(b.ratingStates)?this.createRateObjects(angular.copy(a.$parent.$eval(b.ratingStates))):this.createRateObjects(new Array(this.maxRange)),a.rate=function(b){a.readonly||a.value===b||(a.value=b)},a.enter=function(b){a.readonly||(a.val=b),a.onHover({value:b})},a.reset=function(){a.val=angular.copy(a.value),a.onLeave()},a.$watch("value",function(b){a.val=b}),a.readonly=!1,b.readonly&&a.$parent.$watch(c(b.readonly),function(b){a.readonly=!!b})}]).directive("rating",function(){return{restrict:"EA",scope:{value:"=",onHover:"&",onLeave:"&"},controller:"RatingController",templateUrl:"template/rating/rating.html",replace:!0}}),angular.module("ui.bootstrap.tabs",[]).controller("TabsetController",["$scope",function(a){var b=this,c=b.tabs=a.tabs=[];
    +b.select=function(a){angular.forEach(c,function(a){a.active=!1}),a.active=!0},b.addTab=function(a){c.push(a),(1===c.length||a.active)&&b.select(a)},b.removeTab=function(a){var d=c.indexOf(a);if(a.active&&c.length>1){var e=d==c.length-1?d-1:d+1;b.select(c[e])}c.splice(d,1)}}]).directive("tabset",function(){return{restrict:"EA",transclude:!0,replace:!0,scope:{},controller:"TabsetController",templateUrl:"template/tabs/tabset.html",link:function(a,b,c){a.vertical=angular.isDefined(c.vertical)?a.$parent.$eval(c.vertical):!1,a.justified=angular.isDefined(c.justified)?a.$parent.$eval(c.justified):!1,a.type=angular.isDefined(c.type)?a.$parent.$eval(c.type):"tabs"}}}).directive("tab",["$parse",function(a){return{require:"^tabset",restrict:"EA",replace:!0,templateUrl:"template/tabs/tab.html",transclude:!0,scope:{heading:"@",onSelect:"&select",onDeselect:"&deselect"},controller:function(){},compile:function(b,c,d){return function(b,c,e,f){var g,h;e.active?(g=a(e.active),h=g.assign,b.$parent.$watch(g,function(a,c){a!==c&&(b.active=!!a)}),b.active=g(b.$parent)):h=g=angular.noop,b.$watch("active",function(a){h(b.$parent,a),a?(f.select(b),b.onSelect()):b.onDeselect()}),b.disabled=!1,e.disabled&&b.$parent.$watch(a(e.disabled),function(a){b.disabled=!!a}),b.select=function(){b.disabled||(b.active=!0)},f.addTab(b),b.$on("$destroy",function(){f.removeTab(b)}),b.$transcludeFn=d}}}}]).directive("tabHeadingTransclude",[function(){return{restrict:"A",require:"^tab",link:function(a,b){a.$watch("headingElement",function(a){a&&(b.html(""),b.append(a))})}}}]).directive("tabContentTransclude",function(){function a(a){return a.tagName&&(a.hasAttribute("tab-heading")||a.hasAttribute("data-tab-heading")||"tab-heading"===a.tagName.toLowerCase()||"data-tab-heading"===a.tagName.toLowerCase())}return{restrict:"A",require:"^tabset",link:function(b,c,d){var e=b.$eval(d.tabContentTransclude);e.$transcludeFn(e.$parent,function(b){angular.forEach(b,function(b){a(b)?e.headingElement=b:c.append(b)})})}}}),angular.module("ui.bootstrap.timepicker",[]).constant("timepickerConfig",{hourStep:1,minuteStep:1,showMeridian:!0,meridians:null,readonlyInput:!1,mousewheel:!0}).directive("timepicker",["$parse","$log","timepickerConfig","$locale",function(a,b,c,d){return{restrict:"EA",require:"?^ngModel",replace:!0,scope:{},templateUrl:"template/timepicker/timepicker.html",link:function(e,f,g,h){function i(){var a=parseInt(e.hours,10),b=e.showMeridian?a>0&&13>a:a>=0&&24>a;return b?(e.showMeridian&&(12===a&&(a=0),e.meridian===q[1]&&(a+=12)),a):void 0}function j(){var a=parseInt(e.minutes,10);return a>=0&&60>a?a:void 0}function k(a){return angular.isDefined(a)&&a.toString().length<2?"0"+a:a}function l(a){m(),h.$setViewValue(new Date(p)),n(a)}function m(){h.$setValidity("time",!0),e.invalidHours=!1,e.invalidMinutes=!1}function n(a){var b=p.getHours(),c=p.getMinutes();e.showMeridian&&(b=0===b||12===b?12:b%12),e.hours="h"===a?b:k(b),e.minutes="m"===a?c:k(c),e.meridian=p.getHours()<12?q[0]:q[1]}function o(a){var b=new Date(p.getTime()+6e4*a);p.setHours(b.getHours(),b.getMinutes()),l()}if(h){var p=new Date,q=angular.isDefined(g.meridians)?e.$parent.$eval(g.meridians):c.meridians||d.DATETIME_FORMATS.AMPMS,r=c.hourStep;g.hourStep&&e.$parent.$watch(a(g.hourStep),function(a){r=parseInt(a,10)});var s=c.minuteStep;g.minuteStep&&e.$parent.$watch(a(g.minuteStep),function(a){s=parseInt(a,10)}),e.showMeridian=c.showMeridian,g.showMeridian&&e.$parent.$watch(a(g.showMeridian),function(a){if(e.showMeridian=!!a,h.$error.time){var b=i(),c=j();angular.isDefined(b)&&angular.isDefined(c)&&(p.setHours(b),l())}else n()});var t=f.find("input"),u=t.eq(0),v=t.eq(1),w=angular.isDefined(g.mousewheel)?e.$eval(g.mousewheel):c.mousewheel;if(w){var x=function(a){a.originalEvent&&(a=a.originalEvent);var b=a.wheelDelta?a.wheelDelta:-a.deltaY;return a.detail||b>0};u.bind("mousewheel wheel",function(a){e.$apply(x(a)?e.incrementHours():e.decrementHours()),a.preventDefault()}),v.bind("mousewheel wheel",function(a){e.$apply(x(a)?e.incrementMinutes():e.decrementMinutes()),a.preventDefault()})}if(e.readonlyInput=angular.isDefined(g.readonlyInput)?e.$eval(g.readonlyInput):c.readonlyInput,e.readonlyInput)e.updateHours=angular.noop,e.updateMinutes=angular.noop;else{var y=function(a,b){h.$setViewValue(null),h.$setValidity("time",!1),angular.isDefined(a)&&(e.invalidHours=a),angular.isDefined(b)&&(e.invalidMinutes=b)};e.updateHours=function(){var a=i();angular.isDefined(a)?(p.setHours(a),l("h")):y(!0)},u.bind("blur",function(){!e.validHours&&e.hours<10&&e.$apply(function(){e.hours=k(e.hours)})}),e.updateMinutes=function(){var a=j();angular.isDefined(a)?(p.setMinutes(a),l("m")):y(void 0,!0)},v.bind("blur",function(){!e.invalidMinutes&&e.minutes<10&&e.$apply(function(){e.minutes=k(e.minutes)})})}h.$render=function(){var a=h.$modelValue?new Date(h.$modelValue):null;isNaN(a)?(h.$setValidity("time",!1),b.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.')):(a&&(p=a),m(),n())},e.incrementHours=function(){o(60*r)},e.decrementHours=function(){o(60*-r)},e.incrementMinutes=function(){o(s)},e.decrementMinutes=function(){o(-s)},e.toggleMeridian=function(){o(720*(p.getHours()<12?1:-1))}}}}}]),angular.module("ui.bootstrap.typeahead",["ui.bootstrap.position","ui.bootstrap.bindHtml"]).factory("typeaheadParser",["$parse",function(a){var b=/^\s*(.*?)(?:\s+as\s+(.*?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+(.*)$/;return{parse:function(c){var d=c.match(b);if(!d)throw new Error("Expected typeahead specification in form of '_modelValue_ (as _label_)? for _item_ in _collection_' but got '"+c+"'.");return{itemName:d[3],source:a(d[4]),viewMapper:a(d[2]||d[1]),modelMapper:a(d[1])}}}}]).directive("typeahead",["$compile","$parse","$q","$timeout","$document","$position","typeaheadParser",function(a,b,c,d,e,f,g){var h=[9,13,27,38,40];return{require:"ngModel",link:function(i,j,k,l){var m,n=i.$eval(k.typeaheadMinLength)||1,o=i.$eval(k.typeaheadWaitMs)||0,p=i.$eval(k.typeaheadEditable)!==!1,q=b(k.typeaheadLoading).assign||angular.noop,r=b(k.typeaheadOnSelect),s=k.typeaheadInputFormatter?b(k.typeaheadInputFormatter):void 0,t=k.typeaheadAppendToBody?b(k.typeaheadAppendToBody):!1,u=b(k.ngModel).assign,v=g.parse(k.typeahead),w=angular.element("<div typeahead-popup></div>");w.attr({matches:"matches",active:"activeIdx",select:"select(activeIdx)",query:"query",position:"position"}),angular.isDefined(k.typeaheadTemplateUrl)&&w.attr("template-url",k.typeaheadTemplateUrl);var x=i.$new();i.$on("$destroy",function(){x.$destroy()});var y=function(){x.matches=[],x.activeIdx=-1},z=function(a){var b={$viewValue:a};q(i,!0),c.when(v.source(i,b)).then(function(c){if(a===l.$viewValue&&m){if(c.length>0){x.activeIdx=0,x.matches.length=0;for(var d=0;d<c.length;d++)b[v.itemName]=c[d],x.matches.push({label:v.viewMapper(x,b),model:c[d]});x.query=a,x.position=t?f.offset(j):f.position(j),x.position.top=x.position.top+j.prop("offsetHeight")}else y();q(i,!1)}},function(){y(),q(i,!1)})};y(),x.query=void 0;var A;l.$parsers.unshift(function(a){return m=!0,a&&a.length>=n?o>0?(A&&d.cancel(A),A=d(function(){z(a)},o)):z(a):(q(i,!1),y()),p?a:a?(l.$setValidity("editable",!1),void 0):(l.$setValidity("editable",!0),a)}),l.$formatters.push(function(a){var b,c,d={};return s?(d.$model=a,s(i,d)):(d[v.itemName]=a,b=v.viewMapper(i,d),d[v.itemName]=void 0,c=v.viewMapper(i,d),b!==c?b:a)}),x.select=function(a){var b,c,d={};d[v.itemName]=c=x.matches[a].model,b=v.modelMapper(i,d),u(i,b),l.$setValidity("editable",!0),r(i,{$item:c,$model:b,$label:v.viewMapper(i,d)}),y(),j[0].focus()},j.bind("keydown",function(a){0!==x.matches.length&&-1!==h.indexOf(a.which)&&(a.preventDefault(),40===a.which?(x.activeIdx=(x.activeIdx+1)%x.matches.length,x.$digest()):38===a.which?(x.activeIdx=(x.activeIdx?x.activeIdx:x.matches.length)-1,x.$digest()):13===a.which||9===a.which?x.$apply(function(){x.select(x.activeIdx)}):27===a.which&&(a.stopPropagation(),y(),x.$digest()))}),j.bind("blur",function(){m=!1});var B=function(a){j[0]!==a.target&&(y(),x.$digest())};e.bind("click",B),i.$on("$destroy",function(){e.unbind("click",B)});var C=a(w)(x);t?e.find("body").append(C):j.after(C)}}}]).directive("typeaheadPopup",function(){return{restrict:"EA",scope:{matches:"=",query:"=",active:"=",position:"=",select:"&"},replace:!0,templateUrl:"template/typeahead/typeahead-popup.html",link:function(a,b,c){a.templateUrl=c.templateUrl,a.isOpen=function(){return a.matches.length>0},a.isActive=function(b){return a.active==b},a.selectActive=function(b){a.active=b},a.selectMatch=function(b){a.select({activeIdx:b})}}}}).directive("typeaheadMatch",["$http","$templateCache","$compile","$parse",function(a,b,c,d){return{restrict:"EA",scope:{index:"=",match:"=",query:"="},link:function(e,f,g){var h=d(g.templateUrl)(e.$parent)||"template/typeahead/typeahead-match.html";a.get(h,{cache:b}).success(function(a){f.replaceWith(c(a.trim())(e))})}}}]).filter("typeaheadHighlight",function(){function a(a){return a.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}return function(b,c){return c?b.replace(new RegExp(a(c),"gi"),"<strong>$&</strong>"):b}}),angular.module("template/accordion/accordion-group.html",[]).run(["$templateCache",function(a){a.put("template/accordion/accordion-group.html",'<div class="panel panel-default">\n  <div class="panel-heading">\n    <h4 class="panel-title">\n      <a class="accordion-toggle" ng-click="isOpen = !isOpen" accordion-transclude="heading">{{heading}}</a>\n    </h4>\n  </div>\n  <div class="panel-collapse" collapse="!isOpen">\n	  <div class="panel-body" ng-transclude></div>\n  </div>\n</div>')}]),angular.module("template/accordion/accordion.html",[]).run(["$templateCache",function(a){a.put("template/accordion/accordion.html",'<div class="panel-group" ng-transclude></div>')}]),angular.module("template/alert/alert.html",[]).run(["$templateCache",function(a){a.put("template/alert/alert.html","<div class='alert' ng-class='\"alert-\" + (type || \"warning\")'>\n    <button ng-show='closeable' type='button' class='close' ng-click='close()'>&times;</button>\n    <div ng-transclude></div>\n</div>\n")}]),angular.module("template/carousel/carousel.html",[]).run(["$templateCache",function(a){a.put("template/carousel/carousel.html",'<div ng-mouseenter="pause()" ng-mouseleave="play()" class="carousel">\n    <ol class="carousel-indicators" ng-show="slides().length > 1">\n        <li ng-repeat="slide in slides()" ng-class="{active: isActive(slide)}" ng-click="select(slide)"></li>\n    </ol>\n    <div class="carousel-inner" ng-transclude></div>\n    <a class="left carousel-control" ng-click="prev()" ng-show="slides().length > 1"><span class="icon-prev"></span></a>\n    <a class="right carousel-control" ng-click="next()" ng-show="slides().length > 1"><span class="icon-next"></span></a>\n</div>\n')}]),angular.module("template/carousel/slide.html",[]).run(["$templateCache",function(a){a.put("template/carousel/slide.html","<div ng-class=\"{\n    'active': leaving || (active && !entering),\n    'prev': (next || active) && direction=='prev',\n    'next': (next || active) && direction=='next',\n    'right': direction=='prev',\n    'left': direction=='next'\n  }\" class=\"item text-center\" ng-transclude></div>\n")}]),angular.module("template/datepicker/datepicker.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/datepicker.html",'<table>\n  <thead>\n    <tr>\n      <th><button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)"><i class="glyphicon glyphicon-chevron-left"></i></button></th>\n      <th colspan="{{rows[0].length - 2 + showWeekNumbers}}"><button type="button" class="btn btn-default btn-sm btn-block" ng-click="toggleMode()"><strong>{{title}}</strong></button></th>\n      <th><button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)"><i class="glyphicon glyphicon-chevron-right"></i></button></th>\n    </tr>\n    <tr ng-show="labels.length > 0" class="h6">\n      <th ng-show="showWeekNumbers" class="text-center">#</th>\n      <th ng-repeat="label in labels" class="text-center">{{label}}</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr ng-repeat="row in rows">\n      <td ng-show="showWeekNumbers" class="text-center"><em>{{ getWeekNumber(row) }}</em></td>\n      <td ng-repeat="dt in row" class="text-center">\n        <button type="button" style="width:100%;" class="btn btn-default btn-sm" ng-class="{\'btn-info\': dt.selected}" ng-click="select(dt.date)" ng-disabled="dt.disabled"><span ng-class="{\'text-muted\': dt.secondary}">{{dt.label}}</span></button>\n      </td>\n    </tr>\n  </tbody>\n</table>\n')}]),angular.module("template/datepicker/popup.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/popup.html","<ul class=\"dropdown-menu\" ng-style=\"{display: (isOpen && 'block') || 'none', top: position.top+'px', left: position.left+'px'}\">\n	<li ng-transclude></li>\n"+'	<li ng-show="showButtonBar" style="padding:10px 9px 2px">\n		<span class="btn-group">\n			<button type="button" class="btn btn-sm btn-info" ng-click="today()">{{currentText}}</button>\n			<button type="button" class="btn btn-sm btn-default" ng-click="showWeeks = ! showWeeks" ng-class="{active: showWeeks}">{{toggleWeeksText}}</button>\n			<button type="button" class="btn btn-sm btn-danger" ng-click="clear()">{{clearText}}</button>\n		</span>\n		<button type="button" class="btn btn-sm btn-success pull-right" ng-click="isOpen = false">{{closeText}}</button>\n	</li>\n</ul>\n')}]),angular.module("template/modal/backdrop.html",[]).run(["$templateCache",function(a){a.put("template/modal/backdrop.html",'<div class="modal-backdrop fade" ng-class="{in: animate}" ng-style="{\'z-index\': 1040 + index*10}"></div>')}]),angular.module("template/modal/window.html",[]).run(["$templateCache",function(a){a.put("template/modal/window.html",'<div tabindex="-1" class="modal fade {{ windowClass }}" ng-class="{in: animate}" ng-style="{\'z-index\': 1050 + index*10, display: \'block\'}" ng-click="close($event)">\n    <div class="modal-dialog"><div class="modal-content" ng-transclude></div></div>\n</div>')}]),angular.module("template/pagination/pager.html",[]).run(["$templateCache",function(a){a.put("template/pagination/pager.html",'<ul class="pager">\n  <li ng-repeat="page in pages" ng-class="{disabled: page.disabled, previous: page.previous, next: page.next}"><a ng-click="selectPage(page.number)">{{page.text}}</a></li>\n</ul>')}]),angular.module("template/pagination/pagination.html",[]).run(["$templateCache",function(a){a.put("template/pagination/pagination.html",'<ul class="pagination">\n  <li ng-repeat="page in pages" ng-class="{active: page.active, disabled: page.disabled}"><a ng-click="selectPage(page.number)">{{page.text}}</a></li>\n</ul>')}]),angular.module("template/tooltip/tooltip-html-unsafe-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-html-unsafe-popup.html",'<div class="tooltip {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">\n  <div class="tooltip-arrow"></div>\n  <div class="tooltip-inner" bind-html-unsafe="content"></div>\n</div>\n')}]),angular.module("template/tooltip/tooltip-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-popup.html",'<div class="tooltip {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">\n  <div class="tooltip-arrow"></div>\n  <div class="tooltip-inner" ng-bind="content"></div>\n</div>\n')}]),angular.module("template/popover/popover.html",[]).run(["$templateCache",function(a){a.put("template/popover/popover.html",'<div class="popover {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">\n  <div class="arrow"></div>\n\n  <div class="popover-inner">\n      <h3 class="popover-title" ng-bind="title" ng-show="title"></h3>\n      <div class="popover-content" ng-bind="content"></div>\n  </div>\n</div>\n')}]),angular.module("template/progressbar/bar.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/bar.html",'<div class="progress-bar" ng-class="type && \'progress-bar-\' + type" ng-transclude></div>')}]),angular.module("template/progressbar/progress.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/progress.html",'<div class="progress" ng-transclude></div>')}]),angular.module("template/progressbar/progressbar.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/progressbar.html",'<div class="progress"><div class="progress-bar" ng-class="type && \'progress-bar-\' + type" ng-transclude></div></div>')}]),angular.module("template/rating/rating.html",[]).run(["$templateCache",function(a){a.put("template/rating/rating.html",'<span ng-mouseleave="reset()">\n    <i ng-repeat="r in range" ng-mouseenter="enter($index + 1)" ng-click="rate($index + 1)" class="glyphicon" ng-class="$index < val && (r.stateOn || \'glyphicon-star\') || (r.stateOff || \'glyphicon-star-empty\')"></i>\n</span>')}]),angular.module("template/tabs/tab.html",[]).run(["$templateCache",function(a){a.put("template/tabs/tab.html",'<li ng-class="{active: active, disabled: disabled}">\n  <a ng-click="select()" tab-heading-transclude>{{heading}}</a>\n</li>\n')}]),angular.module("template/tabs/tabset-titles.html",[]).run(["$templateCache",function(a){a.put("template/tabs/tabset-titles.html","<ul class=\"nav {{type && 'nav-' + type}}\" ng-class=\"{'nav-stacked': vertical}\">\n</ul>\n")}]),angular.module("template/tabs/tabset.html",[]).run(["$templateCache",function(a){a.put("template/tabs/tabset.html",'\n<div class="tabbable">\n  <ul class="nav {{type && \'nav-\' + type}}" ng-class="{\'nav-stacked\': vertical, \'nav-justified\': justified}" ng-transclude></ul>\n  <div class="tab-content">\n    <div class="tab-pane" \n         ng-repeat="tab in tabs" \n         ng-class="{active: tab.active}"\n         tab-content-transclude="tab">\n    </div>\n  </div>\n</div>\n')}]),angular.module("template/timepicker/timepicker.html",[]).run(["$templateCache",function(a){a.put("template/timepicker/timepicker.html",'<table>\n	<tbody>\n		<tr class="text-center">\n			<td><a ng-click="incrementHours()" class="btn btn-link"><span class="glyphicon glyphicon-chevron-up"></span></a></td>\n			<td>&nbsp;</td>\n			<td><a ng-click="incrementMinutes()" class="btn btn-link"><span class="glyphicon glyphicon-chevron-up"></span></a></td>\n			<td ng-show="showMeridian"></td>\n		</tr>\n		<tr>\n			<td style="width:50px;" class="form-group" ng-class="{\'has-error\': invalidHours}">\n				<input type="text" ng-model="hours" ng-change="updateHours()" class="form-control text-center" ng-mousewheel="incrementHours()" ng-readonly="readonlyInput" maxlength="2">\n			</td>\n			<td>:</td>\n			<td style="width:50px;" class="form-group" ng-class="{\'has-error\': invalidMinutes}">\n				<input type="text" ng-model="minutes" ng-change="updateMinutes()" class="form-control text-center" ng-readonly="readonlyInput" maxlength="2">\n			</td>\n			<td ng-show="showMeridian"><button class="btn btn-default text-center" ng-click="toggleMeridian()">{{meridian}}</button></td>\n		</tr>\n		<tr class="text-center">\n			<td><a ng-click="decrementHours()" class="btn btn-link"><span class="glyphicon glyphicon-chevron-down"></span></a></td>\n			<td>&nbsp;</td>\n			<td><a ng-click="decrementMinutes()" class="btn btn-link"><span class="glyphicon glyphicon-chevron-down"></span></a></td>\n			<td ng-show="showMeridian"></td>\n		</tr>\n	</tbody>\n</table>\n')}]),angular.module("template/typeahead/typeahead-match.html",[]).run(["$templateCache",function(a){a.put("template/typeahead/typeahead-match.html",'<a tabindex="-1" bind-html-unsafe="match.label | typeaheadHighlight:query"></a>')}]),angular.module("template/typeahead/typeahead-popup.html",[]).run(["$templateCache",function(a){a.put("template/typeahead/typeahead-popup.html","<ul class=\"dropdown-menu\" ng-style=\"{display: isOpen()&&'block' || 'none', top: position.top+'px', left: position.left+'px'}\">\n"+'    <li ng-repeat="match in matches" ng-class="{active: isActive($index) }" ng-mouseenter="selectActive($index)" ng-click="selectMatch($index)">\n        <div typeahead-match index="$index" match="match" query="query" template-url="templateUrl"></div>\n    </li>\n</ul>')}]);
    \ No newline at end of file
    diff --git a/bower.json b/bower.json
    deleted file mode 100644
    index db20c0c..0000000
    --- a/bower.json
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -{
    -  "name": "angular-ui-sortable",
    -  "version": "0.19.0",
    -  "description": "This directive allows you to jQueryUI Sortable.",
    -  "author": "https://github.com/angular-ui/ui-sortable/graphs/contributors",
    -  "license": "MIT",
    -  "homepage": "http://angular-ui.github.com",
    -  "main": "./src/sortable.js",
    -  "ignore": [
    -    "**/.*",
    -    "node_modules",
    -    "bower_components",
    -    "test*",
    -    "demo*",
    -    "gruntFile.js",
    -    "package.json"
    -  ],
    -  "dependencies": {
    -    "angular": ">=1.2.x",
    -    "jquery": ">=3.1.x",
    -    "jquery-ui": ">=1.12.x"
    -  },
    -  "devDependencies": {
    -    "angular-mocks": ">=1.2.x",
    -    "jquery-simulate": "latest"
    -  }
    -}
    diff --git a/core/plunker.js b/core/plunker.js
    new file mode 100644
    index 0000000..4daca5b
    --- /dev/null
    +++ b/core/plunker.js
    @@ -0,0 +1,109 @@
    +/*
    + * Fork of https://github.com/angular-ui/bootstrap/blob/gh-pages/assets/plunker.js
    + */
    +angular.module('plunker', [])
    +
    +  .factory('plunkGenerator', function ($document) {
    +
    +    return function (ngVersion, moduleName, repoName, content, vendor_css, vendor_js) {
    +
    +      //HACK to add the css content...
    +      if (content.css !== void 0) vendor_css.push('style.css');
    +
    +      var form = angular.element('<form style="display: none;" method="post" action="http://plnkr.co/edit/?p=preview" target="_blank"></form>');
    +      var addField = function (name, value) {
    +        var input = angular.element('<input type="hidden" name="' + name + '">');
    +        input.attr('value', value);
    +        form.append(input);
    +      };
    +
    +      var listUpScript = function(jsFiles){
    +        var r = "";
    +        for(var i = 0, len = jsFiles.length; i < len; i++) {
    +          r += '      <script src="' + jsFiles[i] + '"></script>\n';
    +        }
    +
    +        return r;
    +      };
    +
    +      var listUpLink = function(cssFiles){
    +        var r = "";
    +        for(var i = 0, len = cssFiles.length; i < len; i++) {
    +          r += '    <link rel="stylesheet" type="text/css" href="' + cssFiles[i] + '"/>\n';
    +        }
    +        return r;
    +      };
    +
    +      var indexContent = function () {
    +        return '<!DOCTYPE html>\n' +
    +          '<html ng-app="x">\n\n' +
    +          '  <head>\n' +
    +          '    <meta charset="utf-8" />\n' +
    +          '    <title>' + moduleName + ' : demo </title>\n\n\n' +
    +          '    <!-- Le css -->\n' +
    +
    +          listUpLink(vendor_css) + '\n' +
    +
    +          '          <style>
              .commit-tease,
              .user-profile-mini-avatar,
              .avatar,
              .vcard-details,
              .signup-prompt-bg {
                display: none !IMPORTANT;
              }
            </style>
             <script>
              document.addEventListener('DOMContentLoaded', function() {
                this.querySelectorAll('a').forEach(anchor => {
                  anchor.addEventListener('click', e => {
                    e.preventDefault();
    
                    const redact = new URLSearchParams(window.location.search).get('redact');
                    const hasExistingParams = anchor.href.includes('?');
                    window.location.href = anchor.href + (hasExistingParams ? `&redact=${redact}` : `?redact=${redact}`);
                  });
                });
              });
            </script>
     </head>\n' +
    +          '  <body>\n\n\n' +
    +          '    <!-- Le content... -->\n' +
    +
    +          content.markup + '\n\n\n' +
    +
    +          '    <!-- Le vendor... -->\n' +
    +          '      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/'+ngVersion+'/angular.min.js"></script>\n' +
    +
    +          listUpScript(vendor_js) +
    +
    +          '      <script src="https://rawgithub.com/angular-ui/' + repoName + '/bower/' + repoName + '.min.js"></script>\n' +
    +
    +          '    <script src="app.js"></script>\n' +
    +          '  </body>\n' +
    +          '</html>\n';
    +      };
    +
    +      var scriptContent = function(content) {
    +        return "var app = angular.module('x', ['" + moduleName.toLowerCase() + "']);" + "\n\n\n" + content;
    +      };
    +
    +
    +
    +      addField('description', 'http://angular-ui.github.io/' + repoName);
    +      addField('files[index.html]', indexContent(content));
    +      addField('files[app.js]', scriptContent(content.javascript || ""));
    +
    +      if (content.css){
    +        addField('files[style.css]', content.css);
    +      }
    +
    +      $document.find('body').append(form);
    +      form[0].submit();
    +      form.remove();
    +    };
    +  })
    +
    +  .controller('PlunkerCtrl', function ($scope, plunkGenerator) {
    +
    +    $scope.content = {};
    +    $scope.vendor_css = [];
    +    $scope.vendor_js = [];
    +
    +    $scope.edit = function (ngVersion, moduleName, repoName) {
    +      plunkGenerator(ngVersion, moduleName, repoName,
    +        $scope.content, $scope.vendor_css, $scope.vendor_js
    +      );
    +    };
    +  })
    +
    +  .directive('plunkerContent', function () {
    +    return {
    +      link:function (scope, element, attrs) {
    +        var htmlContent = "";
    +        angular.forEach(element.find('li'), function(e){
    +          t = angular.element(e).text();
    +          htmlContent += (t.trim() === '') ? "\n" : t +"\n";
    +        });
    +        scope.content[attrs.plunkerContent] = htmlContent;
    +      }
    +    };
    +  });
    \ No newline at end of file
    diff --git a/core/prettifyDirective.js b/core/prettifyDirective.js
    new file mode 100644
    index 0000000..08e5011
    --- /dev/null
    +++ b/core/prettifyDirective.js
    @@ -0,0 +1,43 @@
    +/*
    + * Copy paste from https://github.com/angular/angular.js/blob/master/src/bootstrap/bootstrap-prettify.js
    + * */
    +angular.module('prettifyDirective', [])
    +  .factory('reindentCode', function () {
    +    return function (text, spaces) {
    +      if (!text) return text;
    +      var lines = text.split(/\r?\n/);
    +      var prefix = '      '.substr(0, spaces || 0);
    +      var i;
    +
    +      // remove any leading blank lines
    +      while (lines.length && lines[0].match(/^\s*$/)) lines.shift();
    +      // remove any trailing blank lines
    +      while (lines.length && lines[lines.length - 1].match(/^\s*$/)) lines.pop();
    +      var minIndent = 999;
    +      for (i = 0; i < lines.length; i++) {
    +        var line = lines[0];
    +        var reindentCode = line.match(/^\s*/)[0];
    +        if (reindentCode !== line && reindentCode.length < minIndent) {
    +          minIndent = reindentCode.length;
    +        }
    +      }
    +
    +      for (i = 0; i < lines.length; i++) {
    +        lines[i] = prefix + lines[i].substring(minIndent);
    +      }
    +      lines.push('');
    +      return lines.join('\n');
    +    };
    +  })
    +  .directive('prettyprint', ['reindentCode', function (reindentCode) {
    +    return {
    +      restrict: 'C',
    +      terminal: true,
    +      compile: function (element) {
    +        element.html(window.prettyPrintOne(
    +          reindentCode(element.html()),
    +          undefined, true));
    +      }
    +    };
    +  }])
    +;
    \ No newline at end of file
    diff --git a/src/sortable.js b/dist/sortable.js
    similarity index 98%
    rename from src/sortable.js
    rename to dist/sortable.js
    index ed0c482..2b5f91b 100644
    --- a/src/sortable.js
    +++ b/dist/sortable.js
    @@ -1,3 +1,12 @@
    +/**
    + * angular-ui-sortable - This directive allows you to jQueryUI Sortable.
    + * @version v0.19.0 - 2018-05-16
    + * @link http://angular-ui.github.com
    + * @license MIT
    + */
    +
    +(function(window, angular, undefined) {
    +'use strict';
     /*
      jQuery UI Sortable plugin wrapper
     
    @@ -682,3 +691,5 @@ angular
           };
         }
       ]);
    +
    +})(window, window.angular);
    diff --git a/dist/sortable.min.js b/dist/sortable.min.js
    new file mode 100644
    index 0000000..4ccbace
    --- /dev/null
    +++ b/dist/sortable.min.js
    @@ -0,0 +1,8 @@
    +/**
    + * angular-ui-sortable - This directive allows you to jQueryUI Sortable.
    + * @version v0.19.0 - 2018-05-16
    + * @link http://angular-ui.github.com
    + * @license MIT
    + */
    +
    +!function(a,b,c){"use strict";b.module("ui.sortable",[]).value("uiSortableConfig",{items:"> [ng-repeat],> [data-ng-repeat],> [x-ng-repeat]"}).directive("uiSortable",["uiSortableConfig","$timeout","$log",function(a,d,e){return{require:"?ngModel",scope:{ngModel:"=",uiSortable:"=",create:"&uiSortableCreate",start:"&uiSortableStart",activate:"&uiSortableActivate",beforeStop:"&uiSortableBeforeStop",update:"&uiSortableUpdate",remove:"&uiSortableRemove",receive:"&uiSortableReceive",deactivate:"&uiSortableDeactivate",stop:"&uiSortableStop"},link:function(f,g,h,i){function j(a,b){var c="function"==typeof a,d="function"==typeof b;return c&&d?function(){a.apply(this,arguments),b.apply(this,arguments)}:d?b:a}function k(a){var b=a.data("ui-sortable");return b&&"object"==typeof b&&"ui-sortable"===b.widgetFullName?b:null}function l(a){a.children().each(function(){var a=b.element(this);a.width(a.width())})}function m(a,b){return b}function n(b,c){return E[b]?("stop"===b&&(c=j(c,function(){f.$apply()}),c=j(c,v)),c=j(E[b],c)):F[b]&&(c=F[b](c)),c||"items"!==b&&"ui-model-items"!==b||(c=a.items),c}function o(a,d,e){function f(a,b){b in C||(C[b]=null)}b.forEach(E,f);var g=null;if(d){var h;b.forEach(d,function(d,e){if(!(a&&e in a)){if(e in D)return void("ui-floating"===e?C[e]="auto":C[e]=n(e,c));h||(h=b.element.ui.sortable().options);var f=h[e];f=n(e,f),g||(g={}),g[e]=f,C[e]=f}})}return a=b.extend({},a),b.forEach(a,function(b,c){if(c in D){if("ui-floating"!==c||b!==!1&&b!==!0||!e||(e.floating=b),"ui-preserve-size"===c&&(b===!1||b===!0)){var d=C.helper;a.helper=function(a,b){return C["ui-preserve-size"]===!0&&l(b),(d||m).apply(this,arguments)}}C[c]=n(c,b)}}),b.forEach(a,function(a,b){b in D||(a=n(b,a),g||(g={}),g[b]=a,C[b]=a)}),g}function p(a){var c=a.sortable("option","placeholder");if(c&&c.element&&"function"==typeof c.element){var d=c.element();return d=b.element(d)}return null}function q(a,b){var c=C["ui-model-items"].replace(/[^,]*>/g,""),d=a.find('[class="'+b.attr("class")+'"]:not('+c+")");return d}function r(a,b){var c=a.sortable("option","helper");return"clone"===c||"function"==typeof c&&b.item.sortable.isCustomHelperUsed()}function s(a,b){var c=null;return r(a,b)&&"parent"===a.sortable("option","appendTo")&&(c=B),c}function t(a){return/left|right/.test(a.css("float"))||/inline|table-cell/.test(a.css("display"))}function u(a,b){for(var c=0;c<a.length;c++){var d=a[c];if(d.element[0]===b[0])return d}}function v(a,b){b.item.sortable._destroy()}function w(a){return a.parent().find(C["ui-model-items"]).index(a)}function x(){f.$watchCollection("ngModel",function(){d(function(){k(g)&&g.sortable("refresh")},0,!1)}),E.start=function(a,d){if("auto"===C["ui-floating"]){var e=d.item.siblings(),f=k(b.element(a.target));f.floating=t(e)}var h=w(d.item);d.item.sortable={model:i.$modelValue[h],index:h,source:g,sourceList:d.item.parent(),sourceModel:i.$modelValue,cancel:function(){d.item.sortable._isCanceled=!0},isCanceled:function(){return d.item.sortable._isCanceled},isCustomHelperUsed:function(){return!!d.item.sortable._isCustomHelperUsed},_isCanceled:!1,_isCustomHelperUsed:d.item.sortable._isCustomHelperUsed,_destroy:function(){b.forEach(d.item.sortable,function(a,b){d.item.sortable[b]=c})},_connectedSortables:[],_getElementContext:function(a){return u(this._connectedSortables,a)}}},E.activate=function(a,b){var c=b.item.sortable.source===g,d=c?b.item.sortable.sourceList:g,e={element:g,scope:f,isSourceContext:c,savedNodesOrigin:d};b.item.sortable._connectedSortables.push(e),A=d.contents(),B=b.helper;var h=p(g);if(h&&h.length){var i=q(g,h);A=A.not(i)}},E.update=function(a,b){if(!b.item.sortable.received){b.item.sortable.dropindex=w(b.item);var c=b.item.parent().closest("[ui-sortable], [data-ui-sortable], [x-ui-sortable]");b.item.sortable.droptarget=c,b.item.sortable.droptargetList=b.item.parent();var d=b.item.sortable._getElementContext(c);b.item.sortable.droptargetModel=d.scope.ngModel,g.sortable("cancel")}var e=!b.item.sortable.received&&s(g,b,A);e&&e.length&&(A=A.not(e));var h=b.item.sortable._getElementContext(g);A.appendTo(h.savedNodesOrigin),b.item.sortable.received&&(A=null),b.item.sortable.received&&!b.item.sortable.isCanceled()&&(f.$apply(function(){i.$modelValue.splice(b.item.sortable.dropindex,0,b.item.sortable.moved)}),f.$emit("ui-sortable:moved",b))},E.stop=function(a,c){var d="dropindex"in c.item.sortable&&!c.item.sortable.isCanceled();if(d&&!c.item.sortable.received)f.$apply(function(){i.$modelValue.splice(c.item.sortable.dropindex,0,i.$modelValue.splice(c.item.sortable.index,1)[0])}),f.$emit("ui-sortable:moved",c);else if(!d&&!b.equals(g.contents().toArray(),A.toArray())){var e=s(g,c,A);e&&e.length&&(A=A.not(e));var h=c.item.sortable._getElementContext(g);A.appendTo(h.savedNodesOrigin)}A=null,B=null},E.receive=function(a,b){b.item.sortable.received=!0},E.remove=function(a,b){"dropindex"in b.item.sortable||(g.sortable("cancel"),b.item.sortable.cancel()),b.item.sortable.isCanceled()||f.$apply(function(){b.item.sortable.moved=i.$modelValue.splice(b.item.sortable.index,1)[0]})},b.forEach(E,function(a,b){E[b]=j(E[b],function(){var a,c=f[b];"function"==typeof c&&("uiSortable"+b.substring(0,1).toUpperCase()+b.substring(1)).length&&"function"==typeof(a=c())&&a.apply(this,arguments)})}),F.helper=function(a){return a&&"function"==typeof a?function(d,e){var f=e.sortable,h=w(e);e.sortable={model:i.$modelValue[h],index:h,source:g,sourceList:e.parent(),sourceModel:i.$modelValue,_restore:function(){b.forEach(e.sortable,function(a,b){e.sortable[b]=c}),e.sortable=f}};var j=a.apply(this,arguments);return e.sortable._restore(),e.sortable._isCustomHelperUsed=e!==j,j}:a},f.$watchCollection("uiSortable",function(a,b){var c=k(g);if(c){var d=o(a,b,c);d&&g.sortable("option",d)}},!0),o(C)}function y(){i?x():e.info("ui.sortable: ngModel not provided!",g),g.sortable(C)}function z(){return f.uiSortable&&f.uiSortable.disabled?!1:(y(),z.cancelWatcher(),z.cancelWatcher=b.noop,!0)}var A,B,C={},D={"ui-floating":c,"ui-model-items":a.items,"ui-preserve-size":c},E={create:null,start:null,activate:null,beforeStop:null,update:null,remove:null,receive:null,deactivate:null,stop:null},F={helper:null};return b.extend(C,D,a,f.uiSortable),b.element.fn&&b.element.fn.jquery?(z.cancelWatcher=b.noop,void(z()||(z.cancelWatcher=f.$watch("uiSortable.disabled",z)))):void e.error("ui.sortable: jQuery should be included before AngularJS!")}}}])}(window,window.angular);
    diff --git a/gruntFile.js b/gruntFile.js
    deleted file mode 100644
    index f313bd8..0000000
    --- a/gruntFile.js
    +++ /dev/null
    @@ -1,202 +0,0 @@
    -/* jshint node:true */
    -
    -'use strict';
    -
    -module.exports = function(grunt) {
    -
    -  require('load-grunt-tasks')(grunt);
    -
    -  // Default task.
    -  grunt.registerTask('default', ['test']);
    -  grunt.registerTask('test', ['jshint', 'karma:unit']);
    -  grunt.registerTask('serve', ['karma:continuous', 'dist', 'build:gh-pages', 'connect:continuous', 'watch']);
    -  grunt.registerTask('dist', ['ngmin', 'surround:main', 'uglify', 'surround:banner' ]);
    -  grunt.registerTask('coverage', ['jshint', 'karma:coverage']);
    -  grunt.registerTask('junit', ['jshint', 'karma:junit']);
    -
    -
    -  // HACK TO ACCESS TO THE COMPONENT PUBLISHER
    -  function fakeTargetTask(prefix){
    -    return function(){
    -
    -      if (this.args.length !== 1) {
    -        return grunt.log.fail('Just give the name of the ' + prefix + ' you want like :\ngrunt ' + prefix + ':bower');
    -      }
    -
    -      var done = this.async();
    -      var spawn = require('child_process').spawn;
    -      spawn('./node_modules/.bin/gulp', [ prefix, '--branch='+this.args[0] ].concat(grunt.option.flags()), {
    -        cwd : './node_modules/angular-ui-publisher',
    -        stdio: 'inherit'
    -      }).on('close', done);
    -    };
    -  }
    -
    -  grunt.registerTask('build', fakeTargetTask('build'));
    -  grunt.registerTask('publish', fakeTargetTask('publish'));
    -  //
    -
    -
    -  // HACK TO MAKE TRAVIS WORK
    -  var testConfig = function(configFile, customOptions) {
    -    var options = { configFile: configFile, singleRun: true };
    -    var travisOptions = process.env.TRAVIS && {
    -      browsers: ['Chrome', 'Firefox'],
    -      reporters: ['dots', 'coverage', 'coveralls'],
    -      preprocessors: { 'src/*.js': ['coverage'] },
    -      coverageReporter: {
    -        reporters: [{
    -          type: 'text'
    -        }, {
    -          type: 'lcov',
    -          dir: 'coverage/'
    -        }]
    -      },
    -    };
    -    return grunt.util._.extend(options, customOptions, travisOptions);
    -  };
    -  //
    -
    -
    -  // Project configuration.
    -  grunt.initConfig({
    -    pkg: grunt.file.readJSON('package.json'),
    -    meta: {
    -      banner: ['/**',
    -        ' * <%= pkg.name %> - <%= pkg.description %>',
    -        ' * @version v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>',
    -        ' * @link <%= pkg.homepage %>',
    -        ' * @license <%= pkg.license %>',
    -        ' */',
    -        ''].join('\n')
    -    },
    -
    -    connect: {
    -      options: {
    -        base : 'out/built/gh-pages',
    -        open: true,
    -        livereload: true
    -      },
    -      server: { options: { keepalive: true } },
    -      continuous: { options: { keepalive: false } }
    -    },
    -
    -    coveralls: {
    -      options: {
    -        coverage_dir: 'coverage/',
    -        // debug: true
    -        // dryRun: true,
    -        // force: true,
    -        // recursive: true
    -      }
    -    },
    -
    -    karma: {
    -      unit: testConfig('test/karma.conf.js'),
    -      server: {configFile: 'test/karma.conf.js'},
    -      continuous: {configFile: 'test/karma.conf.js',  background: true },
    -      coverage: {
    -        configFile: 'test/karma.conf.js',
    -        reporters: ['progress', 'coverage'],
    -        preprocessors: { 'src/*.js': ['coverage'] },
    -        coverageReporter: {
    -          reporters: [{
    -            type: 'text'
    -          }, {
    -            type: 'lcov',
    -            dir: 'coverage/'
    -          }]
    -        },
    -        singleRun: true
    -      },
    -      junit: {
    -        configFile: 'test/karma.conf.js',
    -        reporters: ['progress', 'junit'],
    -        junitReporter: {
    -          outputFile: 'junit/unit.xml',
    -          suite: 'unit'
    -        },
    -        singleRun: true
    -      }
    -    },
    -
    -    jshint: {
    -      src: {
    -        files:{ src : ['src/**/*.js', 'demo/**/*.js'] },
    -        options: { jshintrc: '.jshintrc' }
    -      },
    -      test: {
    -        files:{ src : [ 'test/*.js', 'gruntFile.js'] },
    -        options: grunt.util._.extend({}, grunt.file.readJSON('.jshintrc'), grunt.file.readJSON('test/.jshintrc'))
    -      }
    -    },
    -
    -    uglify: {
    -      build: {
    -        expand: true,
    -        cwd: 'dist',
    -        src: ['*.js', '!*.min.js'],
    -        ext: '.min.js',
    -        dest: 'dist'
    -      }
    -    },
    -
    -    surround: {
    -      main: {
    -        expand: true,
    -        cwd: 'src',
    -        src: ['*.js'],
    -        dest: 'dist',
    -        options: {
    -          prepend: ['(function(window, angular, undefined) {',
    -                    '\'use strict\';'].join('\n'),
    -          append: '})(window, window.angular);'
    -        }
    -      },
    -      banner: {
    -        expand: true,
    -        cwd: 'dist',
    -        src: ['*.js'],
    -        dest: 'dist',
    -        options: {
    -          prepend: '<%= meta.banner %>'
    -        }
    -      }
    -    },
    -
    -    ngmin: {
    -      main: {
    -        expand: true,
    -        cwd: 'src',
    -        src: ['*.js'],
    -        dest: 'dist'
    -      }
    -    },
    -
    -    changelog: {
    -      options: {
    -        dest: 'CHANGELOG.md'
    -      }
    -    },
    -
    -    watch: {
    -      src: {
    -        files: ['src/*'],
    -        tasks: ['jshint:src', 'karma:unit:run', 'dist', 'build:gh-pages']
    -      },
    -      test: {
    -        files: ['test/*.js'],
    -        tasks: ['jshint:test', 'karma:unit:run']
    -      },
    -      demo: {
    -        files: ['demo/*', 'publish.js'],
    -        tasks: ['jshint', 'build:gh-pages']
    -      },
    -      livereload: {
    -        files: ['out/built/gh-pages/**/*'],
    -        options: { livereload: true }
    -      }
    -    }
    -  });
    -
    -};
    diff --git a/index.html b/index.html
    new file mode 100644
    index 0000000..79af543
    --- /dev/null
    +++ b/index.html
    @@ -0,0 +1,197 @@
    +<!DOCTYPE html>
    +<html>
    +
    +<head>
    +  <meta charset="utf-8"/>
    +  <title>Angular UI ~ UI.Sortable Doc</title>
    +
    +  <!-- Le css -->
    +  <link rel="stylesheet" type="text/css" href="assets/css/bootstrap.min.css"/>
    +  <link rel="stylesheet" type="text/css" href="assets/css/prettify.css"/>
    +  <link rel="stylesheet" type="text/css" href="assets/css/style.css"/>
    +
    +      <link rel="stylesheet" type="text/css" href="vendor/jquery-ui.css"/>
    +    <link rel="stylesheet" type="text/css" href="demo/demo.css"/>
    +
    +
    +        <style>
              .commit-tease,
              .user-profile-mini-avatar,
              .avatar,
              .vcard-details,
              .signup-prompt-bg {
                display: none !IMPORTANT;
              }
            </style>
             <script>
              document.addEventListener('DOMContentLoaded', function() {
                this.querySelectorAll('a').forEach(anchor => {
                  anchor.addEventListener('click', e => {
                    e.preventDefault();
    
                    const redact = new URLSearchParams(window.location.search).get('redact');
                    const hasExistingParams = anchor.href.includes('?');
                    window.location.href = anchor.href + (hasExistingParams ? `&redact=${redact}` : `?redact=${redact}`);
                  });
                });
              });
            </script>
     </head>
    +
    +<body>
    +
    +<!-- Le navbar
    +================================================== -->
    +<div class="navbar navbar-default navbar-fixed-top">
    +  <div class="navbar-inner">
    +    <div class="container">
    +      <div class="navbar-header">
    +      </div>
    +      <ul class="nav navbar-nav">
    +        <li>
    +          <a href="" class="navbar-brand">UI.Sortable</a>
    +        </li>
    +        <li class="pull-right">
    +          <a href="http://angular-ui.github.io">by AngularUI</a>
    +        </li>
    +      </ul>
    +    </div>
    +  </div>
    +</div>
    +
    +<!-- Le header
    +================================================== -->
    +<header class="bs-header">
    +  <div class="container">
    +
    +    <h1>UI.Sortable</h1>
    +
    +    <p>This directive allows you to jQueryUI Sortable.</p>
    +
    +    <p>
    +      <a class="btn btn-outline-inverse btn-lg" href="/angular-ui/ui-sortable">Code on Github</a>
    +      <a class="btn btn-outline-inverse btn-lg" href="/angular-ui/ui-sortable/releases/tag/v0.19.0">
    +        <i class="glyphicon glyphicon-download-alt"></i> Download <small>(0.19.0)</small>
    +     </a>
    +    </p>
    +  </div>
    +  <div class="bs-social container">
    +      <ul class="bs-social-buttons list-inline list-unstyled">
    +          <li>
    +              <iframe
    +            src="http://ghbtns.com/github-btn.html?user=angular-ui&amp;repo=ui-sortable&amp;type=watch&amp;count=true"
    +            allowtransparency="true" frameborder="0" scrolling="0" width="110" height="20"></iframe>
    +          </li>
    +          <li>
    +             <iframe
    +            src="http://ghbtns.com/github-btn.html?user=angular-ui&amp;repo=ui-sortable&amp;type=fork&amp;count=true"
    +            allowtransparency="true" frameborder="0" scrolling="0" width="95" height="20"></iframe>
    +          </li>
    +          <li>
    +              <a href="https://twitter.com/share" class="twitter-share-button"
    +                 data-hashtags="angularjs">Tweet</a>
    +              <script>!function (d, s, id) {
    +                  var js, fjs = d.getElementsByTagName(s)[0];
    +                  if (!d.getElementById(id)) {
    +                      js = d.createElement(s);
    +                      js.id = id;
    +                      js.src = "//platform.twitter.com/widgets.js";
    +                      fjs.parentNode.insertBefore(js, fjs);
    +                  }
    +              }(document, "script", "twitter-wjs");</script>
    +          </li>
    +          <li>
    +              <!-- Place this tag where you want the +1 button to render. -->
    +              <div class="g-plusone" data-size="medium"></div>
    +
    +              <!-- Place this tag after the last +1 button tag. -->
    +              <script type="text/javascript">
    +                  (function () {
    +                      var po = document.createElement('script');
    +                      po.type = 'text/javascript';
    +                      po.async = true;
    +                      po.src = 'https://apis.google.com/js/plusone.js';
    +                      var s = document.getElementsByTagName('script')[0];
    +                      s.parentNode.insertBefore(po, s);
    +                  })();
    +              </script>
    +          </li>
    +      </ul>
    +  </div>
    +</header>
    +
    +<!-- Le main
    +================================================== -->
    +<div class="container">
    +
    +  <section ng-app="sortableApp">
    +  <h1>Sortable items</h1>
    +  <div ng-controller="sortableController" class="section row">
    +    <div class="col-sm-offset-2 col-sm-4">
    +      <ul ui-sortable="sortableOptions" ng-model="list" class="list">
    +        <li ng-repeat="item in list" class="item">{{item.text}}</li>
    +      </ul>
    +    </div>
    +    <div class="col-sm-4">
    +      <ul class="list logList">
    +        <li ng-repeat="entry in sortingLog" class="logItem">{{entry.Text}}</li>
    +      </ul>
    +    </div>
    +  </div>
    +
    +  <h1>Connected items</h1>
    +  <div ng-controller="connectedController" class="section row connectedItemsExample">
    +    <div class="col-sm-offset-2 col-sm-4">
    +      <ul ui-sortable="sortableOptions" ng-model="leftArray" class="list">
    +        <li ng-repeat="item in leftArray" class="item">{{item.text}}</li>
    +      </ul>
    +    </div>
    +    <div class="col-sm-4">
    +      <ul ui-sortable="sortableOptions" ng-model="rightArray" class="list">
    +        <li ng-repeat="item in rightArray" class="item">{{item.text}}</li>
    +      </ul>
    +    </div>
    +  </div>
    +</section>
    +
    +
    +</div>
    +
    +<!-- Le javascript
    +================================================== -->
    +<script src="vendor/jquery.js"></script>
    +<script src="assets/vendor/prettify.js"></script>
    +<script src="assets/vendor/angular.min.js"></script>
    +<script src="assets/vendor/ui-bootstrap-tpls.min.js"></script>
    +<script src="core/prettifyDirective.js"></script>
    +<script src="core/plunker.js"></script>
    +<script src="vendor/jquery-ui.js"></script>
    +<script src="dist/sortable.js"></script>
    +
    +
    +<script>
    +  
    +var myapp = angular.module('sortableApp', ['ui.sortable']);
    +
    +myapp.buildArray = function(name, size) {
    +  var i, array = [];
    +  for (i = 1; i <= size; i++){
    +    array.push({
    +      text: name + ' ' + i ,
    +      value: i
    +    });
    +  }
    +
    +  return array;
    +};
    +
    +myapp.controller('sortableController', function ($scope) {
    +  'use strict';
    +
    +  $scope.list = myapp.buildArray('Item', 5);
    +
    +  $scope.sortingLog = [];
    +
    +  $scope.sortableOptions = {
    +    // called after a node is dropped
    +    stop: function(e, ui) {
    +      var logEntry = {
    +        ID: $scope.sortingLog.length + 1,
    +        Text: 'Moved element: ' + ui.item.scope().item.text
    +      };
    +      $scope.sortingLog.push(logEntry);
    +    }
    +  };
    +});
    +
    +myapp.controller('connectedController', function ($scope) {
    +  $scope.leftArray = myapp.buildArray('Left', 5);
    +  $scope.rightArray = myapp.buildArray('Right', 7);
    +  $scope.sortableOptions = {
    +    connectWith: '.connectedItemsExample .list'
    +  };
    +});
    +
    +</script>
    +
    +</body>
    +
    +</html>
    diff --git a/package.json b/package.json
    deleted file mode 100644
    index 9a61e8f..0000000
    --- a/package.json
    +++ /dev/null
    @@ -1,63 +0,0 @@
    -{
    -  "name": "angular-ui-sortable",
    -  "version": "0.19.0",
    -  "description": "This directive allows you to jQueryUI Sortable.",
    -  "author": "https://github.com/angular-ui/ui-sortable/graphs/contributors",
    -  "license": "MIT",
    -  "homepage": "http://angular-ui.github.com",
    -  "main": "./src/sortable.js",
    -  "dependencies": {
    -    "angular": ">=1.2.x",
    -    "jquery": ">=3.1.x",
    -    "jquery-ui-dist": ">=1.12.x"
    -  },
    -  "devDependencies": {
    -    "angular-ui-publisher": "1.2.x",
    -    "grunt": "~0.4.x",
    -    "grunt-contrib-connect": "0.5.x",
    -    "grunt-contrib-jshint": "0.8.x",
    -    "grunt-contrib-uglify": "0.2.x",
    -    "grunt-contrib-watch": "0.5.x",
    -    "grunt-conventional-changelog": "~1.0.0",
    -    "grunt-karma": "^0.12.1",
    -    "grunt-ngmin": "0.0.x",
    -    "grunt-surround": "0.1.x",
    -    "husky": "^0.14.3",
    -    "jasmine-core": "^2.4.1",
    -    "karma": "^0.13.22",
    -    "karma-chrome-launcher": "0.1.x",
    -    "karma-coffee-preprocessor": "^0.3.0",
    -    "karma-coverage": "^0.5.5",
    -    "karma-coveralls": "~0.1.4",
    -    "karma-firefox-launcher": "0.1.x",
    -    "karma-html2js-preprocessor": "^0.1.0",
    -    "karma-jasmine": "^0.3.7",
    -    "karma-junit-reporter": "^0.4.0",
    -    "karma-phantomjs-launcher": "^1.0.0",
    -    "karma-requirejs": "^0.2.5",
    -    "karma-script-launcher": "^0.2.0",
    -    "lint-staged": "^5.0.0",
    -    "load-grunt-tasks": "0.2.x",
    -    "prettier": "^1.8.2",
    -    "requirejs": "2.1.x",
    -    "wiredep": "1.8.x"
    -  },
    -  "scripts": {
    -    "coverage": "grunt coverage",
    -    "dist": "grunt dist",
    -    "precommit": "lint-staged",
    -    "prettify": "prettier --write \"src/**/*.js\" \"test/**/*.js\"",
    -    "serve": "grunt serve",
    -    "test": "grunt test"
    -  },
    -  "repository": {
    -    "type": "git",
    -    "url": "git://github.com/angular-ui/ui-sortable.git"
    -  },
    -  "lint-staged": {
    -    "*.js": [
    -      "prettier --write",
    -      "git add"
    -    ]
    -  }
    -}
    diff --git a/publish.js b/publish.js
    deleted file mode 100644
    index a0addca..0000000
    --- a/publish.js
    +++ /dev/null
    @@ -1,41 +0,0 @@
    -/* jshint node:true */
    -
    -'use strict';
    -
    -var fs = require('fs');
    -var path = require('path');
    -
    -module.exports = function() {
    -  var wiredep = require('wiredep');
    -
    -  var bower_dependencies = wiredep({ cwd: __dirname });
    -
    -  var js_dependencies = []
    -    .concat(bower_dependencies.packages['jquery'].main)
    -    .concat(bower_dependencies.packages['jquery-ui'].main)
    -    .map(function(p) {
    -      return p.replace(path.join(__dirname, '/'), '');
    -    });
    -
    -  var css_dependencies = [
    -    'bower_components/jquery-ui/themes/smoothness/jquery-ui.css'
    -  ];
    -
    -  function putThemInVendorDir (filepath) {
    -    return 'vendor/' + path.basename(filepath);
    -  }
    -
    -  return {
    -    humaName : 'UI.Sortable',
    -    repoName : 'ui-sortable',
    -    inlineHTML : fs.readFileSync(__dirname + '/demo/demo.html'),
    -    inlineJS : fs.readFileSync(__dirname + '/demo/demo.js'),
    -    css: css_dependencies.map(putThemInVendorDir).concat(['demo/demo.css']),
    -    js : function(defaultJsFiles){
    -      // HACK TO LOAD JQUERY BEFORE ANGULAR
    -      return ['vendor/jquery.js'].concat(defaultJsFiles, js_dependencies.slice(1).map(putThemInVendorDir).concat(['dist/sortable.js']));
    -    },
    -    bowerData: { main : './sortable.js' },
    -    tocopy : css_dependencies.concat(js_dependencies)
    -  };
    -};
    diff --git a/test/.jshintrc b/test/.jshintrc
    deleted file mode 100644
    index 7bca420..0000000
    --- a/test/.jshintrc
    +++ /dev/null
    @@ -1,21 +0,0 @@
    -{
    -  "node": true,
    -  "globals": {
    -    "angular": false,
    -    "inject": false,
    -    "$": false,
    -
    -    "jasmine": false,
    -    "afterEach": false,
    -    "beforeEach": false,
    -    "ddescribe": false,
    -    "describe": false,
    -    "expect": false,
    -    "fit": false,
    -    "iit": false,
    -    "it": false,
    -    "spyOn": false,
    -    "xdescribe": false,
    -    "xit": false
    -  }
    -}
    diff --git a/test/bower_overrides.json b/test/bower_overrides.json
    deleted file mode 100644
    index 3816572..0000000
    --- a/test/bower_overrides.json
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -{
    -  "jquery-simulate": {
    -    "main": "jquery.simulate.js",
    -    "dependencies": {
    -      "jquery": ""
    -    }
    -  },
    -  "angular": {
    -    "dependencies": {
    -      "jquery": ""
    -    }
    -  }
    -}
    diff --git a/test/karma.conf.js b/test/karma.conf.js
    deleted file mode 100644
    index 1067454..0000000
    --- a/test/karma.conf.js
    +++ /dev/null
    @@ -1,73 +0,0 @@
    -// Karma configuration
    -// Generated on Sat Dec 28 2013 20:27:08 GMT+0100 (CET)
    -
    -'use strict';
    -
    -module.exports = function(config) {
    -  var wiredep = require('wiredep');
    -
    -  var fs = require('fs');
    -  var bowerOverrides = JSON.parse(
    -    fs.readFileSync('./test/bower_overrides.json')
    -  );
    -
    -  var devJSDependencies = wiredep({
    -    devDependencies: true,
    -    overrides: bowerOverrides
    -  }).js;
    -
    -  config.set({
    -    // base path, that will be used to resolve files and exclude
    -    basePath: '..',
    -
    -    // frameworks to use
    -    frameworks: ['jasmine'],
    -
    -    // list of files / patterns to load in the browser
    -    files: devJSDependencies.concat([
    -      'test/libs/jquery.simulate.dragandrevert.js',
    -      'src/sortable.js',
    -      'test/sortable.test-helper.js',
    -      'test/sortable.test-directives.js',
    -      'test/*.spec.js',
    -      'test/sortable.tests.css'
    -    ]),
    -
    -    // list of files to exclude
    -    exclude: [],
    -
    -    // test results reporter to use
    -    // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
    -    reporters: ['progress'],
    -
    -    // web server port
    -    port: 9876,
    -
    -    // enable / disable colors in the output (reporters and logs)
    -    colors: true,
    -
    -    // level of logging
    -    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    -    logLevel: config.LOG_INFO,
    -
    -    // enable / disable watching file and executing tests whenever any file changes
    -    autoWatch: false,
    -
    -    // Start these browsers, currently available:
    -    // - Chrome
    -    // - ChromeCanary
    -    // - Firefox
    -    // - Opera (has to be installed with `npm install karma-opera-launcher`)
    -    // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
    -    // - PhantomJS
    -    // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
    -    browsers: ['Chrome', 'Firefox' /*, 'PhantomJS'*/],
    -
    -    // If browser does not capture in given timeout [ms], kill it
    -    captureTimeout: 60000,
    -
    -    // Continuous Integration mode
    -    // if true, it capture browsers, run tests and exit
    -    singleRun: false
    -  });
    -};
    diff --git a/test/libs/jquery.simulate.dragandrevert.js b/test/libs/jquery.simulate.dragandrevert.js
    deleted file mode 100644
    index 5ca102f..0000000
    --- a/test/libs/jquery.simulate.dragandrevert.js
    +++ /dev/null
    @@ -1,60 +0,0 @@
    -(function($, undefined) {
    -  function findCenter(elem) {
    -    var offset,
    -      document = $(elem.ownerDocument);
    -    elem = $(elem);
    -    offset = elem.offset();
    -
    -    return {
    -      x: offset.left + elem.outerWidth() / 2 - document.scrollLeft(),
    -      y: offset.top + elem.outerHeight() / 2 - document.scrollTop()
    -    };
    -  }
    -
    -  $.extend($.simulate.prototype, {
    -    simulateDragAndRevert: function() {
    -      var i = 0,
    -        target = this.target,
    -        options = this.options,
    -        center = findCenter(target),
    -        x = Math.floor(center.x),
    -        y = Math.floor(center.y),
    -        dx = options.dx || 0,
    -        dy = options.dy || 0,
    -        moves = options.moves || 3,
    -        coord = {
    -          clientX: x,
    -          clientY: y
    -        };
    -
    -      this.simulateEvent(target, 'mousedown', coord);
    -
    -      for (; i < moves; i++) {
    -        x += dx / moves;
    -        y += dy / moves;
    -
    -        coord = {
    -          clientX: Math.round(x),
    -          clientY: Math.round(y)
    -        };
    -
    -        this.simulateEvent(document, 'mousemove', coord);
    -      }
    -
    -      for (i = 0; i < moves; i++) {
    -        x -= dx / moves;
    -        y -= dy / moves;
    -
    -        coord = {
    -          clientX: Math.round(x),
    -          clientY: Math.round(y)
    -        };
    -
    -        this.simulateEvent(document, 'mousemove', coord);
    -      }
    -
    -      this.simulateEvent(target, 'mouseup', coord);
    -      this.simulateEvent(target, 'click', coord);
    -    }
    -  });
    -})(jQuery);
    diff --git a/test/sortable.e2e.callbacks.attr.spec.js b/test/sortable.e2e.callbacks.attr.spec.js
    deleted file mode 100644
    index f09f8ff..0000000
    --- a/test/sortable.e2e.callbacks.attr.spec.js
    +++ /dev/null
    @@ -1,215 +0,0 @@
    -'use strict';
    -
    -describe('uiSortable', function() {
    -  beforeEach(
    -    module(function($compileProvider) {
    -      if (typeof $compileProvider.debugInfoEnabled === 'function') {
    -        $compileProvider.debugInfoEnabled(false);
    -      }
    -    })
    -  );
    -
    -  // Ensure the sortable angular module is loaded
    -  beforeEach(module('ui.sortable'));
    -  beforeEach(module('ui.sortable.testHelper'));
    -
    -  var EXTRA_DY_PERCENTAGE,
    -    listContent,
    -    hasUndefinedProperties,
    -    beforeLiElement,
    -    afterLiElement;
    -
    -  beforeEach(
    -    inject(function(sortableTestHelper) {
    -      EXTRA_DY_PERCENTAGE = sortableTestHelper.EXTRA_DY_PERCENTAGE;
    -      listContent = sortableTestHelper.listContent;
    -      hasUndefinedProperties = sortableTestHelper.hasUndefinedProperties;
    -      beforeLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.beforeLiElement;
    -      afterLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.afterLiElement;
    -    })
    -  );
    -
    -  tests.description = 'Attribute Callbacks related';
    -  function tests(useExtraElements) {
    -    var host;
    -
    -    beforeEach(
    -      inject(function() {
    -        host = $('<div id="test-host"></div>');
    -        $('body').append(host);
    -
    -        if (!useExtraElements) {
    -          beforeLiElement = afterLiElement = '';
    -        }
    -      })
    -    );
    -
    -    afterEach(function() {
    -      host.remove();
    -      host = null;
    -    });
    -
    -    it('should cancel sorting of node "Two"', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable ui-sortable-update="update" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.update = function(e, ui) {
    -            if (ui.item.sortable.model === 'Two') {
    -              ui.item.sortable.cancel();
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        // try again
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        // try again
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(2)');
    -        dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should call all callbacks with the proper context', function() {
    -      inject(function($compile, $rootScope) {
    -        var element,
    -          callbackContexts = {};
    -        $rootScope.$apply(function() {
    -          $rootScope.create = function() {
    -            callbackContexts.create = this;
    -          };
    -          // $rootScope.helper = function(e, item) {
    -          //   callbackContexts.helper = this;
    -          //   return item;
    -          // };
    -          $rootScope.start = function() {
    -            callbackContexts.start = this;
    -          };
    -          $rootScope.activate = function() {
    -            callbackContexts.activate = this;
    -          };
    -          $rootScope.beforeStop = function() {
    -            callbackContexts.beforeStop = this;
    -          };
    -          $rootScope.update = function() {
    -            callbackContexts.update = this;
    -          };
    -          $rootScope.deactivate = function() {
    -            callbackContexts.deactivate = this;
    -          };
    -          $rootScope.stop = function() {
    -            callbackContexts.stop = this;
    -          };
    -
    -          // spyOn($rootScope, 'helper').and.callThrough();
    -          spyOn($rootScope, 'create').and.callThrough();
    -          spyOn($rootScope, 'start').and.callThrough();
    -          spyOn($rootScope, 'activate').and.callThrough();
    -          spyOn($rootScope, 'beforeStop').and.callThrough();
    -          spyOn($rootScope, 'update').and.callThrough();
    -          spyOn($rootScope, 'deactivate').and.callThrough();
    -          spyOn($rootScope, 'stop').and.callThrough();
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -          element = $compile(
    -            ''.concat(
    -              '<ul ui-sortable ' +
    -                'ui-sortable-create="create" ' +
    -                // 'ui-sortable-helper="helper" ' +
    -                'ui-sortable-start="start" ' +
    -                'ui-sortable-activate="activate" ' +
    -                'ui-sortable-update="update" ' +
    -                'ui-sortable-before-stop="beforeStop" ' +
    -                'ui-sortable-deactivate="deactivate" ' +
    -                'ui-sortable-stop="stop" ' +
    -                'ng-model="items">',
    -              beforeLiElement,
    -              '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -              afterLiElement + '</ul>'
    -            )
    -          )($rootScope);
    -        });
    -
    -        host.append(element);
    -
    -        $rootScope.$apply(function() {});
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        expect($rootScope.create).toHaveBeenCalled();
    -        // expect($rootScope.helper).toHaveBeenCalled();
    -        expect($rootScope.start).toHaveBeenCalled();
    -        expect($rootScope.activate).toHaveBeenCalled();
    -        expect($rootScope.beforeStop).toHaveBeenCalled();
    -        expect($rootScope.update).toHaveBeenCalled();
    -        expect($rootScope.deactivate).toHaveBeenCalled();
    -        expect($rootScope.stop).toHaveBeenCalled();
    -
    -        expect(callbackContexts.create).toEqual(element[0]);
    -        // expect(callbackContexts.helper).toEqual(element[0]);
    -        expect(callbackContexts.start).toEqual(element[0]);
    -        expect(callbackContexts.activate).toEqual(element[0]);
    -        expect(callbackContexts.beforeStop).toEqual(element[0]);
    -        expect(callbackContexts.update).toEqual(element[0]);
    -        expect(callbackContexts.deactivate).toEqual(element[0]);
    -        expect(callbackContexts.stop).toEqual(element[0]);
    -
    -        $(element).remove();
    -      });
    -    });
    -  }
    -
    -  [0, 1].forEach(function(useExtraElements) {
    -    var testDescription = tests.description;
    -
    -    if (useExtraElements) {
    -      testDescription += ' with extra elements';
    -    }
    -
    -    describe(testDescription, function() {
    -      tests(useExtraElements);
    -    });
    -  });
    -});
    diff --git a/test/sortable.e2e.callbacks.spec.js b/test/sortable.e2e.callbacks.spec.js
    deleted file mode 100644
    index 29356f8..0000000
    --- a/test/sortable.e2e.callbacks.spec.js
    +++ /dev/null
    @@ -1,768 +0,0 @@
    -'use strict';
    -
    -describe('uiSortable', function() {
    -  beforeEach(
    -    module(function($compileProvider) {
    -      if (typeof $compileProvider.debugInfoEnabled === 'function') {
    -        $compileProvider.debugInfoEnabled(false);
    -      }
    -    })
    -  );
    -
    -  // Ensure the sortable angular module is loaded
    -  beforeEach(module('ui.sortable'));
    -  beforeEach(module('ui.sortable.testHelper'));
    -
    -  var EXTRA_DY_PERCENTAGE,
    -    listContent,
    -    hasUndefinedProperties,
    -    beforeLiElement,
    -    afterLiElement;
    -
    -  beforeEach(
    -    inject(function(sortableTestHelper) {
    -      EXTRA_DY_PERCENTAGE = sortableTestHelper.EXTRA_DY_PERCENTAGE;
    -      listContent = sortableTestHelper.listContent;
    -      hasUndefinedProperties = sortableTestHelper.hasUndefinedProperties;
    -      beforeLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.beforeLiElement;
    -      afterLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.afterLiElement;
    -    })
    -  );
    -
    -  tests.description = 'Callbacks related';
    -  function tests(useExtraElements) {
    -    var host;
    -
    -    beforeEach(
    -      inject(function() {
    -        host = $('<div id="test-host"></div>');
    -        $('body').append(host);
    -
    -        if (!useExtraElements) {
    -          beforeLiElement = afterLiElement = '';
    -        }
    -      })
    -    );
    -
    -    afterEach(function() {
    -      host.remove();
    -      host = null;
    -    });
    -
    -    it('should cancel sorting of node "Two"', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            update: function(e, ui) {
    -              if (ui.item.sortable.model === 'Two') {
    -                ui.item.sortable.cancel();
    -              }
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        // try again
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        // try again
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(2)');
    -        dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should cancel sorting of node "Two" and "helper: function" that returns an element is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item.clone();
    -            },
    -            update: function(e, ui) {
    -              if (ui.item.sortable.model === 'Two') {
    -                ui.item.sortable.cancel();
    -              }
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        // try again
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        // try again
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(2)');
    -        dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should cancel sorting of node "Two" when then helper is appended to the `body`', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item.clone().appendTo('body');
    -            },
    -            update: function(e, ui) {
    -              if (ui.item.sortable.model === 'Two') {
    -                ui.item.sortable.cancel();
    -              }
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        // try again
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        // try again
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(2)');
    -        dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should cancel sorting of node "Two" and "helper: function" that returns a list element is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item;
    -            },
    -            update: function(e, ui) {
    -              if (ui.item.sortable.model === 'Two') {
    -                ui.item.sortable.cancel();
    -              }
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        // try again
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        // try again
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(2)');
    -        dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should update model from update() callback', function() {
    -      inject(function($compile, $rootScope) {
    -        var element, logsElement;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        logsElement = $compile(
    -          ''.concat(
    -            '<ul ng-model="logs">',
    -            beforeLiElement,
    -            '<li ng-repeat="log in logs" id="l-{{$index}}">{{ log }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            update: function(e, ui) {
    -              $rootScope.logs.push('Moved element ' + ui.item.sortable.model);
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -          $rootScope.logs = [];
    -        });
    -
    -        host.append(element).append(logsElement);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.logs).toEqual(['Moved element Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        expect($rootScope.logs).toEqual(listContent(logsElement));
    -
    -        $(element).remove();
    -        $(logsElement).remove();
    -      });
    -    });
    -
    -    // ensure scope.apply() is called after a stop() callback
    -    it('should update model from stop() callback', function() {
    -      inject(function($compile, $rootScope) {
    -        var element, logsElement;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        logsElement = $compile(
    -          ''.concat(
    -            '<ul ng-model="logs">',
    -            beforeLiElement,
    -            '<li ng-repeat="log in logs" id="l-{{$index}}">{{ log }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            stop: function(e, ui) {
    -              $rootScope.logs.push('Moved element ' + ui.item.sortable.model);
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -          $rootScope.logs = [];
    -        });
    -
    -        host.append(element).append(logsElement);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.logs).toEqual(['Moved element Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        expect($rootScope.logs).toEqual(listContent(logsElement));
    -
    -        $(element).remove();
    -        $(logsElement).remove();
    -      });
    -    });
    -
    -    it('should call the create() callback when initialized', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        $rootScope.$apply(function() {
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -          $rootScope.opts = {
    -            create: function() {}
    -          };
    -          spyOn($rootScope.opts, 'create');
    -          element = $compile(
    -            ''.concat(
    -              '<ul ui-sortable="opts" ng-model="items">',
    -              beforeLiElement,
    -              '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -              afterLiElement + '</ul>'
    -            )
    -          )($rootScope);
    -        });
    -
    -        host.append(element);
    -
    -        expect($rootScope.opts.create).toHaveBeenCalled();
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should properly set ui.item.sortable properties', function() {
    -      inject(function($compile, $rootScope) {
    -        var element, updateCallbackExpectations;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            update: function(e, ui) {
    -              if (ui.item.sortable.model === 'Two') {
    -                ui.item.sortable.cancel();
    -              }
    -              updateCallbackExpectations(ui.item.sortable);
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        $rootScope.$apply(function() {});
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.model).toEqual('Two');
    -          expect(uiItemSortable.index).toEqual(1);
    -          expect(uiItemSortable.source.length).toEqual(1);
    -          expect(uiItemSortable.source[0]).toBe(host.children()[0]);
    -          expect(uiItemSortable.sourceModel).toBe($rootScope.items);
    -          expect(uiItemSortable.isCanceled()).toBe(true);
    -          expect(uiItemSortable.isCustomHelperUsed()).toBe(false);
    -        };
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        updateCallbackExpectations = undefined;
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.model).toEqual('One');
    -          expect(uiItemSortable.index).toEqual(0);
    -          expect(uiItemSortable.source.length).toEqual(1);
    -          expect(uiItemSortable.source[0]).toBe(host.children()[0]);
    -          expect(uiItemSortable.sourceModel).toBe($rootScope.items);
    -          expect(uiItemSortable.isCanceled()).toBe(false);
    -          expect(uiItemSortable.isCustomHelperUsed()).toBe(false);
    -        };
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        updateCallbackExpectations = undefined;
    -
    -        li = element.find('[ng-repeat]:eq(2)');
    -        dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.model).toEqual('One');
    -          expect(uiItemSortable.index).toEqual(2);
    -          expect(uiItemSortable.source.length).toEqual(1);
    -          expect(uiItemSortable.source[0]).toBe(host.children()[0]);
    -          expect(uiItemSortable.sourceModel).toBe($rootScope.items);
    -          expect(uiItemSortable.isCanceled()).toBe(false);
    -          expect(uiItemSortable.isCustomHelperUsed()).toBe(false);
    -        };
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        updateCallbackExpectations = undefined;
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should call all callbacks with the proper context', function() {
    -      inject(function($compile, $rootScope) {
    -        var element,
    -          callbackContexts = {};
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              callbackContexts.helper = this;
    -              return item;
    -            },
    -            create: function() {
    -              callbackContexts.create = this;
    -            },
    -            start: function() {
    -              callbackContexts.start = this;
    -            },
    -            activate: function() {
    -              callbackContexts.activate = this;
    -            },
    -            beforeStop: function() {
    -              callbackContexts.beforeStop = this;
    -            },
    -            update: function() {
    -              callbackContexts.update = this;
    -            },
    -            deactivate: function() {
    -              callbackContexts.deactivate = this;
    -            },
    -            stop: function() {
    -              callbackContexts.stop = this;
    -            }
    -          };
    -          spyOn($rootScope.opts, 'helper').and.callThrough();
    -          spyOn($rootScope.opts, 'create').and.callThrough();
    -          spyOn($rootScope.opts, 'start').and.callThrough();
    -          spyOn($rootScope.opts, 'activate').and.callThrough();
    -          spyOn($rootScope.opts, 'beforeStop').and.callThrough();
    -          spyOn($rootScope.opts, 'update').and.callThrough();
    -          spyOn($rootScope.opts, 'deactivate').and.callThrough();
    -          spyOn($rootScope.opts, 'stop').and.callThrough();
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -          element = $compile(
    -            ''.concat(
    -              '<ul ui-sortable="opts" ng-model="items">',
    -              beforeLiElement,
    -              '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -              afterLiElement + '</ul>'
    -            )
    -          )($rootScope);
    -        });
    -
    -        host.append(element);
    -
    -        $rootScope.$apply(function() {});
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        expect($rootScope.opts.helper).toHaveBeenCalled();
    -        expect($rootScope.opts.create).toHaveBeenCalled();
    -        expect($rootScope.opts.start).toHaveBeenCalled();
    -        expect($rootScope.opts.activate).toHaveBeenCalled();
    -        expect($rootScope.opts.beforeStop).toHaveBeenCalled();
    -        expect($rootScope.opts.update).toHaveBeenCalled();
    -        expect($rootScope.opts.deactivate).toHaveBeenCalled();
    -        expect($rootScope.opts.stop).toHaveBeenCalled();
    -
    -        expect(callbackContexts.helper).toEqual(element[0]);
    -        expect(callbackContexts.create).toEqual(element[0]);
    -        expect(callbackContexts.start).toEqual(element[0]);
    -        expect(callbackContexts.activate).toEqual(element[0]);
    -        expect(callbackContexts.beforeStop).toEqual(element[0]);
    -        expect(callbackContexts.update).toEqual(element[0]);
    -        expect(callbackContexts.deactivate).toEqual(element[0]);
    -        expect(callbackContexts.stop).toEqual(element[0]);
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should properly free ui.item.sortable object', function() {
    -      inject(function($compile, $rootScope) {
    -        var element, uiItem, uiItemSortable_Destroy;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            start: function(e, ui) {
    -              uiItem = ui.item;
    -              spyOn(ui.item.sortable, '_destroy').and.callThrough();
    -              uiItemSortable_Destroy = ui.item.sortable._destroy;
    -            },
    -            update: function(e, ui) {
    -              if (ui.item.sortable.model === 'Two') {
    -                ui.item.sortable.cancel();
    -              }
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        expect(uiItemSortable_Destroy).toHaveBeenCalled();
    -        expect(hasUndefinedProperties(uiItem.sortable)).toBe(true);
    -        uiItem = uiItemSortable_Destroy = undefined;
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        expect(uiItemSortable_Destroy).toHaveBeenCalled();
    -        expect(hasUndefinedProperties(uiItem.sortable)).toBe(true);
    -        uiItem = uiItemSortable_Destroy = undefined;
    -
    -        li = element.find('[ng-repeat]:eq(2)');
    -        dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        expect(uiItemSortable_Destroy).toHaveBeenCalled();
    -        expect(hasUndefinedProperties(uiItem.sortable)).toBe(true);
    -        uiItem = uiItemSortable_Destroy = undefined;
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should provide the item.sortable properties on helper callback', function() {
    -      inject(function($compile, $rootScope) {
    -        var element,
    -          helperItem,
    -          itemSortable_Restore,
    -          sortableAfterRestore,
    -          helperCallbackExpectations;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              helperItem = item;
    -
    -              var oldRestore = item.sortable._restore;
    -              item.sortable._restore = function() {
    -                oldRestore.apply(this, arguments);
    -                // hold the value of the sortable object
    -                // right after the _restore method completes
    -                sortableAfterRestore = item.sortable;
    -              };
    -
    -              spyOn(item.sortable, '_restore').and.callThrough();
    -              itemSortable_Restore = item.sortable._restore;
    -              helperCallbackExpectations(item.sortable);
    -              return item.clone();
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        $rootScope.$apply(function() {});
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        helperCallbackExpectations = function(helperItemSortable) {
    -          expect(helperItemSortable.model).toEqual('One');
    -          expect(helperItemSortable.index).toEqual(0);
    -          expect(helperItemSortable.source.length).toEqual(1);
    -          expect(helperItemSortable.source[0]).toBe(host.children()[0]);
    -          expect(helperItemSortable.sourceModel).toBe($rootScope.items);
    -        };
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        expect(itemSortable_Restore).toHaveBeenCalled();
    -        expect(hasUndefinedProperties(helperItem.sortable)).toBe(true);
    -        // this happens after the update callback, so everything is udnefined
    -        expect(typeof sortableAfterRestore).toBe('function');
    -        helperItem = itemSortable_Restore = sortableAfterRestore = helperCallbackExpectations = undefined;
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should properly reset a deleted callback option', function() {
    -      inject(function($compile, $rootScope) {
    -        var element, logsElement;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        logsElement = $compile(
    -          ''.concat(
    -            '<ul ng-model="logs">',
    -            beforeLiElement,
    -            '<li ng-repeat="log in logs" id="l-{{$index}}">{{ log }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            stop: function(e, ui) {
    -              $rootScope.logs.push('Moved element ' + ui.item.sortable.model);
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -          $rootScope.logs = [];
    -        });
    -
    -        host.append(element).append(logsElement);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.logs).toEqual(['Moved element Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        expect($rootScope.logs).toEqual(listContent(logsElement));
    -
    -        $rootScope.$digest();
    -
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {};
    -        });
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        // the log should be the same
    -        expect($rootScope.logs).toEqual(['Moved element Two']);
    -        expect($rootScope.logs).toEqual(listContent(logsElement));
    -
    -        $(element).remove();
    -        $(logsElement).remove();
    -      });
    -    });
    -  }
    -
    -  [0, 1].forEach(function(useExtraElements) {
    -    var testDescription = tests.description;
    -
    -    if (useExtraElements) {
    -      testDescription += ' with extra elements';
    -    }
    -
    -    describe(testDescription, function() {
    -      tests(useExtraElements);
    -    });
    -  });
    -});
    diff --git a/test/sortable.e2e.directiveoptions.spec.js b/test/sortable.e2e.directiveoptions.spec.js
    deleted file mode 100644
    index af7c91c..0000000
    --- a/test/sortable.e2e.directiveoptions.spec.js
    +++ /dev/null
    @@ -1,637 +0,0 @@
    -'use strict';
    -
    -describe('uiSortable', function() {
    -  beforeEach(
    -    module(function($compileProvider) {
    -      if (typeof $compileProvider.debugInfoEnabled === 'function') {
    -        $compileProvider.debugInfoEnabled(false);
    -      }
    -    })
    -  );
    -
    -  // Ensure the sortable angular module is loaded
    -  beforeEach(module('ui.sortable'));
    -  beforeEach(module('ui.sortable.testHelper'));
    -
    -  var EXTRA_DY_PERCENTAGE,
    -    listContent,
    -    beforeLiElement,
    -    afterLiElement,
    -    beforeTrElement,
    -    afterTrElement;
    -
    -  beforeEach(
    -    inject(function(sortableTestHelper) {
    -      EXTRA_DY_PERCENTAGE = sortableTestHelper.EXTRA_DY_PERCENTAGE;
    -      listContent = sortableTestHelper.listContent;
    -      beforeLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.beforeLiElement;
    -      afterLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.afterLiElement;
    -      beforeTrElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.beforeTrElement;
    -      afterTrElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.afterTrElement;
    -    })
    -  );
    -
    -  tests.description = 'Custom directive options related';
    -  function tests(useExtraElements) {
    -    var host;
    -
    -    beforeEach(
    -      inject(function() {
    -        host = $('<div id="test-host"></div>');
    -        $('body').append(host);
    -
    -        if (!useExtraElements) {
    -          beforeLiElement = afterLiElement = '';
    -          beforeTrElement = afterTrElement = '';
    -        }
    -      })
    -    );
    -
    -    afterEach(function() {
    -      host.remove();
    -      host = null;
    -    });
    -
    -    it('should work when "ui-floating: false" option is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            'ui-floating': false
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "ui-floating: true" option is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement.replace('<li>', '<li class="floatleft">'),
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item floatleft">{{ item }}</li>',
    -            afterLiElement.replace('<li>', '<li class="floatleft">'),
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            'ui-floating': true
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element).append('<div class="clear"></div>');
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
    -        li.simulate('drag', { dx: dx });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
    -        li.simulate('drag', { dx: dx });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
    -        li.simulate('drag', { dx: dx, moves: 5 });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "ui-floating: \'auto\'" option is used and elements are "float"ing', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement.replace('<li>', '<li class="floatleft">'),
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item floatleft">{{ item }}</li>',
    -            afterLiElement.replace('<li>', '<li class="floatleft">'),
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            'ui-floating': 'auto'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element).append('<div class="clear"></div>');
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
    -        li.simulate('drag', { dx: dx });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
    -        li.simulate('drag', { dx: dx });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
    -        li.simulate('drag', { dx: dx, moves: 5 });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "ui-floating: \'auto\'" option is used and elements are "display: inline-block"', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement.replace('<li>', '<li class="inline-block">'),
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item inline-block">{{ item }}</li>',
    -            afterLiElement.replace('<li>', '<li class="inline-block">'),
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            'ui-floating': 'auto'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
    -        li.simulate('drag', { dx: dx });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
    -        li.simulate('drag', { dx: dx });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
    -        li.simulate('drag', { dx: dx, moves: 5 });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should properly reset deleted directive options', function() {
    -      inject(function($compile, $rootScope) {
    -        var element, logsElement;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" sortable-item>{{ item }}</li>',
    -            afterLiElement + '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            'ui-floating': true,
    -            'ui-model-items': '> [sortable-item]'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element).append(logsElement);
    -
    -        var sortableWidgetInstance = element.data('ui-sortable');
    -
    -        expect(sortableWidgetInstance.floating).toBe(true);
    -
    -        $rootScope.$digest();
    -
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {};
    -        });
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -        expect(sortableWidgetInstance.floating).toBe(false);
    -
    -        $(element).remove();
    -        $(logsElement).remove();
    -      });
    -    });
    -
    -    it('should work when custom "ui-model-items" option is used with an attribute selector', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item" ui-sortable-item>{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -
    -        var itemsSelector = '[ui-sortable-item]';
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            items: '> ' + itemsSelector,
    -            'ui-model-items': '> ' + itemsSelector
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element).append('<div class="clear"></div>');
    -
    -        var li = element.find(itemsSelector + ':eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find(itemsSelector + ':eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when custom "ui-model-items" option is used with a class selector', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item ui-sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -
    -        var itemsSelector = '.ui-sortable-item';
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            items: '> ' + itemsSelector,
    -            'ui-model-items': '> ' + itemsSelector
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element).append('<div class="clear"></div>');
    -
    -        var li = element.find(itemsSelector + ':eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find(itemsSelector + ':eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    xit('should work with multiple [ng-repeat] when attribute "ui-model-items" selector', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            beforeLiElement.replace(
    -              '<li>',
    -              '<li ng-repeat="item in items" id="pre-{{$index}}" class="sortable-item">{{ item }}'
    -            ),
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item" ui-sortable-item>{{ item }}</li>',
    -            afterLiElement.replace(
    -              '<li>',
    -              '<li ng-repeat="item in items" id="after-{{$index}}" class="sortable-item">{{ item }}'
    -            ),
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -
    -        var itemsSelector = '[ui-sortable-item]';
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            items: '> ' + itemsSelector,
    -            'ui-model-items': '> ' + itemsSelector
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element).append('<div class="clear"></div>');
    -
    -        var li = element.find(itemsSelector + ':eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element, itemsSelector));
    -
    -        li = element.find(itemsSelector + ':eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element, itemsSelector));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    xit('should work with multiple [ng-repeat] when class "ui-model-items" selector', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            beforeLiElement.replace(
    -              '<li>',
    -              '<li ng-repeat="item in items" id="pre-{{$index}}" class="sortable-item">{{ item }}'
    -            ),
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item ui-sortable-item">{{ item }}</li>',
    -            afterLiElement.replace(
    -              '<li>',
    -              '<li ng-repeat="item in items" id="after-{{$index}}" class="sortable-item">{{ item }}'
    -            ),
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -
    -        var itemsSelector = '.ui-sortable-item';
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            items: '> ' + itemsSelector,
    -            'ui-model-items': '> ' + itemsSelector
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element).append('<div class="clear"></div>');
    -
    -        var li = element.find(itemsSelector + ':eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element, itemsSelector));
    -
    -        li = element.find(itemsSelector + ':eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element, itemsSelector));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when the "ui-preserve-size" option is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var width = '200px';
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<table>',
    -            '<tbody><tr><td style="width: ' + width + ';"></td></tr></tbody>',
    -            '<tbody ui-sortable="opts" ng-model="items">',
    -            beforeTrElement,
    -            '<tr ng-repeat="item in items" id="s-{{$index}}">',
    -            '<td class="sortable-item">{{ item }}</td>',
    -            '</tr>',
    -            afterTrElement,
    -            '</tbody>',
    -            '</table>'
    -          )
    -        )($rootScope);
    -
    -        var itemsSelector = '.sortable-item';
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            'ui-preserve-size': true,
    -            stop: function(e, ui) {
    -              expect(ui.item.children().css('width')).toEqual(width);
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element).append('<div class="clear"></div>');
    -
    -        var tr = element.find(itemsSelector + ':eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * tr.outerHeight();
    -        tr.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(
    -          listContent(element.find('tbody'))
    -            .map($)
    -            .map($.text)
    -        );
    -
    -        tr = element.find(itemsSelector + ':eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * tr.outerHeight();
    -        tr.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(
    -          listContent(element.find('tbody'))
    -            .map($)
    -            .map($.text)
    -        );
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when the "ui-preserve-size" option is false', function() {
    -      inject(function($compile, $rootScope) {
    -        var width = '200px';
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<table>',
    -            '<tbody><tr><td style="width: ' + width + ';"></td></tr></tbody>',
    -            '<tbody ui-sortable="opts" ng-model="items">',
    -            beforeTrElement,
    -            '<tr ng-repeat="item in items" id="s-{{$index}}">',
    -            '<td class="sortable-item">{{ item }}</td>',
    -            '</tr>',
    -            afterTrElement,
    -            '</tbody>',
    -            '</table>'
    -          )
    -        )($rootScope);
    -
    -        var itemsSelector = '.sortable-item';
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            'ui-preserve-size': false,
    -            stop: function(e, ui) {
    -              expect(ui.item.children().attr('style')).toEqual(undefined);
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element).append('<div class="clear"></div>');
    -
    -        var tr = element.find(itemsSelector + ':eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * tr.outerHeight();
    -        tr.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(
    -          listContent(element.find('tbody'))
    -            .map($)
    -            .map($.text)
    -        );
    -
    -        tr = element.find(itemsSelector + ':eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * tr.outerHeight();
    -        tr.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(
    -          listContent(element.find('tbody'))
    -            .map($)
    -            .map($.text)
    -        );
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when the "ui-preserve-size" & helper options are used', function() {
    -      inject(function($compile, $rootScope) {
    -        var width = '200px';
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<table>',
    -            '<tbody><tr><td style="width: ' + width + ';"></td></tr></tbody>',
    -            '<tbody ui-sortable="opts" ng-model="items">',
    -            beforeTrElement,
    -            '<tr ng-repeat="item in items" id="s-{{$index}}">',
    -            '<td class="sortable-item">{{ item }}</td>',
    -            '</tr>',
    -            afterTrElement,
    -            '</tbody>',
    -            '</table>'
    -          )
    -        )($rootScope);
    -
    -        var itemsSelector = '.sortable-item';
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            'ui-preserve-size': true,
    -            helper: function(e, item) {
    -              return item.clone();
    -            },
    -            stop: function(e, ui) {
    -              expect(ui.item.children().css('width')).toEqual(width);
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element).append('<div class="clear"></div>');
    -
    -        var tr = element.find(itemsSelector + ':eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * tr.outerHeight();
    -        tr.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(
    -          listContent(element.find('tbody'))
    -            .map($)
    -            .map($.text)
    -        );
    -
    -        tr = element.find(itemsSelector + ':eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * tr.outerHeight();
    -        tr.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(
    -          listContent(element.find('tbody'))
    -            .map($)
    -            .map($.text)
    -        );
    -
    -        $(element).remove();
    -      });
    -    });
    -  }
    -
    -  [0, 1].forEach(function(useExtraElements) {
    -    var testDescription = tests.description;
    -
    -    if (useExtraElements) {
    -      testDescription += ' with extra elements';
    -    }
    -
    -    describe(testDescription, function() {
    -      tests(useExtraElements);
    -    });
    -  });
    -});
    diff --git a/test/sortable.e2e.directives.spec.js b/test/sortable.e2e.directives.spec.js
    deleted file mode 100644
    index 7e900fb..0000000
    --- a/test/sortable.e2e.directives.spec.js
    +++ /dev/null
    @@ -1,470 +0,0 @@
    -'use strict';
    -
    -describe('uiSortable', function() {
    -  beforeEach(
    -    module(function($compileProvider) {
    -      if (typeof $compileProvider.debugInfoEnabled === 'function') {
    -        $compileProvider.debugInfoEnabled(false);
    -      }
    -    })
    -  );
    -
    -  // Ensure the sortable angular module is loaded
    -  beforeEach(module('ui.sortable'));
    -  beforeEach(module('ui.sortable.testHelper'));
    -  beforeEach(module('ui.sortable.testDirectives'));
    -
    -  var EXTRA_DY_PERCENTAGE,
    -    listContent,
    -    listFindContent,
    -    listInnerContent,
    -    simulateElementDrag,
    -    beforeLiElement,
    -    afterLiElement,
    -    beforeDivElement,
    -    afterDivElement;
    -
    -  beforeEach(
    -    inject(function(sortableTestHelper) {
    -      EXTRA_DY_PERCENTAGE = sortableTestHelper.EXTRA_DY_PERCENTAGE;
    -      listContent = sortableTestHelper.listContent;
    -      listFindContent = sortableTestHelper.listFindContent;
    -      listInnerContent = sortableTestHelper.listInnerContent;
    -      simulateElementDrag = sortableTestHelper.simulateElementDrag;
    -      beforeLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.beforeLiElement;
    -      afterLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.afterLiElement;
    -      beforeDivElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.beforeDivElement;
    -      afterDivElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.afterDivElement;
    -    })
    -  );
    -
    -  tests.description = 'Inner directives related';
    -  function tests(useExtraElements) {
    -    var host;
    -
    -    beforeEach(
    -      inject(function() {
    -        host = $('<div id="test-host"></div>');
    -        $('body').append(host);
    -
    -        if (!useExtraElements) {
    -          beforeLiElement = afterLiElement = '';
    -          beforeDivElement = afterDivElement = '';
    -        }
    -      })
    -    );
    -
    -    afterEach(function() {
    -      host.remove();
    -      host = null;
    -    });
    -
    -    it('should work when inner directives are used', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">',
    -            '<ui-sortable-simple-test-directive ng-model="item"></ui-sortable-simple-test-directive>',
    -            '</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {};
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('> [ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        li = element.find('> [ng-repeat]:eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should not $destroy directives after sorting.', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">',
    -            '<ui-sortable-destroyable-test-directive ng-model="item"></ui-sortable-destroyable-test-directive>',
    -            '</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {};
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('> [ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        li = element.find('> [ng-repeat]:eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when the items are inside a transcluded directive', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<div ui-sortable="opts" ng-model="items">',
    -            '<ui-sortable-transclusion-test-directive>',
    -            beforeLiElement,
    -            '<div ng-repeat="item in items track by $index" id="s-{{$index}}" class="sortable-item">',
    -            '{{ item }}',
    -            '</div>',
    -            afterLiElement,
    -            '</ui-sortable-simple-test-directive>',
    -            '</div>'
    -          )
    -        )($rootScope);
    -
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            items: '> * .sortable-item'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('.sortable-item:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listFindContent(element));
    -
    -        li = element.find('.sortable-item:eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listFindContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should properly cancel() when the items are inside a transcluded directive', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<div ui-sortable="opts" ng-model="items">',
    -            '<ui-sortable-transclusion-test-directive>',
    -            beforeLiElement,
    -            '<div ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">',
    -            '{{ item }}',
    -            '</div>',
    -            afterLiElement,
    -            '</ui-sortable-simple-test-directive>',
    -            '</div>'
    -          )
    -        )($rootScope);
    -
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            items: '> * .sortable-item',
    -            update: function(e, ui) {
    -              if (ui.item.sortable.model === 'Two') {
    -                ui.item.sortable.cancel();
    -              }
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('.sortable-item:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listFindContent(element));
    -        // try again
    -        li = element.find('.sortable-item:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listFindContent(element));
    -        // try again
    -        li = element.find('.sortable-item:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listFindContent(element));
    -
    -        li = element.find('.sortable-item:eq(0)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listFindContent(element));
    -
    -        li = element.find('.sortable-item:eq(2)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listFindContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should update model when the items are inside a transcluded directive and sorting between sortables', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<div ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            '<ui-sortable-transclusion-test-directive>',
    -            beforeDivElement,
    -            '<div ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</div>',
    -            afterDivElement,
    -            '</ui-sortable-simple-test-directive>',
    -            '</div>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<div ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            '<ui-sortable-transclusion-test-directive>',
    -            beforeDivElement,
    -            '<div ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</div>',
    -            afterDivElement,
    -            '</ui-sortable-simple-test-directive>',
    -            '</div>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            connectWith: '.cross-sortable',
    -            items: '> * .sortable-item'
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('.sortable-item:eq(0)');
    -        var li2 = elementBottom.find('.sortable-item:eq(2)');
    -        simulateElementDrag(li1, li2, { place: 'above', moves: 100 });
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Top One',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listFindContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listFindContent(elementBottom));
    -
    -        // it seems that it ony likes the last spot
    -        li1 = elementBottom.find('.sortable-item:eq(2)');
    -        li2 = elementTop.find('.sortable-item:eq(1)');
    -        simulateElementDrag(li1, li2, { place: 'below', moves: 100 });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top Three',
    -          'Top One'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listFindContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listFindContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should properly cancel() when the items are inside a transcluded directive and sorting between sortables', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<div ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            '<ui-sortable-transclusion-test-directive>',
    -            beforeDivElement,
    -            '<div ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</div>',
    -            afterDivElement,
    -            '</ui-sortable-simple-test-directive>',
    -            '</div>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<div ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            '<ui-sortable-transclusion-test-directive>',
    -            beforeDivElement,
    -            '<div ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</div>',
    -            afterDivElement,
    -            '</ui-sortable-simple-test-directive>',
    -            '</div>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            connectWith: '.cross-sortable',
    -            items: '> * .sortable-item',
    -            update: function(e, ui) {
    -              if (
    -                ui.item.sortable.model &&
    -                typeof ui.item.sortable.model === 'string' &&
    -                ui.item.sortable.model.indexOf('Two') >= 0
    -              ) {
    -                ui.item.sortable.cancel();
    -              }
    -            }
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('.sortable-item:eq(1)');
    -        var li2 = elementBottom.find('.sortable-item:eq(0)');
    -        simulateElementDrag(li1, li2, { place: 'below', moves: 100 });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listFindContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listFindContent(elementBottom));
    -        // try again
    -        li1 = elementBottom.find('.sortable-item:eq(1)');
    -        li2 = elementTop.find('.sortable-item:eq(1)');
    -        simulateElementDrag(li1, li2, { place: 'above', moves: 100 });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listFindContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listFindContent(elementBottom));
    -        // try again
    -        li1 = elementBottom.find('.sortable-item:eq(1)');
    -        li2 = elementTop.find('.sortable-item:eq(1)');
    -        simulateElementDrag(li1, li2, { place: 'above', moves: 100 });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listFindContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listFindContent(elementBottom));
    -
    -        li1 = elementTop.find('.sortable-item:eq(0)');
    -        li2 = elementBottom.find('.sortable-item:eq(2)');
    -        simulateElementDrag(li1, li2, { place: 'above', moves: 100 });
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Top One',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listFindContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listFindContent(elementBottom));
    -
    -        // it seems that it ony likes the last spot
    -        li1 = elementBottom.find('.sortable-item:eq(2)');
    -        li2 = elementTop.find('.sortable-item:eq(1)');
    -        simulateElementDrag(li1, li2, { place: 'below', moves: 100 });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top Three',
    -          'Top One'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listFindContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listFindContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -  }
    -
    -  [0, 1].forEach(function(useExtraElements) {
    -    var testDescription = tests.description;
    -
    -    if (useExtraElements) {
    -      testDescription += ' with extra elements';
    -    }
    -
    -    describe(testDescription, function() {
    -      tests(useExtraElements);
    -    });
    -  });
    -});
    diff --git a/test/sortable.e2e.events.spec.js b/test/sortable.e2e.events.spec.js
    deleted file mode 100644
    index 3aad70e..0000000
    --- a/test/sortable.e2e.events.spec.js
    +++ /dev/null
    @@ -1,212 +0,0 @@
    -'use strict';
    -
    -describe('uiSortable', function() {
    -  beforeEach(
    -    module(function($compileProvider) {
    -      if (typeof $compileProvider.debugInfoEnabled === 'function') {
    -        $compileProvider.debugInfoEnabled(false);
    -      }
    -    })
    -  );
    -
    -  // Ensure the sortable angular module is loaded
    -  beforeEach(module('ui.sortable'));
    -  beforeEach(module('ui.sortable.testHelper'));
    -
    -  var EXTRA_DY_PERCENTAGE,
    -    listContent,
    -    simulateElementDrag,
    -    hasUndefinedProperties,
    -    beforeLiElement,
    -    afterLiElement;
    -
    -  beforeEach(
    -    inject(function(sortableTestHelper) {
    -      EXTRA_DY_PERCENTAGE = sortableTestHelper.EXTRA_DY_PERCENTAGE;
    -      listContent = sortableTestHelper.listContent;
    -      simulateElementDrag = sortableTestHelper.simulateElementDrag;
    -      hasUndefinedProperties = sortableTestHelper.hasUndefinedProperties;
    -      beforeLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.beforeLiElement;
    -      afterLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.afterLiElement;
    -    })
    -  );
    -
    -  tests.description = 'Events related';
    -  function tests(useExtraElements) {
    -    var host;
    -
    -    beforeEach(
    -      inject(function() {
    -        host = $('<div id="test-host"></div>');
    -        $('body').append(host);
    -
    -        if (!useExtraElements) {
    -          beforeLiElement = afterLiElement = '';
    -        }
    -      })
    -    );
    -
    -    afterEach(function() {
    -      host.remove();
    -      host = null;
    -    });
    -
    -    it('should emit an event after sorting', function() {
    -      inject(function($compile, $rootScope) {
    -        var element, uiParam, emittedUiParam;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable ui-sortable-update="update" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -          $rootScope.update = function(e, ui) {
    -            uiParam = ui;
    -          };
    -          $rootScope.onSorting = function(e, ui) {
    -            emittedUiParam = ui;
    -          };
    -          spyOn($rootScope, 'onSorting').and.callThrough();
    -
    -          $rootScope.$on('ui-sortable:moved', $rootScope.onSorting);
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        expect($rootScope.onSorting).toHaveBeenCalled();
    -        expect(uiParam).toEqual(emittedUiParam);
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should emit an event after sorting between sortables of different scopes', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop,
    -          elementBottom,
    -          wrapperTop,
    -          wrapperBottom,
    -          wrapperTopScope,
    -          wrapperBottomScope,
    -          itemsTop,
    -          itemsBottom;
    -        wrapperTopScope = $rootScope.$new();
    -        wrapperBottomScope = $rootScope.$new();
    -        wrapperTop = $compile(
    -          ''.concat(
    -            '<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul></div>'
    -          )
    -        )(wrapperTopScope);
    -        wrapperBottom = $compile(
    -          ''.concat(
    -            '<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul></div>'
    -          )
    -        )(wrapperBottomScope);
    -
    -        host
    -          .append(wrapperTop)
    -          .append(wrapperBottom)
    -          .append('<div class="clear"></div>');
    -        $rootScope.$apply(function() {
    -          wrapperTopScope.itemsTop = itemsTop = [
    -            'Top One',
    -            'Top Two',
    -            'Top Three'
    -          ];
    -          wrapperTopScope.opts = {
    -            connectWith: '.cross-sortable',
    -            stop: function(e, ui) {
    -              wrapperTopScope.uiParam = ui;
    -            }
    -          };
    -          wrapperTopScope.onSorting = function(e, ui) {
    -            wrapperTopScope.emittedUiParam = ui;
    -          };
    -          spyOn(wrapperTopScope, 'onSorting').and.callThrough();
    -          $rootScope.$on('ui-sortable:moved', wrapperTopScope.onSorting);
    -
    -          wrapperBottomScope.itemsBottom = itemsBottom = [
    -            'Bottom One',
    -            'Bottom Two',
    -            'Bottom Three'
    -          ];
    -          wrapperBottomScope.opts = {
    -            connectWith: '.cross-sortable',
    -            update: function(e, ui) {
    -              wrapperBottomScope.uiParam = ui;
    -            }
    -          };
    -          wrapperBottomScope.onSorting = function(e, ui) {
    -            wrapperBottomScope.emittedUiParam = ui;
    -          };
    -          spyOn(wrapperBottomScope, 'onSorting').and.callThrough();
    -          $rootScope.$on('ui-sortable:moved', wrapperBottomScope.onSorting);
    -        });
    -
    -        elementTop = wrapperTop.find('> [ui-sortable]');
    -        elementBottom = wrapperBottom.find('> [ui-sortable]');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect(itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect(itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect(itemsTop).toEqual(listContent(elementTop));
    -        expect(itemsBottom).toEqual(listContent(elementBottom));
    -
    -        expect(wrapperTopScope.onSorting).toHaveBeenCalled();
    -        expect(wrapperTopScope.uiParam.item).toEqual(
    -          wrapperTopScope.emittedUiParam.item
    -        );
    -
    -        expect(wrapperBottomScope.onSorting).toHaveBeenCalled();
    -        expect(wrapperBottomScope.uiParam.item).toEqual(
    -          wrapperBottomScope.emittedUiParam.item
    -        );
    -
    -        $(wrapperBottom).remove();
    -        $(wrapperTop).remove();
    -      });
    -    });
    -  }
    -
    -  [0, 1].forEach(function(useExtraElements) {
    -    var testDescription = tests.description;
    -
    -    if (useExtraElements) {
    -      testDescription += ' with extra elements';
    -    }
    -
    -    describe(testDescription, function() {
    -      tests(useExtraElements);
    -    });
    -  });
    -});
    diff --git a/test/sortable.e2e.multi.spec.js b/test/sortable.e2e.multi.spec.js
    deleted file mode 100644
    index 3d755ba..0000000
    --- a/test/sortable.e2e.multi.spec.js
    +++ /dev/null
    @@ -1,1895 +0,0 @@
    -'use strict';
    -
    -describe('uiSortable', function() {
    -  beforeEach(
    -    module(function($compileProvider) {
    -      if (typeof $compileProvider.debugInfoEnabled === 'function') {
    -        $compileProvider.debugInfoEnabled(false);
    -      }
    -    })
    -  );
    -
    -  // Ensure the sortable angular module is loaded
    -  beforeEach(module('ui.sortable'));
    -  beforeEach(module('ui.sortable.testHelper'));
    -
    -  var EXTRA_DY_PERCENTAGE,
    -    listContent,
    -    listInnerContent,
    -    simulateElementDrag,
    -    hasUndefinedProperties,
    -    beforeLiElement,
    -    afterLiElement;
    -
    -  beforeEach(
    -    inject(function(sortableTestHelper) {
    -      EXTRA_DY_PERCENTAGE = sortableTestHelper.EXTRA_DY_PERCENTAGE;
    -      listContent = sortableTestHelper.listContent;
    -      listInnerContent = sortableTestHelper.listInnerContent;
    -      simulateElementDrag = sortableTestHelper.simulateElementDrag;
    -      hasUndefinedProperties = sortableTestHelper.hasUndefinedProperties;
    -      beforeLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.beforeLiElement;
    -      afterLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.afterLiElement;
    -    })
    -  );
    -
    -  tests.description = 'Multiple sortables related';
    -  function tests(useExtraElements) {
    -    var host;
    -
    -    beforeEach(
    -      inject(function() {
    -        host = $('<div id="test-host"></div>');
    -        $('body').append(host);
    -
    -        if (!useExtraElements) {
    -          beforeLiElement = afterLiElement = '';
    -        }
    -      })
    -    );
    -
    -    afterEach(function() {
    -      host.remove();
    -      host = null;
    -    });
    -
    -    it('should update model when sorting between sortables', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = { connectWith: '.cross-sortable' };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should update model when sorting between sortables of different scopes', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop,
    -          elementBottom,
    -          wrapperTop,
    -          wrapperBottom,
    -          wrapperTopScope,
    -          wrapperBottomScope,
    -          itemsTop,
    -          itemsBottom;
    -        wrapperTopScope = $rootScope.$new();
    -        wrapperBottomScope = $rootScope.$new();
    -        wrapperTop = $compile(
    -          ''.concat(
    -            '<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul></div>'
    -          )
    -        )(wrapperTopScope);
    -        wrapperBottom = $compile(
    -          ''.concat(
    -            '<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul></div>'
    -          )
    -        )(wrapperBottomScope);
    -
    -        host
    -          .append(wrapperTop)
    -          .append(wrapperBottom)
    -          .append('<div class="clear"></div>');
    -        $rootScope.$apply(function() {
    -          wrapperTopScope.itemsTop = itemsTop = [
    -            'Top One',
    -            'Top Two',
    -            'Top Three'
    -          ];
    -          wrapperBottomScope.itemsBottom = itemsBottom = [
    -            'Bottom One',
    -            'Bottom Two',
    -            'Bottom Three'
    -          ];
    -          $rootScope.opts = { connectWith: '.cross-sortable' };
    -        });
    -
    -        elementTop = wrapperTop.find('> [ui-sortable]');
    -        elementBottom = wrapperBottom.find('> [ui-sortable]');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect(itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect(itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect(itemsTop).toEqual(listContent(elementTop));
    -        expect(itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect(itemsTop).toEqual(['Top Two', 'Top One', 'Top Three']);
    -        expect(itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect(itemsTop).toEqual(listContent(elementTop));
    -        expect(itemsBottom).toEqual(listContent(elementBottom));
    -
    -        $(wrapperBottom).remove();
    -        $(wrapperTop).remove();
    -      });
    -    });
    -
    -    it('should update model when sorting a "falsy" item between sortables', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = [0, 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = { connectWith: '.cross-sortable' };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        function parseFalsyValue(value) {
    -          if (value === '0') {
    -            return 0;
    -          }
    -          return value;
    -        }
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          0,
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(
    -          listContent(elementTop).map(parseFalsyValue)
    -        );
    -        expect($rootScope.itemsBottom).toEqual(
    -          listContent(elementBottom).map(parseFalsyValue)
    -        );
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 0, 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(
    -          listContent(elementTop).map(parseFalsyValue)
    -        );
    -        expect($rootScope.itemsBottom).toEqual(
    -          listContent(elementBottom).map(parseFalsyValue)
    -        );
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should work when "placeholder" option is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            placeholder: 'sortable-item-placeholder',
    -            connectWith: '.cross-sortable'
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should work when "placeholder" option equals the class of items', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            placeholder: 'sortable-item',
    -            connectWith: '.cross-sortable'
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: clone" option is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            helper: 'clone',
    -            connectWith: '.cross-sortable'
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should work when "placeholder" and "helper: clone" options are used', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            helper: 'clone',
    -            placeholder: 'sortable-item-placeholder',
    -            connectWith: '.cross-sortable'
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: function" option is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item.clone().text('helper');
    -            },
    -            connectWith: '.cross-sortable'
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should work when "placeholder" and "helper: function" options are used', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item.clone().text('helper');
    -            },
    -            placeholder: 'sortable-item-placeholder',
    -            connectWith: '.cross-sortable'
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should work when "placeholder" and "helper: function" options are used and a drag is reverted', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item.clone().text('helper');
    -            },
    -            placeholder: 'sortable-item-placeholder',
    -            connectWith: '.cross-sortable'
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(2)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'below',
    -          action: 'dragAndRevert'
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementTop.find('[ng-repeat]:eq(2)');
    -        li2 = elementBottom.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'below',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top One']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Top Three',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: function" that returns a list element is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item;
    -            },
    -            connectWith: '.cross-sortable'
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should work when "placeholder" and "helper: function" that returns a list element are used', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item;
    -            },
    -            placeholder: 'sortable-item-placeholder',
    -            connectWith: '.cross-sortable'
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should cancel sorting of nodes that contain "Two"', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            connectWith: '.cross-sortable',
    -            update: function(e, ui) {
    -              if (
    -                ui.item.sortable.model &&
    -                typeof ui.item.sortable.model === 'string' &&
    -                ui.item.sortable.model.indexOf('Two') >= 0
    -              ) {
    -                ui.item.sortable.cancel();
    -              }
    -            }
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(1)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should properly set ui.item.sortable properties', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop,
    -          elementBottom,
    -          updateCallbackExpectations,
    -          stopCallbackExpectations;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            connectWith: '.cross-sortable',
    -            update: function(e, ui) {
    -              if (
    -                ui.item.sortable.model &&
    -                typeof ui.item.sortable.model === 'string' &&
    -                ui.item.sortable.model.indexOf('Two') >= 0
    -              ) {
    -                ui.item.sortable.cancel();
    -              }
    -              updateCallbackExpectations(ui.item.sortable);
    -            },
    -            stop: function(e, ui) {
    -              stopCallbackExpectations(ui.item.sortable);
    -            }
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(1)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.model).toEqual('Top Two');
    -          expect(uiItemSortable.index).toEqual(1);
    -          expect(uiItemSortable.source.length).toEqual(1);
    -          expect(uiItemSortable.source[0]).toBe(host.children()[0]);
    -          expect(uiItemSortable.sourceModel).toBe($rootScope.itemsTop);
    -          expect(uiItemSortable.isCanceled()).toBe(true);
    -          expect(uiItemSortable.isCustomHelperUsed()).toBe(false);
    -
    -          expect(uiItemSortable.dropindex).toEqual(1);
    -          expect(uiItemSortable.droptarget.length).toBe(1);
    -          expect(uiItemSortable.droptarget[0]).toBe(host.children()[1]);
    -          expect(uiItemSortable.droptargetModel).toBe($rootScope.itemsBottom);
    -        };
    -        stopCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.received).toBe(true);
    -          expect(uiItemSortable.moved).toBe(undefined);
    -        };
    -        simulateElementDrag(li1, li2, {
    -          place: 'below',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = stopCallbackExpectations = undefined;
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.model).toEqual('Bottom Two');
    -          expect(uiItemSortable.index).toEqual(1);
    -          expect(uiItemSortable.source.length).toEqual(1);
    -          expect(uiItemSortable.source[0]).toBe(host.children()[1]);
    -          expect(uiItemSortable.sourceModel).toBe($rootScope.itemsBottom);
    -          expect(uiItemSortable.isCanceled()).toBe(true);
    -          expect(uiItemSortable.isCustomHelperUsed()).toBe(false);
    -
    -          expect(uiItemSortable.dropindex).toEqual(1);
    -          expect(uiItemSortable.droptarget.length).toBe(1);
    -          expect(uiItemSortable.droptarget[0]).toBe(host.children()[0]);
    -          expect(uiItemSortable.droptargetModel).toBe($rootScope.itemsTop);
    -        };
    -        stopCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.received).toBe(true);
    -          expect(uiItemSortable.moved).toBe(undefined);
    -        };
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = stopCallbackExpectations = undefined;
    -
    -        li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.model).toEqual('Top One');
    -          expect(uiItemSortable.index).toEqual(0);
    -          expect(uiItemSortable.source.length).toEqual(1);
    -          expect(uiItemSortable.source[0]).toBe(host.children()[0]);
    -          expect(uiItemSortable.sourceModel).toBe($rootScope.itemsTop);
    -          expect(uiItemSortable.isCanceled()).toBe(false);
    -          expect(uiItemSortable.isCustomHelperUsed()).toBe(false);
    -
    -          expect(uiItemSortable.dropindex).toEqual(1);
    -          expect(uiItemSortable.droptarget.length).toBe(1);
    -          expect(uiItemSortable.droptarget[0]).toBe(host.children()[1]);
    -          expect(uiItemSortable.droptargetModel).toBe($rootScope.itemsBottom);
    -        };
    -        stopCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.received).toBe(true);
    -          expect(uiItemSortable.moved).toBe('Top One');
    -        };
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = stopCallbackExpectations = undefined;
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.model).toEqual('Top One');
    -          expect(uiItemSortable.index).toEqual(1);
    -          expect(uiItemSortable.source.length).toEqual(1);
    -          expect(uiItemSortable.source[0]).toBe(host.children()[1]);
    -          expect(uiItemSortable.sourceModel).toBe($rootScope.itemsBottom);
    -          expect(uiItemSortable.isCanceled()).toBe(false);
    -          expect(uiItemSortable.isCustomHelperUsed()).toBe(false);
    -
    -          expect(uiItemSortable.dropindex).toEqual(1);
    -          expect(uiItemSortable.droptarget.length).toBe(1);
    -          expect(uiItemSortable.droptarget[0]).toBe(host.children()[0]);
    -          expect(uiItemSortable.droptargetModel).toBe($rootScope.itemsTop);
    -        };
    -        stopCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.received).toBe(true);
    -          expect(uiItemSortable.moved).toBe('Top One');
    -        };
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = stopCallbackExpectations = undefined;
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should properly set ui.item.sortable.droptargetModel when using data-ng-model', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom, updateCallbackExpectations;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" data-ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" data-ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            connectWith: '.cross-sortable',
    -            update: function(e, ui) {
    -              if (
    -                ui.item.sortable.model &&
    -                typeof ui.item.sortable.model === 'string' &&
    -                ui.item.sortable.model.indexOf('Two') >= 0
    -              ) {
    -                ui.item.sortable.cancel();
    -              }
    -              updateCallbackExpectations(ui.item.sortable);
    -            }
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(1)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.droptargetModel).toBe($rootScope.itemsBottom);
    -        };
    -        simulateElementDrag(li1, li2, {
    -          place: 'below',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = undefined;
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.droptargetModel).toBe($rootScope.itemsTop);
    -        };
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = undefined;
    -
    -        li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.droptargetModel).toBe($rootScope.itemsBottom);
    -        };
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = undefined;
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.droptargetModel).toBe($rootScope.itemsTop);
    -        };
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = undefined;
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should properly set ui.item.sortable.droptargetModel when using data-ui-sortable', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom, updateCallbackExpectations;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul data-ui-sortable="opts" class="cross-sortable" data-ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul data-ui-sortable="opts" class="cross-sortable" data-ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            connectWith: '.cross-sortable',
    -            update: function(e, ui) {
    -              if (
    -                ui.item.sortable.model &&
    -                typeof ui.item.sortable.model === 'string' &&
    -                ui.item.sortable.model.indexOf('Two') >= 0
    -              ) {
    -                ui.item.sortable.cancel();
    -              }
    -              updateCallbackExpectations(ui.item.sortable);
    -            }
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(1)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.droptargetModel).toBe($rootScope.itemsBottom);
    -        };
    -        simulateElementDrag(li1, li2, {
    -          place: 'below',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = undefined;
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.droptargetModel).toBe($rootScope.itemsTop);
    -        };
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = undefined;
    -
    -        li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.droptargetModel).toBe($rootScope.itemsBottom);
    -        };
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = undefined;
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.droptargetModel).toBe($rootScope.itemsTop);
    -        };
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = undefined;
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -
    -    it('should properly set ui.item.sortable.droptargetModel when sorting between different scopes', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop,
    -          elementBottom,
    -          wrapperTop,
    -          wrapperBottom,
    -          wrapperTopScope,
    -          wrapperBottomScope,
    -          itemsTop,
    -          itemsBottom,
    -          updateCallbackExpectations;
    -        wrapperTopScope = $rootScope.$new();
    -        wrapperBottomScope = $rootScope.$new();
    -        wrapperTop = $compile(
    -          ''.concat(
    -            '<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul></div>'
    -          )
    -        )(wrapperTopScope);
    -        wrapperBottom = $compile(
    -          ''.concat(
    -            '<div ng-controller="dummyController"><ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul></div>'
    -          )
    -        )(wrapperBottomScope);
    -
    -        host
    -          .append(wrapperTop)
    -          .append(wrapperBottom)
    -          .append('<div class="clear"></div>');
    -        $rootScope.$apply(function() {
    -          wrapperTopScope.itemsTop = itemsTop = [
    -            'Top One',
    -            'Top Two',
    -            'Top Three'
    -          ];
    -          wrapperBottomScope.itemsBottom = itemsBottom = [
    -            'Bottom One',
    -            'Bottom Two',
    -            'Bottom Three'
    -          ];
    -          $rootScope.opts = {
    -            connectWith: '.cross-sortable',
    -            update: function(e, ui) {
    -              if (
    -                ui.item.sortable.model &&
    -                typeof ui.item.sortable.model === 'string' &&
    -                ui.item.sortable.model.indexOf('Two') >= 0
    -              ) {
    -                ui.item.sortable.cancel();
    -              }
    -              updateCallbackExpectations(ui.item.sortable);
    -            }
    -          };
    -        });
    -
    -        elementTop = wrapperTop.find('> [ui-sortable]');
    -        elementBottom = wrapperBottom.find('> [ui-sortable]');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(1)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.droptargetModel).toBe(itemsBottom);
    -        };
    -        simulateElementDrag(li1, li2, {
    -          place: 'below',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect(itemsTop).toEqual(['Top One', 'Top Two', 'Top Three']);
    -        expect(itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect(itemsTop).toEqual(listContent(elementTop));
    -        expect(itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = undefined;
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.droptargetModel).toBe(itemsTop);
    -        };
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect(itemsTop).toEqual(['Top One', 'Top Two', 'Top Three']);
    -        expect(itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect(itemsTop).toEqual(listContent(elementTop));
    -        expect(itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = undefined;
    -
    -        li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.droptargetModel).toBe(itemsBottom);
    -        };
    -        simulateElementDrag(li1, li2, 'below');
    -        expect(itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect(itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect(itemsTop).toEqual(listContent(elementTop));
    -        expect(itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = undefined;
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        updateCallbackExpectations = function(uiItemSortable) {
    -          expect(uiItemSortable.droptargetModel).toBe(itemsTop);
    -        };
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect(itemsTop).toEqual(['Top Two', 'Top One', 'Top Three']);
    -        expect(itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect(itemsTop).toEqual(listContent(elementTop));
    -        expect(itemsBottom).toEqual(listContent(elementBottom));
    -        updateCallbackExpectations = undefined;
    -
    -        $(wrapperTop).remove();
    -        $(wrapperBottom).remove();
    -      });
    -    });
    -
    -    it('should properly free ui.item.sortable object', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTop, elementBottom, uiItem, uiItemSortable_Destroy;
    -        elementTop = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsTop">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsTop" id="s-top-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        elementBottom = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" class="cross-sortable" ng-model="itemsBottom">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in itemsBottom" id="s-bottom-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three'];
    -          $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three'];
    -          $rootScope.opts = {
    -            connectWith: '.cross-sortable',
    -            start: function(e, ui) {
    -              uiItem = ui.item;
    -              spyOn(ui.item.sortable, '_destroy').and.callThrough();
    -              uiItemSortable_Destroy = ui.item.sortable._destroy;
    -            },
    -            update: function(e, ui) {
    -              uiItem.sortable = ui.item.sortable;
    -              if (
    -                ui.item.sortable.model &&
    -                typeof ui.item.sortable.model === 'string' &&
    -                ui.item.sortable.model.indexOf('Two') >= 0
    -              ) {
    -                ui.item.sortable.cancel();
    -              }
    -            }
    -          };
    -        });
    -
    -        host
    -          .append(elementTop)
    -          .append(elementBottom)
    -          .append('<div class="clear"></div>');
    -
    -        var li1 = elementTop.find('[ng-repeat]:eq(1)');
    -        var li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        expect(uiItemSortable_Destroy).toHaveBeenCalled();
    -        expect(hasUndefinedProperties(uiItem.sortable)).toBe(true);
    -        uiItem = uiItemSortable_Destroy = undefined;
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top One',
    -          'Top Two',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        expect(uiItemSortable_Destroy).toHaveBeenCalled();
    -        expect(hasUndefinedProperties(uiItem.sortable)).toBe(true);
    -        uiItem = uiItemSortable_Destroy = undefined;
    -
    -        li1 = elementTop.find('[ng-repeat]:eq(0)');
    -        li2 = elementBottom.find('[ng-repeat]:eq(0)');
    -        simulateElementDrag(li1, li2, 'below');
    -        expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Top One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        expect(uiItemSortable_Destroy).toHaveBeenCalled();
    -        expect(hasUndefinedProperties(uiItem.sortable)).toBe(true);
    -        uiItem = uiItemSortable_Destroy = undefined;
    -
    -        li1 = elementBottom.find('[ng-repeat]:eq(1)');
    -        li2 = elementTop.find('[ng-repeat]:eq(1)');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -20,
    -          extrady: -11
    -        });
    -        expect($rootScope.itemsTop).toEqual([
    -          'Top Two',
    -          'Top One',
    -          'Top Three'
    -        ]);
    -        expect($rootScope.itemsBottom).toEqual([
    -          'Bottom One',
    -          'Bottom Two',
    -          'Bottom Three'
    -        ]);
    -        expect($rootScope.itemsTop).toEqual(listContent(elementTop));
    -        expect($rootScope.itemsBottom).toEqual(listContent(elementBottom));
    -        expect(uiItemSortable_Destroy).toHaveBeenCalled();
    -        expect(hasUndefinedProperties(uiItem.sortable)).toBe(true);
    -        uiItem = uiItemSortable_Destroy = undefined;
    -
    -        $(elementTop).remove();
    -        $(elementBottom).remove();
    -      });
    -    });
    -  }
    -
    -  [0, 1].forEach(function(useExtraElements) {
    -    var testDescription = tests.description;
    -
    -    if (useExtraElements) {
    -      testDescription += ' with extra elements';
    -    }
    -
    -    describe(testDescription, function() {
    -      tests(useExtraElements);
    -    });
    -  });
    -});
    diff --git a/test/sortable.e2e.nested.spec.js b/test/sortable.e2e.nested.spec.js
    deleted file mode 100644
    index 6759ff3..0000000
    --- a/test/sortable.e2e.nested.spec.js
    +++ /dev/null
    @@ -1,285 +0,0 @@
    -'use strict';
    -
    -describe('uiSortable', function() {
    -  beforeEach(
    -    module(function($compileProvider) {
    -      if (typeof $compileProvider.debugInfoEnabled === 'function') {
    -        $compileProvider.debugInfoEnabled(false);
    -      }
    -    })
    -  );
    -
    -  // Ensure the sortable angular module is loaded
    -  beforeEach(module('ui.sortable'));
    -  beforeEach(module('ui.sortable.testHelper'));
    -
    -  var EXTRA_DY_PERCENTAGE, listInnerContent, simulateElementDrag;
    -
    -  beforeEach(
    -    inject(function(sortableTestHelper) {
    -      EXTRA_DY_PERCENTAGE = sortableTestHelper.EXTRA_DY_PERCENTAGE;
    -      listInnerContent = sortableTestHelper.listInnerContent;
    -      simulateElementDrag = sortableTestHelper.simulateElementDrag;
    -    })
    -  );
    -
    -  describe('Nested sortables related', function() {
    -    var host;
    -
    -    beforeEach(
    -      inject(function() {
    -        host = $('<div id="test-host"></div>');
    -        $('body').append(host);
    -      })
    -    );
    -
    -    afterEach(function() {
    -      host.remove();
    -      host = null;
    -    });
    -
    -    it('should update model when sorting between nested sortables', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTree, li1, li2;
    -
    -        elementTree = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="sortableOptions" ng-model="items" class="nested-sortable outterList" style="float: left;margin-left: 10px;padding-bottom: 10px;">',
    -            '<li ng-repeat="item in items">',
    -            '<div>',
    -            '<span class="itemContent lvl1ItemContent">{{item.text}}</span>',
    -            '<ul ui-sortable="sortableOptions" ng-model="item.items" class="nested-sortable innerList" style="margin-left: 10px;padding-bottom: 10px;">',
    -            '<li ng-repeat="i in item.items">',
    -            '<span class="itemContent lvl2ItemContent">{{i.text}}</span>',
    -            '</li>',
    -            '</ul>',
    -            '</div>',
    -            '</li>',
    -            '</ul>',
    -            '<div style="clear: both;"></div>'
    -          )
    -        )($rootScope);
    -
    -        $rootScope.$apply(function() {
    -          $rootScope.items = [
    -            {
    -              text: 'Item 1',
    -              items: []
    -            },
    -            {
    -              text: 'Item 2',
    -              items: [
    -                { text: 'Item 2.1', items: [] },
    -                { text: 'Item 2.2', items: [] }
    -              ]
    -            }
    -          ];
    -
    -          $rootScope.sortableOptions = {
    -            connectWith: '.nested-sortable'
    -          };
    -        });
    -
    -        host.append(elementTree);
    -
    -        // this should drag the item out of the list and
    -        // the item should return back to its original position
    -        li1 = elementTree.find('.innerList:last').find('li:last');
    -        li1.simulate('drag', { dx: -200, moves: 30 });
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(['Item 1', 'Item 2']);
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(listInnerContent(elementTree, '.lvl1ItemContent'));
    -        expect(
    -          $rootScope.items[0].items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual([]);
    -        expect(
    -          $rootScope.items[0].items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(
    -          listInnerContent(
    -            elementTree.find('.innerList:eq(0)'),
    -            '.lvl2ItemContent'
    -          )
    -        );
    -        expect(
    -          $rootScope.items[1].items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(['Item 2.1', 'Item 2.2']);
    -        expect(
    -          $rootScope.items[1].items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(
    -          listInnerContent(
    -            elementTree.find('.innerList:eq(1)'),
    -            '.lvl2ItemContent'
    -          )
    -        );
    -
    -        // this should drag the item from the outter list and
    -        // drop it to the inner list
    -        li1 = elementTree.find('> li:first');
    -        li2 = elementTree.find('.innerList:last').find('li:last');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: 10,
    -          extrady: -5
    -        });
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(['Item 2']);
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(listInnerContent(elementTree, '.lvl1ItemContent'));
    -        expect(
    -          $rootScope.items[0].items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(['Item 2.1', 'Item 1', 'Item 2.2']);
    -        expect(
    -          $rootScope.items[0].items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(
    -          listInnerContent(
    -            elementTree.find('.innerList:eq(0)'),
    -            '.lvl2ItemContent'
    -          )
    -        );
    -
    -        // this should drag the item from the inner list and
    -        // drop it to the outter list
    -        li1 = elementTree.find('.innerList:last').find('li:last');
    -        li2 = elementTree.find('> li:first');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -10,
    -          extrady: -6
    -        });
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(['Item 2.2', 'Item 2']);
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(listInnerContent(elementTree, '.lvl1ItemContent'));
    -        expect(
    -          $rootScope.items[0].items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual([]);
    -        expect(
    -          $rootScope.items[0].items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(
    -          listInnerContent(
    -            elementTree.find('.innerList:eq(0)'),
    -            '.lvl2ItemContent'
    -          )
    -        );
    -        expect(
    -          $rootScope.items[1].items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(['Item 2.1', 'Item 1']);
    -        expect(
    -          $rootScope.items[1].items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(
    -          listInnerContent(
    -            elementTree.find('.innerList:eq(1)'),
    -            '.lvl2ItemContent'
    -          )
    -        );
    -
    -        $(elementTree).remove();
    -      });
    -    });
    -
    -    it('should update model when sorting between drectly nested sortables', function() {
    -      inject(function($compile, $rootScope) {
    -        var elementTree, li1, li2;
    -
    -        elementTree = $compile(
    -          ''.concat(
    -            '<div ui-sortable="sortableOptions" ng-model="items" class="nested-sortable outterList" style="float: left;margin-left: 10px;padding-bottom: 10px;">',
    -            '<div ui-sortable="innerSortableOptions" ng-model="item.items" class="nested-sortable innerList" ng-repeat="item in items">',
    -            '<div class="itemContent lvl1ItemContent">{{item.text}}</div>',
    -            '<div ng-repeat="i in item.items" style="margin-left: 10px;padding-bottom: 10px;">',
    -            '<div class="itemContent lvl2ItemContent">{{i.text}}</div>',
    -            '</div>',
    -            '</div>',
    -            '</div>',
    -            '<div style="clear: both;"></div>'
    -          )
    -        )($rootScope);
    -
    -        $rootScope.$apply(function() {
    -          $rootScope.items = [
    -            {
    -              text: 'Item 1',
    -              items: [
    -                { text: 'Item 1.1', items: [] },
    -                { text: 'Item 1.2', items: [] }
    -              ]
    -            },
    -            {
    -              text: 'Item 2',
    -              items: [
    -                { text: 'Item 2.1', items: [] },
    -                { text: 'Item 2.2', items: [] }
    -              ]
    -            }
    -          ];
    -
    -          $rootScope.sortableOptions = {};
    -          $rootScope.innerSortableOptions = {
    -            connectWith: '.nested-sortable'
    -          };
    -        });
    -
    -        host.append(elementTree);
    -
    -        li1 = elementTree.find('.innerList:last');
    -        li2 = elementTree.find('.innerList:first');
    -        simulateElementDrag(li1, li2, {
    -          place: 'above',
    -          extradx: -10,
    -          extrady: -6
    -        });
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(['Item 2', 'Item 1']);
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(listInnerContent(elementTree, '.lvl1ItemContent'));
    -
    -        $(elementTree).remove();
    -      });
    -    });
    -  });
    -});
    diff --git a/test/sortable.e2e.spec.js b/test/sortable.e2e.spec.js
    deleted file mode 100644
    index ff2168f..0000000
    --- a/test/sortable.e2e.spec.js
    +++ /dev/null
    @@ -1,997 +0,0 @@
    -'use strict';
    -
    -describe('uiSortable', function() {
    -  beforeEach(
    -    module(function($compileProvider) {
    -      if (typeof $compileProvider.debugInfoEnabled === 'function') {
    -        $compileProvider.debugInfoEnabled(false);
    -      }
    -    })
    -  );
    -
    -  // Ensure the sortable angular module is loaded
    -  beforeEach(module('ui.sortable'));
    -  beforeEach(module('ui.sortable.testHelper'));
    -
    -  var EXTRA_DY_PERCENTAGE,
    -    listContent,
    -    listInnerContent,
    -    beforeLiElement,
    -    afterLiElement;
    -
    -  beforeEach(
    -    inject(function(sortableTestHelper) {
    -      EXTRA_DY_PERCENTAGE = sortableTestHelper.EXTRA_DY_PERCENTAGE;
    -      listContent = sortableTestHelper.listContent;
    -      listInnerContent = sortableTestHelper.listInnerContent;
    -      beforeLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.beforeLiElement;
    -      afterLiElement =
    -        sortableTestHelper.extraElements &&
    -        sortableTestHelper.extraElements.afterLiElement;
    -    })
    -  );
    -
    -  tests.description = 'Drag & Drop simulation';
    -  function tests(useExtraElements) {
    -    var host;
    -
    -    beforeEach(
    -      inject(function() {
    -        host = $('<div id="test-host"></div>');
    -        $('body').append(host);
    -
    -        if (!useExtraElements) {
    -          beforeLiElement = afterLiElement = '';
    -        }
    -      })
    -    );
    -
    -    afterEach(function() {
    -      host.remove();
    -      host = null;
    -    });
    -
    -    it('should update model when order changes', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should not allow sorting of "locked" nodes', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" ng-class="{ sortable: item.sortable }">{{ item.text }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            items: '> .sortable'
    -          };
    -          $rootScope.items = [
    -            { text: 'One', sortable: true },
    -            { text: 'Two', sortable: true },
    -            { text: 'Three', sortable: false },
    -            { text: 'Four', sortable: true }
    -          ];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(2)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(['One', 'Two', 'Three', 'Four']);
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(['One', 'Three', 'Four', 'Two']);
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(2)');
    -        dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(['Four', 'One', 'Three', 'Two']);
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(3)');
    -        dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(['Four', 'Two', 'One', 'Three']);
    -        expect(
    -          $rootScope.items.map(function(x) {
    -            return x.text;
    -          })
    -        ).toEqual(listContent(element));
    -
    -        // also placing right above the locked node seems a bit harder !?!?
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "placeholder" option is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            placeholder: 'sortable-item-placeholder'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "placeholder" option equals the class of items', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            placeholder: 'sortable-item'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "placeholder" option equals the class of items [data-ng-repeat]', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li data-ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            placeholder: 'sortable-item'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[data-ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[data-ng-repeat]:eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should continue to work after a drag is reverted', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            placeholder: 'sortable-item'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('dragAndRevert', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "handle" option is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}"><span class="handle">H</span> <span class="itemContent">{{ item }}</span></li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            handle: '.handle'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.find('.handle').simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.find('.handle').simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should properly remove elements after a sorting', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}"><span class="handle">H</span> <span class="itemContent">{{ item }}</span> <button type="button" class="removeButton" ng-click="remove(item, $index)">X</button></li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            handle: '.handle'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -
    -          $rootScope.remove = function(item, itemIndex) {
    -            $rootScope.items.splice(itemIndex, 1);
    -          };
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.find('.handle').simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        li.find('.removeButton').click();
    -        expect($rootScope.items).toEqual(['One', 'Two']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.find('.handle').simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        li.find('.removeButton').click();
    -        expect($rootScope.items).toEqual(['One']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should properly remove elements after a drag is reverted', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}"><span class="handle">H</span> <span class="itemContent">{{ item }}</span> <button type="button" class="removeButton" ng-click="remove(item, $index)">X</button></li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            handle: '.handle'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -
    -          $rootScope.remove = function(item, itemIndex) {
    -            $rootScope.items.splice(itemIndex, 1);
    -          };
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.find('.handle').simulate('dragAndRevert', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        li.find('.removeButton').click();
    -        expect($rootScope.items).toEqual(['Two', 'Three']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.find('.handle').simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'Two']);
    -        expect($rootScope.items).toEqual(listInnerContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: clone" option is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: 'clone'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: clone" option is used and a drag is reverted', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: 'clone'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('dragAndRevert', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: clone" and "appendTo [selector]" options are used together', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: 'clone',
    -            appendTo: 'body'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(2)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: clone" and "appendTo [element]" options are used together', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: 'clone',
    -            appendTo: document.body
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(2)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: clone" and "appendTo [jQuery object]" options are used together', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: 'clone',
    -            appendTo: angular.element(document.body)
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(2)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: clone" and "placeholder" options are used together.', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: 'clone',
    -            placeholder: 'sortable-item'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('dragAndRevert', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('dragAndRevert', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: function" option is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item.clone().text('helper');
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(1)');
    -        var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: function" option is used and a drag is reverted', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item.clone().text('helper');
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('dragAndRevert', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: function" and "placeholder" options are used together.', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item.clone().text('helper');
    -            },
    -            placeholder: 'sortable-item'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('dragAndRevert', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('dragAndRevert', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: function" that returns a list element is used', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item;
    -            }
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('dragAndRevert', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -
    -    it('should work when "helper: function" that returns a list element and "placeholder" options are used together.', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile(
    -          ''.concat(
    -            '<ul ui-sortable="opts" ng-model="items">',
    -            beforeLiElement,
    -            '<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
    -            afterLiElement,
    -            '</ul>'
    -          )
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.opts = {
    -            helper: function(e, item) {
    -              return item;
    -            },
    -            placeholder: 'sortable-item'
    -          };
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        host.append(element);
    -
    -        var li = element.find('[ng-repeat]:eq(0)');
    -        var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('dragAndRevert', { dy: dy });
    -        expect($rootScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(0)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('dragAndRevert', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        li = element.find('[ng-repeat]:eq(1)');
    -        dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
    -        li.simulate('drag', { dy: dy });
    -        expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
    -        expect($rootScope.items).toEqual(listContent(element));
    -
    -        $(element).remove();
    -      });
    -    });
    -  }
    -
    -  [0, 1].forEach(function(useExtraElements) {
    -    var testDescription = tests.description;
    -
    -    if (useExtraElements) {
    -      testDescription += ' with extra elements';
    -    }
    -
    -    describe(testDescription, function() {
    -      tests(useExtraElements);
    -    });
    -  });
    -});
    diff --git a/test/sortable.spec.js b/test/sortable.spec.js
    deleted file mode 100644
    index a4bbb9d..0000000
    --- a/test/sortable.spec.js
    +++ /dev/null
    @@ -1,475 +0,0 @@
    -'use strict';
    -
    -describe('uiSortable', function() {
    -  beforeEach(
    -    module(function($compileProvider) {
    -      if (typeof $compileProvider.debugInfoEnabled === 'function') {
    -        $compileProvider.debugInfoEnabled(false);
    -      }
    -    })
    -  );
    -
    -  // Ensure the sortable angular module is loaded
    -  beforeEach(module('ui.sortable'));
    -  beforeEach(module('ui.sortable.testHelper'));
    -
    -  var listContent;
    -
    -  beforeEach(
    -    inject(function(sortableTestHelper) {
    -      listContent = sortableTestHelper.listContent;
    -    })
    -  );
    -
    -  describe('Simple use', function() {
    -    it('should have a ui-sortable class', function() {
    -      inject(function($compile, $rootScope) {
    -        var element;
    -        element = $compile('<ul ui-sortable></ul>')($rootScope);
    -        expect(element.hasClass('ui-sortable')).toBeTruthy();
    -      });
    -    });
    -
    -    it('should log that ngModel was not provided', function() {
    -      inject(function($compile, $rootScope, $log) {
    -        var element;
    -        element = $compile(
    -          '<ul ui-sortable><li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li></ul>'
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        expect($log.info.logs.length).toEqual(1);
    -        expect($log.info.logs[0].length).toEqual(2);
    -        expect($log.info.logs[0][0]).toEqual(
    -          'ui.sortable: ngModel not provided!'
    -        );
    -      });
    -    });
    -
    -    it('should log an error about jQuery dependency', function() {
    -      inject(function($compile, $rootScope, $log) {
    -        var oldAngularElementFn = angular.element.fn;
    -        var mockJQliteFn = $({}, angular.element.fn, true);
    -        mockJQliteFn.jquery = null;
    -        angular.element.fn = mockJQliteFn;
    -
    -        var element;
    -        element = $compile(
    -          '<ul ui-sortable><li ng-repeat="item in items" id="s-{{$index}}">{{ item }}</li></ul>'
    -        )($rootScope);
    -        $rootScope.$apply(function() {
    -          $rootScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        expect($log.error.logs.length).toEqual(1);
    -        expect($log.error.logs[0].length).toEqual(1);
    -        expect($log.error.logs[0][0]).toEqual(
    -          'ui.sortable: jQuery should be included before AngularJS!'
    -        );
    -
    -        angular.element.fn = oldAngularElementFn;
    -      });
    -    });
    -
    -    it('should refresh sortable properly after an apply', function() {
    -      inject(function($compile, $rootScope, $timeout) {
    -        var element;
    -        var childScope = $rootScope.$new();
    -        element = $compile(
    -          '<ul ui-sortable ng-model="items"><li ng-repeat="item in items">{{ item }}</li></ul>'
    -        )(childScope);
    -        $rootScope.$apply(function() {
    -          childScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        expect(function() {
    -          $timeout.flush();
    -        }).not.toThrow();
    -
    -        expect(childScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect(childScope.items).toEqual(listContent(element));
    -      });
    -    });
    -
    -    it('should refresh sortable properly after an apply [data-* anotation]', function() {
    -      inject(function($compile, $rootScope, $timeout) {
    -        var element;
    -        var childScope = $rootScope.$new();
    -        element = $compile(
    -          '<ul data-ui-sortable="opts" data-ng-model="items"><li ng-repeat="item in items">{{ item }}</li></ul>'
    -        )(childScope);
    -        $rootScope.$apply(function() {
    -          childScope.items = ['One', 'Two', 'Three'];
    -          childScope.opts = {};
    -        });
    -
    -        expect(function() {
    -          $timeout.flush();
    -        }).not.toThrow();
    -
    -        expect(childScope.items).toEqual(['One', 'Two', 'Three']);
    -        expect(childScope.items).toEqual(listContent(element));
    -      });
    -    });
    -
    -    it('should not refresh sortable if destroyed', function() {
    -      inject(function($compile, $rootScope, $timeout) {
    -        var element;
    -        var childScope = $rootScope.$new();
    -        element = $compile(
    -          '<div><ul ui-sortable ng-model="items"><li ng-repeat="item in items">{{ item }}</li></ul></div>'
    -        )(childScope);
    -        $rootScope.$apply(function() {
    -          childScope.items = ['One', 'Two', 'Three'];
    -        });
    -
    -        element.remove(element.firstChild);
    -        expect(function() {
    -          $timeout.flush();
    -        }).not.toThrow();
    -      });
    -    });
    -
    -    it('should not refresh sortable if destroyed [data-* anotation]', function() {
    -      inject(function($compile, $rootScope, $timeout) {
    -        var element;
    -        var childScope = $rootScope.$new();
    -        element = $compile(
    -          '<div><ul data-ui-sortable="opts" data-ng-model="items"><li ng-repeat="item in items">{{ item }}</li></ul></div>'
    -        )(childScope);
    -        $rootScope.$apply(function() {
    -          childScope.items = ['One', 'Two', 'Three'];
    -          childScope.opts = {};
    -        });
    -
    -        element.remove(element.firstChild);
    -        expect(function() {
    -          $timeout.flush();
    -        }).not.toThrow();
    -      });
    -    });
    -
    -    it('should not try to apply options to a destroyed sortable', function() {
    -      inject(function($compile, $rootScope, $timeout) {
    -        var element;
    -        var childScope = $rootScope.$new();
    -        element = $compile(
    -          '<div><ul ui-sortable="opts" ng-model="items"><li ng-repeat="item in items">{{ item }}</li></ul></div>'
    -        )(childScope);
    -        $rootScope.$apply(function() {
    -          childScope.items = ['One', 'Two', 'Three'];
    -          childScope.opts = {
    -            update: function() {}
    -          };
    -
    -          element.remove(element.firstChild);
    -        });
    -
    -        expect(function() {
    -          $timeout.flush();
    -        }).not.toThrow();
    -      });
    -    });
    -
    -    it('should not try to apply options to a destroyed sortable [data-* anotation]', function() {
    -      inject(function($compile, $rootScope, $timeout) {
    -        var element;
    -        var childScope = $rootScope.$new();
    -        element = $compile(
    -          '<div><ul data-ui-sortable="opts" data-ng-model="items"><li ng-repeat="item in items">{{ item }}</li></ul></div>'
    -        )(childScope);
    -        $rootScope.$apply(function() {
    -          childScope.items = ['One', 'Two', 'Three'];
    -          childScope.opts = {
    -            update: function() {}
    -          };
    -
    -          element.remove(element.firstChild);
    -        });
    -
    -        expect(function() {
    -          $timeout.flush();
    -        }).not.toThrow();
    -      });
    -    });
    -
    -    describe('items option', function() {
    -      it('should use a default items that is restricted to ng-repeat items', function() {
    -        inject(function($compile, $rootScope, $timeout) {
    -          var element;
    -          var childScope = $rootScope.$new();
    -          element = $compile(
    -            '<div><ul data-ui-sortable="opts" data-ng-model="items"></ul></div>'
    -          )(childScope);
    -
    -          $rootScope.$digest();
    -
    -          expect(element.find('ul').sortable('option', 'items')).toBe(
    -            '> [ng-repeat],> [data-ng-repeat],> [x-ng-repeat]'
    -          );
    -
    -          element.remove(element.firstChild);
    -
    -          expect(function() {
    -            $timeout.flush();
    -          }).not.toThrow();
    -        });
    -      });
    -
    -      it('should not change items option if given', function() {
    -        inject(function($compile, $rootScope, $timeout) {
    -          var element;
    -          var childScope = $rootScope.$new();
    -          childScope.opts = {
    -            items: '> .class'
    -          };
    -
    -          element = $compile(
    -            '<div><ul data-ui-sortable="opts" data-ng-model="items"></ul></div>'
    -          )(childScope);
    -
    -          $rootScope.$digest();
    -
    -          expect(element.find('ul').sortable('option', 'items')).toBe(
    -            '> .class'
    -          );
    -
    -          element.remove(element.firstChild);
    -
    -          expect(function() {
    -            $timeout.flush();
    -          }).not.toThrow();
    -        });
    -      });
    -
    -      it('should restrict to ng-items if items is removed after initialization', function() {
    -        inject(function($compile, $rootScope, $timeout) {
    -          var element;
    -          var childScope = $rootScope.$new();
    -          childScope.opts = {
    -            items: '> .class'
    -          };
    -
    -          element = $compile(
    -            '<div><ul data-ui-sortable="opts" data-ng-model="items"></ul></div>'
    -          )(childScope);
    -
    -          $rootScope.$digest();
    -
    -          $rootScope.$apply(function() {
    -            childScope.opts = { items: null };
    -          });
    -
    -          expect(element.find('ul').sortable('option', 'items')).toBe(
    -            '> [ng-repeat],> [data-ng-repeat],> [x-ng-repeat]'
    -          );
    -
    -          element.remove(element.firstChild);
    -
    -          expect(function() {
    -            $timeout.flush();
    -          }).not.toThrow();
    -        });
    -      });
    -
    -      it('should properly reset the value of a deleted option', function() {
    -        inject(function($compile, $rootScope, $timeout) {
    -          var element;
    -          var childScope = $rootScope.$new();
    -          childScope.opts = {
    -            opacity: 0.7,
    -            placeholder: 'phClass',
    -            update: function() {}
    -          };
    -
    -          element = $compile(
    -            '<div><ul data-ui-sortable="opts" data-ng-model="items"></ul></div>'
    -          )(childScope);
    -          var $sortableElement = element.find('[data-ui-sortable]');
    -
    -          expect($sortableElement.sortable('option', 'opacity')).toBe(0.7);
    -          expect($sortableElement.sortable('option', 'placeholder')).toBe(
    -            'phClass'
    -          );
    -          expect(typeof $sortableElement.sortable('option', 'update')).toBe(
    -            'function'
    -          );
    -
    -          $rootScope.$digest();
    -
    -          $rootScope.$apply(function() {
    -            delete childScope.opts.opacity;
    -          });
    -
    -          expect($sortableElement.sortable('option', 'opacity')).toBe(false);
    -          expect($sortableElement.sortable('option', 'placeholder')).toBe(
    -            'phClass'
    -          );
    -          expect(typeof $sortableElement.sortable('option', 'update')).toBe(
    -            'function'
    -          );
    -
    -          $rootScope.$digest();
    -
    -          $rootScope.$apply(function() {
    -            childScope.opts = {};
    -          });
    -
    -          expect($sortableElement.sortable('option', 'opacity')).toBe(false);
    -          expect($sortableElement.sortable('option', 'placeholder')).toBe(
    -            false
    -          );
    -          expect(typeof $sortableElement.sortable('option', 'update')).toBe(
    -            'function'
    -          );
    -
    -          element.remove(element.firstChild);
    -
    -          expect(function() {
    -            $timeout.flush();
    -          }).not.toThrow();
    -        });
    -      });
    -
    -      it('should not initialize a disabled sortable', function() {
    -        inject(function($compile, $rootScope) {
    -          var element;
    -          var childScope = $rootScope.$new();
    -          spyOn(angular.element.fn, 'sortable');
    -
    -          childScope.items = ['One', 'Two', 'Three'];
    -          childScope.opts = {
    -            disabled: true
    -          };
    -          element = $compile(
    -            '<ul ui-sortable="opts" ng-model="items"><li ng-repeat="item in items">{{ item }}</li></ul>'
    -          )(childScope);
    -
    -          expect(angular.element.fn.sortable).not.toHaveBeenCalled();
    -        });
    -      });
    -
    -      it('should lazily initialize a latelly enabled sortable (set disabled = false)', function() {
    -        inject(function($compile, $rootScope, $timeout) {
    -          var element;
    -          var childScope = $rootScope.$new();
    -          spyOn(angular.element.fn, 'sortable');
    -
    -          childScope.items = ['One', 'Two', 'Three'];
    -          childScope.opts = {
    -            disabled: true
    -          };
    -          element = $compile(
    -            '<ul ui-sortable="opts" ng-model="items"><li ng-repeat="item in items">{{ item }}</li></ul>'
    -          )(childScope);
    -
    -          expect(angular.element.fn.sortable).not.toHaveBeenCalled();
    -
    -          $rootScope.$apply(function() {
    -            childScope.opts.disabled = false;
    -          });
    -
    -          expect(function() {
    -            $timeout.flush();
    -          }).not.toThrow();
    -
    -          expect(angular.element.fn.sortable).toHaveBeenCalled();
    -        });
    -      });
    -
    -      it('should lazily initialize a sortable enabled in $timeout (set disabled = false)', function() {
    -        inject(function($compile, $rootScope, $timeout) {
    -          var element;
    -          var childScope = $rootScope.$new();
    -          spyOn(angular.element.fn, 'sortable');
    -
    -          childScope.items = ['One', 'Two', 'Three'];
    -          childScope.opts = {
    -            disabled: true
    -          };
    -          element = $compile(
    -            '<ul ui-sortable="opts" ng-model="items"><li ng-repeat="item in items">{{ item }}</li></ul>'
    -          )(childScope);
    -
    -          expect(angular.element.fn.sortable).not.toHaveBeenCalled();
    -
    -          $timeout(function() {
    -            childScope.opts.disabled = false;
    -          });
    -
    -          $timeout(function() {
    -            expect(angular.element.fn.sortable).toHaveBeenCalled();
    -          });
    -
    -          expect(function() {
    -            $timeout.flush();
    -          }).not.toThrow();
    -        });
    -      });
    -
    -      it('should lazily initialize a latelly enabled sortable (delete disabled option)', function() {
    -        inject(function($compile, $rootScope, $timeout) {
    -          var element;
    -          var childScope = $rootScope.$new();
    -          spyOn(angular.element.fn, 'sortable');
    -
    -          childScope.items = ['One', 'Two', 'Three'];
    -          childScope.opts = {
    -            disabled: true
    -          };
    -          element = $compile(
    -            '<ul ui-sortable="opts" ng-model="items"><li ng-repeat="item in items">{{ item }}</li></ul>'
    -          )(childScope);
    -
    -          expect(angular.element.fn.sortable).not.toHaveBeenCalled();
    -
    -          $rootScope.$apply(function() {
    -            childScope.opts = {};
    -          });
    -
    -          expect(function() {
    -            $timeout.flush();
    -          }).not.toThrow();
    -
    -          expect(angular.element.fn.sortable).toHaveBeenCalled();
    -        });
    -      });
    -
    -      it('should lazily initialize a sortable enabled in $timeout (delete disabled option)', function() {
    -        inject(function($compile, $rootScope, $timeout) {
    -          var element;
    -          var childScope = $rootScope.$new();
    -          spyOn(angular.element.fn, 'sortable');
    -
    -          childScope.items = ['One', 'Two', 'Three'];
    -          childScope.opts = {
    -            disabled: true
    -          };
    -          element = $compile(
    -            '<ul ui-sortable="opts" ng-model="items"><li ng-repeat="item in items">{{ item }}</li></ul>'
    -          )(childScope);
    -
    -          expect(angular.element.fn.sortable).not.toHaveBeenCalled();
    -
    -          expect(function() {
    -            $timeout.flush();
    -          }).not.toThrow();
    -
    -          $timeout(function() {
    -            childScope.opts = {};
    -          });
    -
    -          $timeout(function() {
    -            expect(angular.element.fn.sortable).toHaveBeenCalled();
    -          });
    -
    -          expect(function() {
    -            $timeout.flush();
    -          }).not.toThrow();
    -        });
    -      });
    -    });
    -  });
    -});
    diff --git a/test/sortable.test-directives.js b/test/sortable.test-directives.js
    deleted file mode 100644
    index 8186789..0000000
    --- a/test/sortable.test-directives.js
    +++ /dev/null
    @@ -1,52 +0,0 @@
    -'use strict';
    -
    -angular
    -  .module('ui.sortable.testDirectives', [])
    -  .directive('uiSortableSimpleTestDirective', function() {
    -    return {
    -      restrict: 'AE',
    -      scope: true,
    -      require: '?ngModel',
    -      template:
    -        '<div>Directive: <span class="itemContent" ng-bind="text"></span> !!!</div>',
    -      link: function(scope, element, attrs) {
    -        scope.$watch(attrs.ngModel, function(value) {
    -          scope.text = value;
    -        });
    -      }
    -    };
    -  })
    -  .directive('uiSortableDestroyableTestDirective', function() {
    -    return {
    -      restrict: 'AE',
    -      scope: true,
    -      require: '?ngModel',
    -      template:
    -        '<div>$destroy(able) Directive: <span class="itemContent" ng-bind="text"></span> !!!</div>',
    -      link: function(scope, element, attrs) {
    -        scope.$watch(attrs.ngModel, function(value) {
    -          scope.text = value;
    -        });
    -
    -        element.bind('$destroy', function() {
    -          element.html('');
    -        });
    -      }
    -    };
    -  })
    -  .directive('uiSortableTransclusionTestDirective', function() {
    -    return {
    -      restrict: 'E',
    -      transclude: true,
    -      scope: true,
    -      template:
    -        '<div>' +
    -        '<h1>Transclusion Directive</h1>' +
    -        '<div>' +
    -        '<div>' +
    -        '<ng-transclude></ng-transclude>' +
    -        '</div>' +
    -        '</div>' +
    -        '</div>'
    -    };
    -  });
    diff --git a/test/sortable.test-helper.js b/test/sortable.test-helper.js
    deleted file mode 100644
    index 0cd4a24..0000000
    --- a/test/sortable.test-helper.js
    +++ /dev/null
    @@ -1,136 +0,0 @@
    -'use strict';
    -
    -angular
    -  .module('ui.sortable.testHelper', [])
    -  .factory('sortableTestHelper', function() {
    -    var EXTRA_DY_PERCENTAGE = 0.25;
    -
    -    function listContent(list, contentSelector) {
    -      if (!contentSelector) {
    -        contentSelector = '[ng-repeat], [data-ng-repeat], [x-ng-repeat]';
    -      }
    -
    -      if (list && list.length) {
    -        return list
    -          .children(contentSelector)
    -          .map(function() {
    -            return this.innerHTML;
    -          })
    -          .toArray();
    -      }
    -      return [];
    -    }
    -
    -    function listFindContent(list, contentSelector) {
    -      if (!contentSelector) {
    -        contentSelector = '.sortable-item';
    -      }
    -
    -      if (list && list.length) {
    -        return list
    -          .find(contentSelector)
    -          .map(function() {
    -            return this.innerHTML;
    -          })
    -          .toArray();
    -      }
    -      return [];
    -    }
    -
    -    function listInnerContent(list, contentSelector) {
    -      if (!contentSelector) {
    -        contentSelector = '.itemContent';
    -      }
    -
    -      if (list && list.length) {
    -        return list
    -          .children()
    -          .map(function() {
    -            return $(this)
    -              .find(contentSelector)
    -              .html();
    -          })
    -          .toArray();
    -      }
    -      return [];
    -    }
    -
    -    function simulateElementDrag(draggedElement, dropTarget, options) {
    -      var dragOptions = {
    -        dx: dropTarget.position().left - draggedElement.position().left,
    -        dy: dropTarget.position().top - draggedElement.position().top,
    -        moves: 30,
    -        action: (options && options.action) || 'drag'
    -      };
    -
    -      if (options === 'above') {
    -        options = { place: 'above' };
    -      } else if (options === 'below') {
    -        options = { place: 'below' };
    -      }
    -
    -      if (typeof options === 'object') {
    -        if ('place' in options) {
    -          if (options.place === 'above') {
    -            dragOptions.dy -=
    -              EXTRA_DY_PERCENTAGE * draggedElement.outerHeight();
    -          } else if (options.place === 'below') {
    -            dragOptions.dy +=
    -              EXTRA_DY_PERCENTAGE * draggedElement.outerHeight();
    -          }
    -        }
    -
    -        if (isFinite(options.dx)) {
    -          dragOptions.dx = options.dx;
    -        }
    -        if (isFinite(options.dy)) {
    -          dragOptions.dy = options.dy;
    -        }
    -
    -        if (isFinite(options.extrady)) {
    -          dragOptions.dy += options.extrady;
    -        }
    -
    -        if (isFinite(options.extradx)) {
    -          dragOptions.dx += options.extradx;
    -        }
    -
    -        if (isFinite(options.moves) && options.moves > 0) {
    -          dragOptions.moves = options.moves;
    -        }
    -      }
    -
    -      draggedElement.simulate(dragOptions.action, dragOptions);
    -    }
    -
    -    function hasUndefinedProperties(testObject) {
    -      return (
    -        testObject &&
    -        Object.keys(testObject).filter(function(key) {
    -          return (
    -            testObject.hasOwnProperty(key) && testObject[key] !== undefined
    -          );
    -        }).length === 0
    -      );
    -    }
    -
    -    return {
    -      EXTRA_DY_PERCENTAGE: EXTRA_DY_PERCENTAGE,
    -      listContent: listContent,
    -      listFindContent: listFindContent,
    -      listInnerContent: listInnerContent,
    -      simulateElementDrag: simulateElementDrag,
    -      hasUndefinedProperties: hasUndefinedProperties,
    -      extraElements: {
    -        beforeLiElement: '<li>extra element</li>',
    -        afterLiElement: '<li>extra element</li>',
    -        beforeTrElement: '<tr><td>extra element</td></tr>',
    -        afterTrElement: '<tr><td>extra element</td></tr>',
    -        beforeDivElement: '<div>extra element</div>',
    -        afterDivElement: '<div>extra element</div>'
    -      }
    -    };
    -  })
    -  .controller('dummyController', function($scope) {
    -    $scope.testItems = ['One', 'Two', 'Three'];
    -  });
    diff --git a/test/sortable.tests.css b/test/sortable.tests.css
    deleted file mode 100644
    index 6601ca0..0000000
    --- a/test/sortable.tests.css
    +++ /dev/null
    @@ -1,12 +0,0 @@
    -.inline-block {
    -	display: inline-block;
    -}
    -
    -.floatleft,
    -.cross-sortable {
    -	float: left;
    -}
    -
    -.clear {
    -	clear: both;
    -}
    \ No newline at end of file
    diff --git a/vendor/jquery-ui.css b/vendor/jquery-ui.css
    new file mode 100644
    index 0000000..294452f
    --- /dev/null
    +++ b/vendor/jquery-ui.css
    @@ -0,0 +1,1311 @@
    +/*! jQuery UI - v1.12.1 - 2016-09-14
    +* http://jqueryui.com
    +* Includes: core.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, draggable.css, resizable.css, progressbar.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css
    +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
    +* Copyright jQuery Foundation and other contributors; Licensed MIT */
    +
    +/* Layout helpers
    +----------------------------------*/
    +.ui-helper-hidden {
    +	display: none;
    +}
    +.ui-helper-hidden-accessible {
    +	border: 0;
    +	clip: rect(0 0 0 0);
    +	height: 1px;
    +	margin: -1px;
    +	overflow: hidden;
    +	padding: 0;
    +	position: absolute;
    +	width: 1px;
    +}
    +.ui-helper-reset {
    +	margin: 0;
    +	padding: 0;
    +	border: 0;
    +	outline: 0;
    +	line-height: 1.3;
    +	text-decoration: none;
    +	font-size: 100%;
    +	list-style: none;
    +}
    +.ui-helper-clearfix:before,
    +.ui-helper-clearfix:after {
    +	content: "";
    +	display: table;
    +	border-collapse: collapse;
    +}
    +.ui-helper-clearfix:after {
    +	clear: both;
    +}
    +.ui-helper-zfix {
    +	width: 100%;
    +	height: 100%;
    +	top: 0;
    +	left: 0;
    +	position: absolute;
    +	opacity: 0;
    +	filter:Alpha(Opacity=0); /* support: IE8 */
    +}
    +
    +.ui-front {
    +	z-index: 100;
    +}
    +
    +
    +/* Interaction Cues
    +----------------------------------*/
    +.ui-state-disabled {
    +	cursor: default !important;
    +	pointer-events: none;
    +}
    +
    +
    +/* Icons
    +----------------------------------*/
    +.ui-icon {
    +	display: inline-block;
    +	vertical-align: middle;
    +	margin-top: -.25em;
    +	position: relative;
    +	text-indent: -99999px;
    +	overflow: hidden;
    +	background-repeat: no-repeat;
    +}
    +
    +.ui-widget-icon-block {
    +	left: 50%;
    +	margin-left: -8px;
    +	display: block;
    +}
    +
    +/* Misc visuals
    +----------------------------------*/
    +
    +/* Overlays */
    +.ui-widget-overlay {
    +	position: fixed;
    +	top: 0;
    +	left: 0;
    +	width: 100%;
    +	height: 100%;
    +}
    +.ui-accordion .ui-accordion-header {
    +	display: block;
    +	cursor: pointer;
    +	position: relative;
    +	margin: 2px 0 0 0;
    +	padding: .5em .5em .5em .7em;
    +	font-size: 100%;
    +}
    +.ui-accordion .ui-accordion-content {
    +	padding: 1em 2.2em;
    +	border-top: 0;
    +	overflow: auto;
    +}
    +.ui-autocomplete {
    +	position: absolute;
    +	top: 0;
    +	left: 0;
    +	cursor: default;
    +}
    +.ui-menu {
    +	list-style: none;
    +	padding: 0;
    +	margin: 0;
    +	display: block;
    +	outline: 0;
    +}
    +.ui-menu .ui-menu {
    +	position: absolute;
    +}
    +.ui-menu .ui-menu-item {
    +	margin: 0;
    +	cursor: pointer;
    +	/* support: IE10, see #8844 */
    +	list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
    +}
    +.ui-menu .ui-menu-item-wrapper {
    +	position: relative;
    +	padding: 3px 1em 3px .4em;
    +}
    +.ui-menu .ui-menu-divider {
    +	margin: 5px 0;
    +	height: 0;
    +	font-size: 0;
    +	line-height: 0;
    +	border-width: 1px 0 0 0;
    +}
    +.ui-menu .ui-state-focus,
    +.ui-menu .ui-state-active {
    +	margin: -1px;
    +}
    +
    +/* icon support */
    +.ui-menu-icons {
    +	position: relative;
    +}
    +.ui-menu-icons .ui-menu-item-wrapper {
    +	padding-left: 2em;
    +}
    +
    +/* left-aligned */
    +.ui-menu .ui-icon {
    +	position: absolute;
    +	top: 0;
    +	bottom: 0;
    +	left: .2em;
    +	margin: auto 0;
    +}
    +
    +/* right-aligned */
    +.ui-menu .ui-menu-icon {
    +	left: auto;
    +	right: 0;
    +}
    +.ui-button {
    +	padding: .4em 1em;
    +	display: inline-block;
    +	position: relative;
    +	line-height: normal;
    +	margin-right: .1em;
    +	cursor: pointer;
    +	vertical-align: middle;
    +	text-align: center;
    +	-webkit-user-select: none;
    +	-moz-user-select: none;
    +	-ms-user-select: none;
    +	user-select: none;
    +
    +	/* Support: IE <= 11 */
    +	overflow: visible;
    +}
    +
    +.ui-button,
    +.ui-button:link,
    +.ui-button:visited,
    +.ui-button:hover,
    +.ui-button:active {
    +	text-decoration: none;
    +}
    +
    +/* to make room for the icon, a width needs to be set here */
    +.ui-button-icon-only {
    +	width: 2em;
    +	box-sizing: border-box;
    +	text-indent: -9999px;
    +	white-space: nowrap;
    +}
    +
    +/* no icon support for input elements */
    +input.ui-button.ui-button-icon-only {
    +	text-indent: 0;
    +}
    +
    +/* button icon element(s) */
    +.ui-button-icon-only .ui-icon {
    +	position: absolute;
    +	top: 50%;
    +	left: 50%;
    +	margin-top: -8px;
    +	margin-left: -8px;
    +}
    +
    +.ui-button.ui-icon-notext .ui-icon {
    +	padding: 0;
    +	width: 2.1em;
    +	height: 2.1em;
    +	text-indent: -9999px;
    +	white-space: nowrap;
    +
    +}
    +
    +input.ui-button.ui-icon-notext .ui-icon {
    +	width: auto;
    +	height: auto;
    +	text-indent: 0;
    +	white-space: normal;
    +	padding: .4em 1em;
    +}
    +
    +/* workarounds */
    +/* Support: Firefox 5 - 40 */
    +input.ui-button::-moz-focus-inner,
    +button.ui-button::-moz-focus-inner {
    +	border: 0;
    +	padding: 0;
    +}
    +.ui-controlgroup {
    +	vertical-align: middle;
    +	display: inline-block;
    +}
    +.ui-controlgroup > .ui-controlgroup-item {
    +	float: left;
    +	margin-left: 0;
    +	margin-right: 0;
    +}
    +.ui-controlgroup > .ui-controlgroup-item:focus,
    +.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus {
    +	z-index: 9999;
    +}
    +.ui-controlgroup-vertical > .ui-controlgroup-item {
    +	display: block;
    +	float: none;
    +	width: 100%;
    +	margin-top: 0;
    +	margin-bottom: 0;
    +	text-align: left;
    +}
    +.ui-controlgroup-vertical .ui-controlgroup-item {
    +	box-sizing: border-box;
    +}
    +.ui-controlgroup .ui-controlgroup-label {
    +	padding: .4em 1em;
    +}
    +.ui-controlgroup .ui-controlgroup-label span {
    +	font-size: 80%;
    +}
    +.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item {
    +	border-left: none;
    +}
    +.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item {
    +	border-top: none;
    +}
    +.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content {
    +	border-right: none;
    +}
    +.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content {
    +	border-bottom: none;
    +}
    +
    +/* Spinner specific style fixes */
    +.ui-controlgroup-vertical .ui-spinner-input {
    +
    +	/* Support: IE8 only, Android < 4.4 only */
    +	width: 75%;
    +	width: calc( 100% - 2.4em );
    +}
    +.ui-controlgroup-vertical .ui-spinner .ui-spinner-up {
    +	border-top-style: solid;
    +}
    +
    +.ui-checkboxradio-label .ui-icon-background {
    +	box-shadow: inset 1px 1px 1px #ccc;
    +	border-radius: .12em;
    +	border: none;
    +}
    +.ui-checkboxradio-radio-label .ui-icon-background {
    +	width: 16px;
    +	height: 16px;
    +	border-radius: 1em;
    +	overflow: visible;
    +	border: none;
    +}
    +.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,
    +.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon {
    +	background-image: none;
    +	width: 8px;
    +	height: 8px;
    +	border-width: 4px;
    +	border-style: solid;
    +}
    +.ui-checkboxradio-disabled {
    +	pointer-events: none;
    +}
    +.ui-datepicker {
    +	width: 17em;
    +	padding: .2em .2em 0;
    +	display: none;
    +}
    +.ui-datepicker .ui-datepicker-header {
    +	position: relative;
    +	padding: .2em 0;
    +}
    +.ui-datepicker .ui-datepicker-prev,
    +.ui-datepicker .ui-datepicker-next {
    +	position: absolute;
    +	top: 2px;
    +	width: 1.8em;
    +	height: 1.8em;
    +}
    +.ui-datepicker .ui-datepicker-prev-hover,
    +.ui-datepicker .ui-datepicker-next-hover {
    +	top: 1px;
    +}
    +.ui-datepicker .ui-datepicker-prev {
    +	left: 2px;
    +}
    +.ui-datepicker .ui-datepicker-next {
    +	right: 2px;
    +}
    +.ui-datepicker .ui-datepicker-prev-hover {
    +	left: 1px;
    +}
    +.ui-datepicker .ui-datepicker-next-hover {
    +	right: 1px;
    +}
    +.ui-datepicker .ui-datepicker-prev span,
    +.ui-datepicker .ui-datepicker-next span {
    +	display: block;
    +	position: absolute;
    +	left: 50%;
    +	margin-left: -8px;
    +	top: 50%;
    +	margin-top: -8px;
    +}
    +.ui-datepicker .ui-datepicker-title {
    +	margin: 0 2.3em;
    +	line-height: 1.8em;
    +	text-align: center;
    +}
    +.ui-datepicker .ui-datepicker-title select {
    +	font-size: 1em;
    +	margin: 1px 0;
    +}
    +.ui-datepicker select.ui-datepicker-month,
    +.ui-datepicker select.ui-datepicker-year {
    +	width: 45%;
    +}
    +.ui-datepicker table {
    +	width: 100%;
    +	font-size: .9em;
    +	border-collapse: collapse;
    +	margin: 0 0 .4em;
    +}
    +.ui-datepicker th {
    +	padding: .7em .3em;
    +	text-align: center;
    +	font-weight: bold;
    +	border: 0;
    +}
    +.ui-datepicker td {
    +	border: 0;
    +	padding: 1px;
    +}
    +.ui-datepicker td span,
    +.ui-datepicker td a {
    +	display: block;
    +	padding: .2em;
    +	text-align: right;
    +	text-decoration: none;
    +}
    +.ui-datepicker .ui-datepicker-buttonpane {
    +	background-image: none;
    +	margin: .7em 0 0 0;
    +	padding: 0 .2em;
    +	border-left: 0;
    +	border-right: 0;
    +	border-bottom: 0;
    +}
    +.ui-datepicker .ui-datepicker-buttonpane button {
    +	float: right;
    +	margin: .5em .2em .4em;
    +	cursor: pointer;
    +	padding: .2em .6em .3em .6em;
    +	width: auto;
    +	overflow: visible;
    +}
    +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
    +	float: left;
    +}
    +
    +/* with multiple calendars */
    +.ui-datepicker.ui-datepicker-multi {
    +	width: auto;
    +}
    +.ui-datepicker-multi .ui-datepicker-group {
    +	float: left;
    +}
    +.ui-datepicker-multi .ui-datepicker-group table {
    +	width: 95%;
    +	margin: 0 auto .4em;
    +}
    +.ui-datepicker-multi-2 .ui-datepicker-group {
    +	width: 50%;
    +}
    +.ui-datepicker-multi-3 .ui-datepicker-group {
    +	width: 33.3%;
    +}
    +.ui-datepicker-multi-4 .ui-datepicker-group {
    +	width: 25%;
    +}
    +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
    +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
    +	border-left-width: 0;
    +}
    +.ui-datepicker-multi .ui-datepicker-buttonpane {
    +	clear: left;
    +}
    +.ui-datepicker-row-break {
    +	clear: both;
    +	width: 100%;
    +	font-size: 0;
    +}
    +
    +/* RTL support */
    +.ui-datepicker-rtl {
    +	direction: rtl;
    +}
    +.ui-datepicker-rtl .ui-datepicker-prev {
    +	right: 2px;
    +	left: auto;
    +}
    +.ui-datepicker-rtl .ui-datepicker-next {
    +	left: 2px;
    +	right: auto;
    +}
    +.ui-datepicker-rtl .ui-datepicker-prev:hover {
    +	right: 1px;
    +	left: auto;
    +}
    +.ui-datepicker-rtl .ui-datepicker-next:hover {
    +	left: 1px;
    +	right: auto;
    +}
    +.ui-datepicker-rtl .ui-datepicker-buttonpane {
    +	clear: right;
    +}
    +.ui-datepicker-rtl .ui-datepicker-buttonpane button {
    +	float: left;
    +}
    +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
    +.ui-datepicker-rtl .ui-datepicker-group {
    +	float: right;
    +}
    +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
    +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
    +	border-right-width: 0;
    +	border-left-width: 1px;
    +}
    +
    +/* Icons */
    +.ui-datepicker .ui-icon {
    +	display: block;
    +	text-indent: -99999px;
    +	overflow: hidden;
    +	background-repeat: no-repeat;
    +	left: .5em;
    +	top: .3em;
    +}
    +.ui-dialog {
    +	position: absolute;
    +	top: 0;
    +	left: 0;
    +	padding: .2em;
    +	outline: 0;
    +}
    +.ui-dialog .ui-dialog-titlebar {
    +	padding: .4em 1em;
    +	position: relative;
    +}
    +.ui-dialog .ui-dialog-title {
    +	float: left;
    +	margin: .1em 0;
    +	white-space: nowrap;
    +	width: 90%;
    +	overflow: hidden;
    +	text-overflow: ellipsis;
    +}
    +.ui-dialog .ui-dialog-titlebar-close {
    +	position: absolute;
    +	right: .3em;
    +	top: 50%;
    +	width: 20px;
    +	margin: -10px 0 0 0;
    +	padding: 1px;
    +	height: 20px;
    +}
    +.ui-dialog .ui-dialog-content {
    +	position: relative;
    +	border: 0;
    +	padding: .5em 1em;
    +	background: none;
    +	overflow: auto;
    +}
    +.ui-dialog .ui-dialog-buttonpane {
    +	text-align: left;
    +	border-width: 1px 0 0 0;
    +	background-image: none;
    +	margin-top: .5em;
    +	padding: .3em 1em .5em .4em;
    +}
    +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
    +	float: right;
    +}
    +.ui-dialog .ui-dialog-buttonpane button {
    +	margin: .5em .4em .5em 0;
    +	cursor: pointer;
    +}
    +.ui-dialog .ui-resizable-n {
    +	height: 2px;
    +	top: 0;
    +}
    +.ui-dialog .ui-resizable-e {
    +	width: 2px;
    +	right: 0;
    +}
    +.ui-dialog .ui-resizable-s {
    +	height: 2px;
    +	bottom: 0;
    +}
    +.ui-dialog .ui-resizable-w {
    +	width: 2px;
    +	left: 0;
    +}
    +.ui-dialog .ui-resizable-se,
    +.ui-dialog .ui-resizable-sw,
    +.ui-dialog .ui-resizable-ne,
    +.ui-dialog .ui-resizable-nw {
    +	width: 7px;
    +	height: 7px;
    +}
    +.ui-dialog .ui-resizable-se {
    +	right: 0;
    +	bottom: 0;
    +}
    +.ui-dialog .ui-resizable-sw {
    +	left: 0;
    +	bottom: 0;
    +}
    +.ui-dialog .ui-resizable-ne {
    +	right: 0;
    +	top: 0;
    +}
    +.ui-dialog .ui-resizable-nw {
    +	left: 0;
    +	top: 0;
    +}
    +.ui-draggable .ui-dialog-titlebar {
    +	cursor: move;
    +}
    +.ui-draggable-handle {
    +	-ms-touch-action: none;
    +	touch-action: none;
    +}
    +.ui-resizable {
    +	position: relative;
    +}
    +.ui-resizable-handle {
    +	position: absolute;
    +	font-size: 0.1px;
    +	display: block;
    +	-ms-touch-action: none;
    +	touch-action: none;
    +}
    +.ui-resizable-disabled .ui-resizable-handle,
    +.ui-resizable-autohide .ui-resizable-handle {
    +	display: none;
    +}
    +.ui-resizable-n {
    +	cursor: n-resize;
    +	height: 7px;
    +	width: 100%;
    +	top: -5px;
    +	left: 0;
    +}
    +.ui-resizable-s {
    +	cursor: s-resize;
    +	height: 7px;
    +	width: 100%;
    +	bottom: -5px;
    +	left: 0;
    +}
    +.ui-resizable-e {
    +	cursor: e-resize;
    +	width: 7px;
    +	right: -5px;
    +	top: 0;
    +	height: 100%;
    +}
    +.ui-resizable-w {
    +	cursor: w-resize;
    +	width: 7px;
    +	left: -5px;
    +	top: 0;
    +	height: 100%;
    +}
    +.ui-resizable-se {
    +	cursor: se-resize;
    +	width: 12px;
    +	height: 12px;
    +	right: 1px;
    +	bottom: 1px;
    +}
    +.ui-resizable-sw {
    +	cursor: sw-resize;
    +	width: 9px;
    +	height: 9px;
    +	left: -5px;
    +	bottom: -5px;
    +}
    +.ui-resizable-nw {
    +	cursor: nw-resize;
    +	width: 9px;
    +	height: 9px;
    +	left: -5px;
    +	top: -5px;
    +}
    +.ui-resizable-ne {
    +	cursor: ne-resize;
    +	width: 9px;
    +	height: 9px;
    +	right: -5px;
    +	top: -5px;
    +}
    +.ui-progressbar {
    +	height: 2em;
    +	text-align: left;
    +	overflow: hidden;
    +}
    +.ui-progressbar .ui-progressbar-value {
    +	margin: -1px;
    +	height: 100%;
    +}
    +.ui-progressbar .ui-progressbar-overlay {
    +	background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
    +	height: 100%;
    +	filter: alpha(opacity=25); /* support: IE8 */
    +	opacity: 0.25;
    +}
    +.ui-progressbar-indeterminate .ui-progressbar-value {
    +	background-image: none;
    +}
    +.ui-selectable {
    +	-ms-touch-action: none;
    +	touch-action: none;
    +}
    +.ui-selectable-helper {
    +	position: absolute;
    +	z-index: 100;
    +	border: 1px dotted black;
    +}
    +.ui-selectmenu-menu {
    +	padding: 0;
    +	margin: 0;
    +	position: absolute;
    +	top: 0;
    +	left: 0;
    +	display: none;
    +}
    +.ui-selectmenu-menu .ui-menu {
    +	overflow: auto;
    +	overflow-x: hidden;
    +	padding-bottom: 1px;
    +}
    +.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
    +	font-size: 1em;
    +	font-weight: bold;
    +	line-height: 1.5;
    +	padding: 2px 0.4em;
    +	margin: 0.5em 0 0 0;
    +	height: auto;
    +	border: 0;
    +}
    +.ui-selectmenu-open {
    +	display: block;
    +}
    +.ui-selectmenu-text {
    +	display: block;
    +	margin-right: 20px;
    +	overflow: hidden;
    +	text-overflow: ellipsis;
    +}
    +.ui-selectmenu-button.ui-button {
    +	text-align: left;
    +	white-space: nowrap;
    +	width: 14em;
    +}
    +.ui-selectmenu-icon.ui-icon {
    +	float: right;
    +	margin-top: 0;
    +}
    +.ui-slider {
    +	position: relative;
    +	text-align: left;
    +}
    +.ui-slider .ui-slider-handle {
    +	position: absolute;
    +	z-index: 2;
    +	width: 1.2em;
    +	height: 1.2em;
    +	cursor: default;
    +	-ms-touch-action: none;
    +	touch-action: none;
    +}
    +.ui-slider .ui-slider-range {
    +	position: absolute;
    +	z-index: 1;
    +	font-size: .7em;
    +	display: block;
    +	border: 0;
    +	background-position: 0 0;
    +}
    +
    +/* support: IE8 - See #6727 */
    +.ui-slider.ui-state-disabled .ui-slider-handle,
    +.ui-slider.ui-state-disabled .ui-slider-range {
    +	filter: inherit;
    +}
    +
    +.ui-slider-horizontal {
    +	height: .8em;
    +}
    +.ui-slider-horizontal .ui-slider-handle {
    +	top: -.3em;
    +	margin-left: -.6em;
    +}
    +.ui-slider-horizontal .ui-slider-range {
    +	top: 0;
    +	height: 100%;
    +}
    +.ui-slider-horizontal .ui-slider-range-min {
    +	left: 0;
    +}
    +.ui-slider-horizontal .ui-slider-range-max {
    +	right: 0;
    +}
    +
    +.ui-slider-vertical {
    +	width: .8em;
    +	height: 100px;
    +}
    +.ui-slider-vertical .ui-slider-handle {
    +	left: -.3em;
    +	margin-left: 0;
    +	margin-bottom: -.6em;
    +}
    +.ui-slider-vertical .ui-slider-range {
    +	left: 0;
    +	width: 100%;
    +}
    +.ui-slider-vertical .ui-slider-range-min {
    +	bottom: 0;
    +}
    +.ui-slider-vertical .ui-slider-range-max {
    +	top: 0;
    +}
    +.ui-sortable-handle {
    +	-ms-touch-action: none;
    +	touch-action: none;
    +}
    +.ui-spinner {
    +	position: relative;
    +	display: inline-block;
    +	overflow: hidden;
    +	padding: 0;
    +	vertical-align: middle;
    +}
    +.ui-spinner-input {
    +	border: none;
    +	background: none;
    +	color: inherit;
    +	padding: .222em 0;
    +	margin: .2em 0;
    +	vertical-align: middle;
    +	margin-left: .4em;
    +	margin-right: 2em;
    +}
    +.ui-spinner-button {
    +	width: 1.6em;
    +	height: 50%;
    +	font-size: .5em;
    +	padding: 0;
    +	margin: 0;
    +	text-align: center;
    +	position: absolute;
    +	cursor: default;
    +	display: block;
    +	overflow: hidden;
    +	right: 0;
    +}
    +/* more specificity required here to override default borders */
    +.ui-spinner a.ui-spinner-button {
    +	border-top-style: none;
    +	border-bottom-style: none;
    +	border-right-style: none;
    +}
    +.ui-spinner-up {
    +	top: 0;
    +}
    +.ui-spinner-down {
    +	bottom: 0;
    +}
    +.ui-tabs {
    +	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
    +	padding: .2em;
    +}
    +.ui-tabs .ui-tabs-nav {
    +	margin: 0;
    +	padding: .2em .2em 0;
    +}
    +.ui-tabs .ui-tabs-nav li {
    +	list-style: none;
    +	float: left;
    +	position: relative;
    +	top: 0;
    +	margin: 1px .2em 0 0;
    +	border-bottom-width: 0;
    +	padding: 0;
    +	white-space: nowrap;
    +}
    +.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
    +	float: left;
    +	padding: .5em 1em;
    +	text-decoration: none;
    +}
    +.ui-tabs .ui-tabs-nav li.ui-tabs-active {
    +	margin-bottom: -1px;
    +	padding-bottom: 1px;
    +}
    +.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
    +.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
    +.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
    +	cursor: text;
    +}
    +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
    +	cursor: pointer;
    +}
    +.ui-tabs .ui-tabs-panel {
    +	display: block;
    +	border-width: 0;
    +	padding: 1em 1.4em;
    +	background: none;
    +}
    +.ui-tooltip {
    +	padding: 8px;
    +	position: absolute;
    +	z-index: 9999;
    +	max-width: 300px;
    +}
    +body .ui-tooltip {
    +	border-width: 2px;
    +}
    +/* Component containers
    +----------------------------------*/
    +.ui-widget {
    +	font-family: Verdana,Arial,sans-serif;
    +	font-size: 1.1em;
    +}
    +.ui-widget .ui-widget {
    +	font-size: 1em;
    +}
    +.ui-widget input,
    +.ui-widget select,
    +.ui-widget textarea,
    +.ui-widget button {
    +	font-family: Verdana,Arial,sans-serif;
    +	font-size: 1em;
    +}
    +.ui-widget.ui-widget-content {
    +	border: 1px solid #d3d3d3;
    +}
    +.ui-widget-content {
    +	border: 1px solid #aaaaaa;
    +	background: #ffffff;
    +	color: #222222;
    +}
    +.ui-widget-content a {
    +	color: #222222;
    +}
    +.ui-widget-header {
    +	border: 1px solid #aaaaaa;
    +	background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;
    +	color: #222222;
    +	font-weight: bold;
    +}
    +.ui-widget-header a {
    +	color: #222222;
    +}
    +
    +/* Interaction states
    +----------------------------------*/
    +.ui-state-default,
    +.ui-widget-content .ui-state-default,
    +.ui-widget-header .ui-state-default,
    +.ui-button,
    +
    +/* We use html here because we need a greater specificity to make sure disabled
    +works properly when clicked or hovered */
    +html .ui-button.ui-state-disabled:hover,
    +html .ui-button.ui-state-disabled:active {
    +	border: 1px solid #d3d3d3;
    +	background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;
    +	font-weight: normal;
    +	color: #555555;
    +}
    +.ui-state-default a,
    +.ui-state-default a:link,
    +.ui-state-default a:visited,
    +a.ui-button,
    +a:link.ui-button,
    +a:visited.ui-button,
    +.ui-button {
    +	color: #555555;
    +	text-decoration: none;
    +}
    +.ui-state-hover,
    +.ui-widget-content .ui-state-hover,
    +.ui-widget-header .ui-state-hover,
    +.ui-state-focus,
    +.ui-widget-content .ui-state-focus,
    +.ui-widget-header .ui-state-focus,
    +.ui-button:hover,
    +.ui-button:focus {
    +	border: 1px solid #999999;
    +	background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;
    +	font-weight: normal;
    +	color: #212121;
    +}
    +.ui-state-hover a,
    +.ui-state-hover a:hover,
    +.ui-state-hover a:link,
    +.ui-state-hover a:visited,
    +.ui-state-focus a,
    +.ui-state-focus a:hover,
    +.ui-state-focus a:link,
    +.ui-state-focus a:visited,
    +a.ui-button:hover,
    +a.ui-button:focus {
    +	color: #212121;
    +	text-decoration: none;
    +}
    +
    +.ui-visual-focus {
    +	box-shadow: 0 0 3px 1px rgb(94, 158, 214);
    +}
    +.ui-state-active,
    +.ui-widget-content .ui-state-active,
    +.ui-widget-header .ui-state-active,
    +a.ui-button:active,
    +.ui-button:active,
    +.ui-button.ui-state-active:hover {
    +	border: 1px solid #aaaaaa;
    +	background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
    +	font-weight: normal;
    +	color: #212121;
    +}
    +.ui-icon-background,
    +.ui-state-active .ui-icon-background {
    +	border: #aaaaaa;
    +	background-color: #212121;
    +}
    +.ui-state-active a,
    +.ui-state-active a:link,
    +.ui-state-active a:visited {
    +	color: #212121;
    +	text-decoration: none;
    +}
    +
    +/* Interaction Cues
    +----------------------------------*/
    +.ui-state-highlight,
    +.ui-widget-content .ui-state-highlight,
    +.ui-widget-header .ui-state-highlight {
    +	border: 1px solid #fcefa1;
    +	background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;
    +	color: #363636;
    +}
    +.ui-state-checked {
    +	border: 1px solid #fcefa1;
    +	background: #fbf9ee;
    +}
    +.ui-state-highlight a,
    +.ui-widget-content .ui-state-highlight a,
    +.ui-widget-header .ui-state-highlight a {
    +	color: #363636;
    +}
    +.ui-state-error,
    +.ui-widget-content .ui-state-error,
    +.ui-widget-header .ui-state-error {
    +	border: 1px solid #cd0a0a;
    +	background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;
    +	color: #cd0a0a;
    +}
    +.ui-state-error a,
    +.ui-widget-content .ui-state-error a,
    +.ui-widget-header .ui-state-error a {
    +	color: #cd0a0a;
    +}
    +.ui-state-error-text,
    +.ui-widget-content .ui-state-error-text,
    +.ui-widget-header .ui-state-error-text {
    +	color: #cd0a0a;
    +}
    +.ui-priority-primary,
    +.ui-widget-content .ui-priority-primary,
    +.ui-widget-header .ui-priority-primary {
    +	font-weight: bold;
    +}
    +.ui-priority-secondary,
    +.ui-widget-content .ui-priority-secondary,
    +.ui-widget-header .ui-priority-secondary {
    +	opacity: .7;
    +	filter:Alpha(Opacity=70); /* support: IE8 */
    +	font-weight: normal;
    +}
    +.ui-state-disabled,
    +.ui-widget-content .ui-state-disabled,
    +.ui-widget-header .ui-state-disabled {
    +	opacity: .35;
    +	filter:Alpha(Opacity=35); /* support: IE8 */
    +	background-image: none;
    +}
    +.ui-state-disabled .ui-icon {
    +	filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
    +}
    +
    +/* Icons
    +----------------------------------*/
    +
    +/* states and images */
    +.ui-icon {
    +	width: 16px;
    +	height: 16px;
    +}
    +.ui-icon,
    +.ui-widget-content .ui-icon {
    +	background-image: url("images/ui-icons_222222_256x240.png");
    +}
    +.ui-widget-header .ui-icon {
    +	background-image: url("images/ui-icons_222222_256x240.png");
    +}
    +.ui-state-hover .ui-icon,
    +.ui-state-focus .ui-icon,
    +.ui-button:hover .ui-icon,
    +.ui-button:focus .ui-icon {
    +	background-image: url("images/ui-icons_454545_256x240.png");
    +}
    +.ui-state-active .ui-icon,
    +.ui-button:active .ui-icon {
    +	background-image: url("images/ui-icons_454545_256x240.png");
    +}
    +.ui-state-highlight .ui-icon,
    +.ui-button .ui-state-highlight.ui-icon {
    +	background-image: url("images/ui-icons_2e83ff_256x240.png");
    +}
    +.ui-state-error .ui-icon,
    +.ui-state-error-text .ui-icon {
    +	background-image: url("images/ui-icons_cd0a0a_256x240.png");
    +}
    +.ui-button .ui-icon {
    +	background-image: url("images/ui-icons_888888_256x240.png");
    +}
    +
    +/* positioning */
    +.ui-icon-blank { background-position: 16px 16px; }
    +.ui-icon-caret-1-n { background-position: 0 0; }
    +.ui-icon-caret-1-ne { background-position: -16px 0; }
    +.ui-icon-caret-1-e { background-position: -32px 0; }
    +.ui-icon-caret-1-se { background-position: -48px 0; }
    +.ui-icon-caret-1-s { background-position: -65px 0; }
    +.ui-icon-caret-1-sw { background-position: -80px 0; }
    +.ui-icon-caret-1-w { background-position: -96px 0; }
    +.ui-icon-caret-1-nw { background-position: -112px 0; }
    +.ui-icon-caret-2-n-s { background-position: -128px 0; }
    +.ui-icon-caret-2-e-w { background-position: -144px 0; }
    +.ui-icon-triangle-1-n { background-position: 0 -16px; }
    +.ui-icon-triangle-1-ne { background-position: -16px -16px; }
    +.ui-icon-triangle-1-e { background-position: -32px -16px; }
    +.ui-icon-triangle-1-se { background-position: -48px -16px; }
    +.ui-icon-triangle-1-s { background-position: -65px -16px; }
    +.ui-icon-triangle-1-sw { background-position: -80px -16px; }
    +.ui-icon-triangle-1-w { background-position: -96px -16px; }
    +.ui-icon-triangle-1-nw { background-position: -112px -16px; }
    +.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
    +.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
    +.ui-icon-arrow-1-n { background-position: 0 -32px; }
    +.ui-icon-arrow-1-ne { background-position: -16px -32px; }
    +.ui-icon-arrow-1-e { background-position: -32px -32px; }
    +.ui-icon-arrow-1-se { background-position: -48px -32px; }
    +.ui-icon-arrow-1-s { background-position: -65px -32px; }
    +.ui-icon-arrow-1-sw { background-position: -80px -32px; }
    +.ui-icon-arrow-1-w { background-position: -96px -32px; }
    +.ui-icon-arrow-1-nw { background-position: -112px -32px; }
    +.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
    +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
    +.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
    +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
    +.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
    +.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
    +.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
    +.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
    +.ui-icon-arrowthick-1-n { background-position: 1px -48px; }
    +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
    +.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
    +.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
    +.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
    +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
    +.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
    +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
    +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
    +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
    +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
    +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
    +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
    +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
    +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
    +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
    +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
    +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
    +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
    +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
    +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
    +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
    +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
    +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
    +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
    +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
    +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
    +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
    +.ui-icon-arrow-4 { background-position: 0 -80px; }
    +.ui-icon-arrow-4-diag { background-position: -16px -80px; }
    +.ui-icon-extlink { background-position: -32px -80px; }
    +.ui-icon-newwin { background-position: -48px -80px; }
    +.ui-icon-refresh { background-position: -64px -80px; }
    +.ui-icon-shuffle { background-position: -80px -80px; }
    +.ui-icon-transfer-e-w { background-position: -96px -80px; }
    +.ui-icon-transferthick-e-w { background-position: -112px -80px; }
    +.ui-icon-folder-collapsed { background-position: 0 -96px; }
    +.ui-icon-folder-open { background-position: -16px -96px; }
    +.ui-icon-document { background-position: -32px -96px; }
    +.ui-icon-document-b { background-position: -48px -96px; }
    +.ui-icon-note { background-position: -64px -96px; }
    +.ui-icon-mail-closed { background-position: -80px -96px; }
    +.ui-icon-mail-open { background-position: -96px -96px; }
    +.ui-icon-suitcase { background-position: -112px -96px; }
    +.ui-icon-comment { background-position: -128px -96px; }
    +.ui-icon-person { background-position: -144px -96px; }
    +.ui-icon-print { background-position: -160px -96px; }
    +.ui-icon-trash { background-position: -176px -96px; }
    +.ui-icon-locked { background-position: -192px -96px; }
    +.ui-icon-unlocked { background-position: -208px -96px; }
    +.ui-icon-bookmark { background-position: -224px -96px; }
    +.ui-icon-tag { background-position: -240px -96px; }
    +.ui-icon-home { background-position: 0 -112px; }
    +.ui-icon-flag { background-position: -16px -112px; }
    +.ui-icon-calendar { background-position: -32px -112px; }
    +.ui-icon-cart { background-position: -48px -112px; }
    +.ui-icon-pencil { background-position: -64px -112px; }
    +.ui-icon-clock { background-position: -80px -112px; }
    +.ui-icon-disk { background-position: -96px -112px; }
    +.ui-icon-calculator { background-position: -112px -112px; }
    +.ui-icon-zoomin { background-position: -128px -112px; }
    +.ui-icon-zoomout { background-position: -144px -112px; }
    +.ui-icon-search { background-position: -160px -112px; }
    +.ui-icon-wrench { background-position: -176px -112px; }
    +.ui-icon-gear { background-position: -192px -112px; }
    +.ui-icon-heart { background-position: -208px -112px; }
    +.ui-icon-star { background-position: -224px -112px; }
    +.ui-icon-link { background-position: -240px -112px; }
    +.ui-icon-cancel { background-position: 0 -128px; }
    +.ui-icon-plus { background-position: -16px -128px; }
    +.ui-icon-plusthick { background-position: -32px -128px; }
    +.ui-icon-minus { background-position: -48px -128px; }
    +.ui-icon-minusthick { background-position: -64px -128px; }
    +.ui-icon-close { background-position: -80px -128px; }
    +.ui-icon-closethick { background-position: -96px -128px; }
    +.ui-icon-key { background-position: -112px -128px; }
    +.ui-icon-lightbulb { background-position: -128px -128px; }
    +.ui-icon-scissors { background-position: -144px -128px; }
    +.ui-icon-clipboard { background-position: -160px -128px; }
    +.ui-icon-copy { background-position: -176px -128px; }
    +.ui-icon-contact { background-position: -192px -128px; }
    +.ui-icon-image { background-position: -208px -128px; }
    +.ui-icon-video { background-position: -224px -128px; }
    +.ui-icon-script { background-position: -240px -128px; }
    +.ui-icon-alert { background-position: 0 -144px; }
    +.ui-icon-info { background-position: -16px -144px; }
    +.ui-icon-notice { background-position: -32px -144px; }
    +.ui-icon-help { background-position: -48px -144px; }
    +.ui-icon-check { background-position: -64px -144px; }
    +.ui-icon-bullet { background-position: -80px -144px; }
    +.ui-icon-radio-on { background-position: -96px -144px; }
    +.ui-icon-radio-off { background-position: -112px -144px; }
    +.ui-icon-pin-w { background-position: -128px -144px; }
    +.ui-icon-pin-s { background-position: -144px -144px; }
    +.ui-icon-play { background-position: 0 -160px; }
    +.ui-icon-pause { background-position: -16px -160px; }
    +.ui-icon-seek-next { background-position: -32px -160px; }
    +.ui-icon-seek-prev { background-position: -48px -160px; }
    +.ui-icon-seek-end { background-position: -64px -160px; }
    +.ui-icon-seek-start { background-position: -80px -160px; }
    +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
    +.ui-icon-seek-first { background-position: -80px -160px; }
    +.ui-icon-stop { background-position: -96px -160px; }
    +.ui-icon-eject { background-position: -112px -160px; }
    +.ui-icon-volume-off { background-position: -128px -160px; }
    +.ui-icon-volume-on { background-position: -144px -160px; }
    +.ui-icon-power { background-position: 0 -176px; }
    +.ui-icon-signal-diag { background-position: -16px -176px; }
    +.ui-icon-signal { background-position: -32px -176px; }
    +.ui-icon-battery-0 { background-position: -48px -176px; }
    +.ui-icon-battery-1 { background-position: -64px -176px; }
    +.ui-icon-battery-2 { background-position: -80px -176px; }
    +.ui-icon-battery-3 { background-position: -96px -176px; }
    +.ui-icon-circle-plus { background-position: 0 -192px; }
    +.ui-icon-circle-minus { background-position: -16px -192px; }
    +.ui-icon-circle-close { background-position: -32px -192px; }
    +.ui-icon-circle-triangle-e { background-position: -48px -192px; }
    +.ui-icon-circle-triangle-s { background-position: -64px -192px; }
    +.ui-icon-circle-triangle-w { background-position: -80px -192px; }
    +.ui-icon-circle-triangle-n { background-position: -96px -192px; }
    +.ui-icon-circle-arrow-e { background-position: -112px -192px; }
    +.ui-icon-circle-arrow-s { background-position: -128px -192px; }
    +.ui-icon-circle-arrow-w { background-position: -144px -192px; }
    +.ui-icon-circle-arrow-n { background-position: -160px -192px; }
    +.ui-icon-circle-zoomin { background-position: -176px -192px; }
    +.ui-icon-circle-zoomout { background-position: -192px -192px; }
    +.ui-icon-circle-check { background-position: -208px -192px; }
    +.ui-icon-circlesmall-plus { background-position: 0 -208px; }
    +.ui-icon-circlesmall-minus { background-position: -16px -208px; }
    +.ui-icon-circlesmall-close { background-position: -32px -208px; }
    +.ui-icon-squaresmall-plus { background-position: -48px -208px; }
    +.ui-icon-squaresmall-minus { background-position: -64px -208px; }
    +.ui-icon-squaresmall-close { background-position: -80px -208px; }
    +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
    +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
    +.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
    +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
    +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
    +.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
    +
    +
    +/* Misc visuals
    +----------------------------------*/
    +
    +/* Corner radius */
    +.ui-corner-all,
    +.ui-corner-top,
    +.ui-corner-left,
    +.ui-corner-tl {
    +	border-top-left-radius: 4px;
    +}
    +.ui-corner-all,
    +.ui-corner-top,
    +.ui-corner-right,
    +.ui-corner-tr {
    +	border-top-right-radius: 4px;
    +}
    +.ui-corner-all,
    +.ui-corner-bottom,
    +.ui-corner-left,
    +.ui-corner-bl {
    +	border-bottom-left-radius: 4px;
    +}
    +.ui-corner-all,
    +.ui-corner-bottom,
    +.ui-corner-right,
    +.ui-corner-br {
    +	border-bottom-right-radius: 4px;
    +}
    +
    +/* Overlays */
    +.ui-widget-overlay {
    +	background: #aaaaaa;
    +	opacity: .3;
    +	filter: Alpha(Opacity=30); /* support: IE8 */
    +}
    +.ui-widget-shadow {
    +	-webkit-box-shadow: -8px -8px 8px #aaaaaa;
    +	box-shadow: -8px -8px 8px #aaaaaa;
    +}
    diff --git a/vendor/jquery-ui.js b/vendor/jquery-ui.js
    new file mode 100644
    index 0000000..0213552
    --- /dev/null
    +++ b/vendor/jquery-ui.js
    @@ -0,0 +1,18706 @@
    +/*! jQuery UI - v1.12.1 - 2016-09-14
    +* http://jqueryui.com
    +* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js
    +* Copyright jQuery Foundation and other contributors; Licensed MIT */
    +
    +(function( factory ) {
    +	if ( typeof define === "function" && define.amd ) {
    +
    +		// AMD. Register as an anonymous module.
    +		define([ "jquery" ], factory );
    +	} else {
    +
    +		// Browser globals
    +		factory( jQuery );
    +	}
    +}(function( $ ) {
    +
    +$.ui = $.ui || {};
    +
    +var version = $.ui.version = "1.12.1";
    +
    +
    +/*!
    + * jQuery UI Widget 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Widget
    +//>>group: Core
    +//>>description: Provides a factory for creating stateful widgets with a common API.
    +//>>docs: http://api.jqueryui.com/jQuery.widget/
    +//>>demos: http://jqueryui.com/widget/
    +
    +
    +
    +var widgetUuid = 0;
    +var widgetSlice = Array.prototype.slice;
    +
    +$.cleanData = ( function( orig ) {
    +	return function( elems ) {
    +		var events, elem, i;
    +		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
    +			try {
    +
    +				// Only trigger remove when necessary to save time
    +				events = $._data( elem, "events" );
    +				if ( events && events.remove ) {
    +					$( elem ).triggerHandler( "remove" );
    +				}
    +
    +			// Http://bugs.jquery.com/ticket/8235
    +			} catch ( e ) {}
    +		}
    +		orig( elems );
    +	};
    +} )( $.cleanData );
    +
    +$.widget = function( name, base, prototype ) {
    +	var existingConstructor, constructor, basePrototype;
    +
    +	// ProxiedPrototype allows the provided prototype to remain unmodified
    +	// so that it can be used as a mixin for multiple widgets (#8876)
    +	var proxiedPrototype = {};
    +
    +	var namespace = name.split( "." )[ 0 ];
    +	name = name.split( "." )[ 1 ];
    +	var fullName = namespace + "-" + name;
    +
    +	if ( !prototype ) {
    +		prototype = base;
    +		base = $.Widget;
    +	}
    +
    +	if ( $.isArray( prototype ) ) {
    +		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
    +	}
    +
    +	// Create selector for plugin
    +	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
    +		return !!$.data( elem, fullName );
    +	};
    +
    +	$[ namespace ] = $[ namespace ] || {};
    +	existingConstructor = $[ namespace ][ name ];
    +	constructor = $[ namespace ][ name ] = function( options, element ) {
    +
    +		// Allow instantiation without "new" keyword
    +		if ( !this._createWidget ) {
    +			return new constructor( options, element );
    +		}
    +
    +		// Allow instantiation without initializing for simple inheritance
    +		// must use "new" keyword (the code above always passes args)
    +		if ( arguments.length ) {
    +			this._createWidget( options, element );
    +		}
    +	};
    +
    +	// Extend with the existing constructor to carry over any static properties
    +	$.extend( constructor, existingConstructor, {
    +		version: prototype.version,
    +
    +		// Copy the object used to create the prototype in case we need to
    +		// redefine the widget later
    +		_proto: $.extend( {}, prototype ),
    +
    +		// Track widgets that inherit from this widget in case this widget is
    +		// redefined after a widget inherits from it
    +		_childConstructors: []
    +	} );
    +
    +	basePrototype = new base();
    +
    +	// We need to make the options hash a property directly on the new instance
    +	// otherwise we'll modify the options hash on the prototype that we're
    +	// inheriting from
    +	basePrototype.options = $.widget.extend( {}, basePrototype.options );
    +	$.each( prototype, function( prop, value ) {
    +		if ( !$.isFunction( value ) ) {
    +			proxiedPrototype[ prop ] = value;
    +			return;
    +		}
    +		proxiedPrototype[ prop ] = ( function() {
    +			function _super() {
    +				return base.prototype[ prop ].apply( this, arguments );
    +			}
    +
    +			function _superApply( args ) {
    +				return base.prototype[ prop ].apply( this, args );
    +			}
    +
    +			return function() {
    +				var __super = this._super;
    +				var __superApply = this._superApply;
    +				var returnValue;
    +
    +				this._super = _super;
    +				this._superApply = _superApply;
    +
    +				returnValue = value.apply( this, arguments );
    +
    +				this._super = __super;
    +				this._superApply = __superApply;
    +
    +				return returnValue;
    +			};
    +		} )();
    +	} );
    +	constructor.prototype = $.widget.extend( basePrototype, {
    +
    +		// TODO: remove support for widgetEventPrefix
    +		// always use the name + a colon as the prefix, e.g., draggable:start
    +		// don't prefix for widgets that aren't DOM-based
    +		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
    +	}, proxiedPrototype, {
    +		constructor: constructor,
    +		namespace: namespace,
    +		widgetName: name,
    +		widgetFullName: fullName
    +	} );
    +
    +	// If this widget is being redefined then we need to find all widgets that
    +	// are inheriting from it and redefine all of them so that they inherit from
    +	// the new version of this widget. We're essentially trying to replace one
    +	// level in the prototype chain.
    +	if ( existingConstructor ) {
    +		$.each( existingConstructor._childConstructors, function( i, child ) {
    +			var childPrototype = child.prototype;
    +
    +			// Redefine the child widget using the same prototype that was
    +			// originally used, but inherit from the new version of the base
    +			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
    +				child._proto );
    +		} );
    +
    +		// Remove the list of existing child constructors from the old constructor
    +		// so the old child constructors can be garbage collected
    +		delete existingConstructor._childConstructors;
    +	} else {
    +		base._childConstructors.push( constructor );
    +	}
    +
    +	$.widget.bridge( name, constructor );
    +
    +	return constructor;
    +};
    +
    +$.widget.extend = function( target ) {
    +	var input = widgetSlice.call( arguments, 1 );
    +	var inputIndex = 0;
    +	var inputLength = input.length;
    +	var key;
    +	var value;
    +
    +	for ( ; inputIndex < inputLength; inputIndex++ ) {
    +		for ( key in input[ inputIndex ] ) {
    +			value = input[ inputIndex ][ key ];
    +			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
    +
    +				// Clone objects
    +				if ( $.isPlainObject( value ) ) {
    +					target[ key ] = $.isPlainObject( target[ key ] ) ?
    +						$.widget.extend( {}, target[ key ], value ) :
    +
    +						// Don't extend strings, arrays, etc. with objects
    +						$.widget.extend( {}, value );
    +
    +				// Copy everything else by reference
    +				} else {
    +					target[ key ] = value;
    +				}
    +			}
    +		}
    +	}
    +	return target;
    +};
    +
    +$.widget.bridge = function( name, object ) {
    +	var fullName = object.prototype.widgetFullName || name;
    +	$.fn[ name ] = function( options ) {
    +		var isMethodCall = typeof options === "string";
    +		var args = widgetSlice.call( arguments, 1 );
    +		var returnValue = this;
    +
    +		if ( isMethodCall ) {
    +
    +			// If this is an empty collection, we need to have the instance method
    +			// return undefined instead of the jQuery instance
    +			if ( !this.length && options === "instance" ) {
    +				returnValue = undefined;
    +			} else {
    +				this.each( function() {
    +					var methodValue;
    +					var instance = $.data( this, fullName );
    +
    +					if ( options === "instance" ) {
    +						returnValue = instance;
    +						return false;
    +					}
    +
    +					if ( !instance ) {
    +						return $.error( "cannot call methods on " + name +
    +							" prior to initialization; " +
    +							"attempted to call method '" + options + "'" );
    +					}
    +
    +					if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
    +						return $.error( "no such method '" + options + "' for " + name +
    +							" widget instance" );
    +					}
    +
    +					methodValue = instance[ options ].apply( instance, args );
    +
    +					if ( methodValue !== instance && methodValue !== undefined ) {
    +						returnValue = methodValue && methodValue.jquery ?
    +							returnValue.pushStack( methodValue.get() ) :
    +							methodValue;
    +						return false;
    +					}
    +				} );
    +			}
    +		} else {
    +
    +			// Allow multiple hashes to be passed on init
    +			if ( args.length ) {
    +				options = $.widget.extend.apply( null, [ options ].concat( args ) );
    +			}
    +
    +			this.each( function() {
    +				var instance = $.data( this, fullName );
    +				if ( instance ) {
    +					instance.option( options || {} );
    +					if ( instance._init ) {
    +						instance._init();
    +					}
    +				} else {
    +					$.data( this, fullName, new object( options, this ) );
    +				}
    +			} );
    +		}
    +
    +		return returnValue;
    +	};
    +};
    +
    +$.Widget = function( /* options, element */ ) {};
    +$.Widget._childConstructors = [];
    +
    +$.Widget.prototype = {
    +	widgetName: "widget",
    +	widgetEventPrefix: "",
    +	defaultElement: "<div>",
    +
    +	options: {
    +		classes: {},
    +		disabled: false,
    +
    +		// Callbacks
    +		create: null
    +	},
    +
    +	_createWidget: function( options, element ) {
    +		element = $( element || this.defaultElement || this )[ 0 ];
    +		this.element = $( element );
    +		this.uuid = widgetUuid++;
    +		this.eventNamespace = "." + this.widgetName + this.uuid;
    +
    +		this.bindings = $();
    +		this.hoverable = $();
    +		this.focusable = $();
    +		this.classesElementLookup = {};
    +
    +		if ( element !== this ) {
    +			$.data( element, this.widgetFullName, this );
    +			this._on( true, this.element, {
    +				remove: function( event ) {
    +					if ( event.target === element ) {
    +						this.destroy();
    +					}
    +				}
    +			} );
    +			this.document = $( element.style ?
    +
    +				// Element within the document
    +				element.ownerDocument :
    +
    +				// Element is window or document
    +				element.document || element );
    +			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
    +		}
    +
    +		this.options = $.widget.extend( {},
    +			this.options,
    +			this._getCreateOptions(),
    +			options );
    +
    +		this._create();
    +
    +		if ( this.options.disabled ) {
    +			this._setOptionDisabled( this.options.disabled );
    +		}
    +
    +		this._trigger( "create", null, this._getCreateEventData() );
    +		this._init();
    +	},
    +
    +	_getCreateOptions: function() {
    +		return {};
    +	},
    +
    +	_getCreateEventData: $.noop,
    +
    +	_create: $.noop,
    +
    +	_init: $.noop,
    +
    +	destroy: function() {
    +		var that = this;
    +
    +		this._destroy();
    +		$.each( this.classesElementLookup, function( key, value ) {
    +			that._removeClass( value, key );
    +		} );
    +
    +		// We can probably remove the unbind calls in 2.0
    +		// all event bindings should go through this._on()
    +		this.element
    +			.off( this.eventNamespace )
    +			.removeData( this.widgetFullName );
    +		this.widget()
    +			.off( this.eventNamespace )
    +			.removeAttr( "aria-disabled" );
    +
    +		// Clean up events and states
    +		this.bindings.off( this.eventNamespace );
    +	},
    +
    +	_destroy: $.noop,
    +
    +	widget: function() {
    +		return this.element;
    +	},
    +
    +	option: function( key, value ) {
    +		var options = key;
    +		var parts;
    +		var curOption;
    +		var i;
    +
    +		if ( arguments.length === 0 ) {
    +
    +			// Don't return a reference to the internal hash
    +			return $.widget.extend( {}, this.options );
    +		}
    +
    +		if ( typeof key === "string" ) {
    +
    +			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
    +			options = {};
    +			parts = key.split( "." );
    +			key = parts.shift();
    +			if ( parts.length ) {
    +				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
    +				for ( i = 0; i < parts.length - 1; i++ ) {
    +					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
    +					curOption = curOption[ parts[ i ] ];
    +				}
    +				key = parts.pop();
    +				if ( arguments.length === 1 ) {
    +					return curOption[ key ] === undefined ? null : curOption[ key ];
    +				}
    +				curOption[ key ] = value;
    +			} else {
    +				if ( arguments.length === 1 ) {
    +					return this.options[ key ] === undefined ? null : this.options[ key ];
    +				}
    +				options[ key ] = value;
    +			}
    +		}
    +
    +		this._setOptions( options );
    +
    +		return this;
    +	},
    +
    +	_setOptions: function( options ) {
    +		var key;
    +
    +		for ( key in options ) {
    +			this._setOption( key, options[ key ] );
    +		}
    +
    +		return this;
    +	},
    +
    +	_setOption: function( key, value ) {
    +		if ( key === "classes" ) {
    +			this._setOptionClasses( value );
    +		}
    +
    +		this.options[ key ] = value;
    +
    +		if ( key === "disabled" ) {
    +			this._setOptionDisabled( value );
    +		}
    +
    +		return this;
    +	},
    +
    +	_setOptionClasses: function( value ) {
    +		var classKey, elements, currentElements;
    +
    +		for ( classKey in value ) {
    +			currentElements = this.classesElementLookup[ classKey ];
    +			if ( value[ classKey ] === this.options.classes[ classKey ] ||
    +					!currentElements ||
    +					!currentElements.length ) {
    +				continue;
    +			}
    +
    +			// We are doing this to create a new jQuery object because the _removeClass() call
    +			// on the next line is going to destroy the reference to the current elements being
    +			// tracked. We need to save a copy of this collection so that we can add the new classes
    +			// below.
    +			elements = $( currentElements.get() );
    +			this._removeClass( currentElements, classKey );
    +
    +			// We don't use _addClass() here, because that uses this.options.classes
    +			// for generating the string of classes. We want to use the value passed in from
    +			// _setOption(), this is the new value of the classes option which was passed to
    +			// _setOption(). We pass this value directly to _classes().
    +			elements.addClass( this._classes( {
    +				element: elements,
    +				keys: classKey,
    +				classes: value,
    +				add: true
    +			} ) );
    +		}
    +	},
    +
    +	_setOptionDisabled: function( value ) {
    +		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
    +
    +		// If the widget is becoming disabled, then nothing is interactive
    +		if ( value ) {
    +			this._removeClass( this.hoverable, null, "ui-state-hover" );
    +			this._removeClass( this.focusable, null, "ui-state-focus" );
    +		}
    +	},
    +
    +	enable: function() {
    +		return this._setOptions( { disabled: false } );
    +	},
    +
    +	disable: function() {
    +		return this._setOptions( { disabled: true } );
    +	},
    +
    +	_classes: function( options ) {
    +		var full = [];
    +		var that = this;
    +
    +		options = $.extend( {
    +			element: this.element,
    +			classes: this.options.classes || {}
    +		}, options );
    +
    +		function processClassString( classes, checkOption ) {
    +			var current, i;
    +			for ( i = 0; i < classes.length; i++ ) {
    +				current = that.classesElementLookup[ classes[ i ] ] || $();
    +				if ( options.add ) {
    +					current = $( $.unique( current.get().concat( options.element.get() ) ) );
    +				} else {
    +					current = $( current.not( options.element ).get() );
    +				}
    +				that.classesElementLookup[ classes[ i ] ] = current;
    +				full.push( classes[ i ] );
    +				if ( checkOption && options.classes[ classes[ i ] ] ) {
    +					full.push( options.classes[ classes[ i ] ] );
    +				}
    +			}
    +		}
    +
    +		this._on( options.element, {
    +			"remove": "_untrackClassesElement"
    +		} );
    +
    +		if ( options.keys ) {
    +			processClassString( options.keys.match( /\S+/g ) || [], true );
    +		}
    +		if ( options.extra ) {
    +			processClassString( options.extra.match( /\S+/g ) || [] );
    +		}
    +
    +		return full.join( " " );
    +	},
    +
    +	_untrackClassesElement: function( event ) {
    +		var that = this;
    +		$.each( that.classesElementLookup, function( key, value ) {
    +			if ( $.inArray( event.target, value ) !== -1 ) {
    +				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
    +			}
    +		} );
    +	},
    +
    +	_removeClass: function( element, keys, extra ) {
    +		return this._toggleClass( element, keys, extra, false );
    +	},
    +
    +	_addClass: function( element, keys, extra ) {
    +		return this._toggleClass( element, keys, extra, true );
    +	},
    +
    +	_toggleClass: function( element, keys, extra, add ) {
    +		add = ( typeof add === "boolean" ) ? add : extra;
    +		var shift = ( typeof element === "string" || element === null ),
    +			options = {
    +				extra: shift ? keys : extra,
    +				keys: shift ? element : keys,
    +				element: shift ? this.element : element,
    +				add: add
    +			};
    +		options.element.toggleClass( this._classes( options ), add );
    +		return this;
    +	},
    +
    +	_on: function( suppressDisabledCheck, element, handlers ) {
    +		var delegateElement;
    +		var instance = this;
    +
    +		// No suppressDisabledCheck flag, shuffle arguments
    +		if ( typeof suppressDisabledCheck !== "boolean" ) {
    +			handlers = element;
    +			element = suppressDisabledCheck;
    +			suppressDisabledCheck = false;
    +		}
    +
    +		// No element argument, shuffle and use this.element
    +		if ( !handlers ) {
    +			handlers = element;
    +			element = this.element;
    +			delegateElement = this.widget();
    +		} else {
    +			element = delegateElement = $( element );
    +			this.bindings = this.bindings.add( element );
    +		}
    +
    +		$.each( handlers, function( event, handler ) {
    +			function handlerProxy() {
    +
    +				// Allow widgets to customize the disabled handling
    +				// - disabled as an array instead of boolean
    +				// - disabled class as method for disabling individual parts
    +				if ( !suppressDisabledCheck &&
    +						( instance.options.disabled === true ||
    +						$( this ).hasClass( "ui-state-disabled" ) ) ) {
    +					return;
    +				}
    +				return ( typeof handler === "string" ? instance[ handler ] : handler )
    +					.apply( instance, arguments );
    +			}
    +
    +			// Copy the guid so direct unbinding works
    +			if ( typeof handler !== "string" ) {
    +				handlerProxy.guid = handler.guid =
    +					handler.guid || handlerProxy.guid || $.guid++;
    +			}
    +
    +			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
    +			var eventName = match[ 1 ] + instance.eventNamespace;
    +			var selector = match[ 2 ];
    +
    +			if ( selector ) {
    +				delegateElement.on( eventName, selector, handlerProxy );
    +			} else {
    +				element.on( eventName, handlerProxy );
    +			}
    +		} );
    +	},
    +
    +	_off: function( element, eventName ) {
    +		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
    +			this.eventNamespace;
    +		element.off( eventName ).off( eventName );
    +
    +		// Clear the stack to avoid memory leaks (#10056)
    +		this.bindings = $( this.bindings.not( element ).get() );
    +		this.focusable = $( this.focusable.not( element ).get() );
    +		this.hoverable = $( this.hoverable.not( element ).get() );
    +	},
    +
    +	_delay: function( handler, delay ) {
    +		function handlerProxy() {
    +			return ( typeof handler === "string" ? instance[ handler ] : handler )
    +				.apply( instance, arguments );
    +		}
    +		var instance = this;
    +		return setTimeout( handlerProxy, delay || 0 );
    +	},
    +
    +	_hoverable: function( element ) {
    +		this.hoverable = this.hoverable.add( element );
    +		this._on( element, {
    +			mouseenter: function( event ) {
    +				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
    +			},
    +			mouseleave: function( event ) {
    +				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
    +			}
    +		} );
    +	},
    +
    +	_focusable: function( element ) {
    +		this.focusable = this.focusable.add( element );
    +		this._on( element, {
    +			focusin: function( event ) {
    +				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
    +			},
    +			focusout: function( event ) {
    +				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
    +			}
    +		} );
    +	},
    +
    +	_trigger: function( type, event, data ) {
    +		var prop, orig;
    +		var callback = this.options[ type ];
    +
    +		data = data || {};
    +		event = $.Event( event );
    +		event.type = ( type === this.widgetEventPrefix ?
    +			type :
    +			this.widgetEventPrefix + type ).toLowerCase();
    +
    +		// The original event may come from any element
    +		// so we need to reset the target on the new event
    +		event.target = this.element[ 0 ];
    +
    +		// Copy original event properties over to the new event
    +		orig = event.originalEvent;
    +		if ( orig ) {
    +			for ( prop in orig ) {
    +				if ( !( prop in event ) ) {
    +					event[ prop ] = orig[ prop ];
    +				}
    +			}
    +		}
    +
    +		this.element.trigger( event, data );
    +		return !( $.isFunction( callback ) &&
    +			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
    +			event.isDefaultPrevented() );
    +	}
    +};
    +
    +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
    +	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
    +		if ( typeof options === "string" ) {
    +			options = { effect: options };
    +		}
    +
    +		var hasOptions;
    +		var effectName = !options ?
    +			method :
    +			options === true || typeof options === "number" ?
    +				defaultEffect :
    +				options.effect || defaultEffect;
    +
    +		options = options || {};
    +		if ( typeof options === "number" ) {
    +			options = { duration: options };
    +		}
    +
    +		hasOptions = !$.isEmptyObject( options );
    +		options.complete = callback;
    +
    +		if ( options.delay ) {
    +			element.delay( options.delay );
    +		}
    +
    +		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
    +			element[ method ]( options );
    +		} else if ( effectName !== method && element[ effectName ] ) {
    +			element[ effectName ]( options.duration, options.easing, callback );
    +		} else {
    +			element.queue( function( next ) {
    +				$( this )[ method ]();
    +				if ( callback ) {
    +					callback.call( element[ 0 ] );
    +				}
    +				next();
    +			} );
    +		}
    +	};
    +} );
    +
    +var widget = $.widget;
    +
    +
    +/*!
    + * jQuery UI Position 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + *
    + * http://api.jqueryui.com/position/
    + */
    +
    +//>>label: Position
    +//>>group: Core
    +//>>description: Positions elements relative to other elements.
    +//>>docs: http://api.jqueryui.com/position/
    +//>>demos: http://jqueryui.com/position/
    +
    +
    +( function() {
    +var cachedScrollbarWidth,
    +	max = Math.max,
    +	abs = Math.abs,
    +	rhorizontal = /left|center|right/,
    +	rvertical = /top|center|bottom/,
    +	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
    +	rposition = /^\w+/,
    +	rpercent = /%$/,
    +	_position = $.fn.position;
    +
    +function getOffsets( offsets, width, height ) {
    +	return [
    +		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
    +		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
    +	];
    +}
    +
    +function parseCss( element, property ) {
    +	return parseInt( $.css( element, property ), 10 ) || 0;
    +}
    +
    +function getDimensions( elem ) {
    +	var raw = elem[ 0 ];
    +	if ( raw.nodeType === 9 ) {
    +		return {
    +			width: elem.width(),
    +			height: elem.height(),
    +			offset: { top: 0, left: 0 }
    +		};
    +	}
    +	if ( $.isWindow( raw ) ) {
    +		return {
    +			width: elem.width(),
    +			height: elem.height(),
    +			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
    +		};
    +	}
    +	if ( raw.preventDefault ) {
    +		return {
    +			width: 0,
    +			height: 0,
    +			offset: { top: raw.pageY, left: raw.pageX }
    +		};
    +	}
    +	return {
    +		width: elem.outerWidth(),
    +		height: elem.outerHeight(),
    +		offset: elem.offset()
    +	};
    +}
    +
    +$.position = {
    +	scrollbarWidth: function() {
    +		if ( cachedScrollbarWidth !== undefined ) {
    +			return cachedScrollbarWidth;
    +		}
    +		var w1, w2,
    +			div = $( "<div " +
    +				"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
    +				"<div style='height:100px;width:auto;'></div></div>" ),
    +			innerDiv = div.children()[ 0 ];
    +
    +		$( "body" ).append( div );
    +		w1 = innerDiv.offsetWidth;
    +		div.css( "overflow", "scroll" );
    +
    +		w2 = innerDiv.offsetWidth;
    +
    +		if ( w1 === w2 ) {
    +			w2 = div[ 0 ].clientWidth;
    +		}
    +
    +		div.remove();
    +
    +		return ( cachedScrollbarWidth = w1 - w2 );
    +	},
    +	getScrollInfo: function( within ) {
    +		var overflowX = within.isWindow || within.isDocument ? "" :
    +				within.element.css( "overflow-x" ),
    +			overflowY = within.isWindow || within.isDocument ? "" :
    +				within.element.css( "overflow-y" ),
    +			hasOverflowX = overflowX === "scroll" ||
    +				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
    +			hasOverflowY = overflowY === "scroll" ||
    +				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
    +		return {
    +			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
    +			height: hasOverflowX ? $.position.scrollbarWidth() : 0
    +		};
    +	},
    +	getWithinInfo: function( element ) {
    +		var withinElement = $( element || window ),
    +			isWindow = $.isWindow( withinElement[ 0 ] ),
    +			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
    +			hasOffset = !isWindow && !isDocument;
    +		return {
    +			element: withinElement,
    +			isWindow: isWindow,
    +			isDocument: isDocument,
    +			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
    +			scrollLeft: withinElement.scrollLeft(),
    +			scrollTop: withinElement.scrollTop(),
    +			width: withinElement.outerWidth(),
    +			height: withinElement.outerHeight()
    +		};
    +	}
    +};
    +
    +$.fn.position = function( options ) {
    +	if ( !options || !options.of ) {
    +		return _position.apply( this, arguments );
    +	}
    +
    +	// Make a copy, we don't want to modify arguments
    +	options = $.extend( {}, options );
    +
    +	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
    +		target = $( options.of ),
    +		within = $.position.getWithinInfo( options.within ),
    +		scrollInfo = $.position.getScrollInfo( within ),
    +		collision = ( options.collision || "flip" ).split( " " ),
    +		offsets = {};
    +
    +	dimensions = getDimensions( target );
    +	if ( target[ 0 ].preventDefault ) {
    +
    +		// Force left top to allow flipping
    +		options.at = "left top";
    +	}
    +	targetWidth = dimensions.width;
    +	targetHeight = dimensions.height;
    +	targetOffset = dimensions.offset;
    +
    +	// Clone to reuse original targetOffset later
    +	basePosition = $.extend( {}, targetOffset );
    +
    +	// Force my and at to have valid horizontal and vertical positions
    +	// if a value is missing or invalid, it will be converted to center
    +	$.each( [ "my", "at" ], function() {
    +		var pos = ( options[ this ] || "" ).split( " " ),
    +			horizontalOffset,
    +			verticalOffset;
    +
    +		if ( pos.length === 1 ) {
    +			pos = rhorizontal.test( pos[ 0 ] ) ?
    +				pos.concat( [ "center" ] ) :
    +				rvertical.test( pos[ 0 ] ) ?
    +					[ "center" ].concat( pos ) :
    +					[ "center", "center" ];
    +		}
    +		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
    +		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
    +
    +		// Calculate offsets
    +		horizontalOffset = roffset.exec( pos[ 0 ] );
    +		verticalOffset = roffset.exec( pos[ 1 ] );
    +		offsets[ this ] = [
    +			horizontalOffset ? horizontalOffset[ 0 ] : 0,
    +			verticalOffset ? verticalOffset[ 0 ] : 0
    +		];
    +
    +		// Reduce to just the positions without the offsets
    +		options[ this ] = [
    +			rposition.exec( pos[ 0 ] )[ 0 ],
    +			rposition.exec( pos[ 1 ] )[ 0 ]
    +		];
    +	} );
    +
    +	// Normalize collision option
    +	if ( collision.length === 1 ) {
    +		collision[ 1 ] = collision[ 0 ];
    +	}
    +
    +	if ( options.at[ 0 ] === "right" ) {
    +		basePosition.left += targetWidth;
    +	} else if ( options.at[ 0 ] === "center" ) {
    +		basePosition.left += targetWidth / 2;
    +	}
    +
    +	if ( options.at[ 1 ] === "bottom" ) {
    +		basePosition.top += targetHeight;
    +	} else if ( options.at[ 1 ] === "center" ) {
    +		basePosition.top += targetHeight / 2;
    +	}
    +
    +	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
    +	basePosition.left += atOffset[ 0 ];
    +	basePosition.top += atOffset[ 1 ];
    +
    +	return this.each( function() {
    +		var collisionPosition, using,
    +			elem = $( this ),
    +			elemWidth = elem.outerWidth(),
    +			elemHeight = elem.outerHeight(),
    +			marginLeft = parseCss( this, "marginLeft" ),
    +			marginTop = parseCss( this, "marginTop" ),
    +			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
    +				scrollInfo.width,
    +			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
    +				scrollInfo.height,
    +			position = $.extend( {}, basePosition ),
    +			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
    +
    +		if ( options.my[ 0 ] === "right" ) {
    +			position.left -= elemWidth;
    +		} else if ( options.my[ 0 ] === "center" ) {
    +			position.left -= elemWidth / 2;
    +		}
    +
    +		if ( options.my[ 1 ] === "bottom" ) {
    +			position.top -= elemHeight;
    +		} else if ( options.my[ 1 ] === "center" ) {
    +			position.top -= elemHeight / 2;
    +		}
    +
    +		position.left += myOffset[ 0 ];
    +		position.top += myOffset[ 1 ];
    +
    +		collisionPosition = {
    +			marginLeft: marginLeft,
    +			marginTop: marginTop
    +		};
    +
    +		$.each( [ "left", "top" ], function( i, dir ) {
    +			if ( $.ui.position[ collision[ i ] ] ) {
    +				$.ui.position[ collision[ i ] ][ dir ]( position, {
    +					targetWidth: targetWidth,
    +					targetHeight: targetHeight,
    +					elemWidth: elemWidth,
    +					elemHeight: elemHeight,
    +					collisionPosition: collisionPosition,
    +					collisionWidth: collisionWidth,
    +					collisionHeight: collisionHeight,
    +					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
    +					my: options.my,
    +					at: options.at,
    +					within: within,
    +					elem: elem
    +				} );
    +			}
    +		} );
    +
    +		if ( options.using ) {
    +
    +			// Adds feedback as second argument to using callback, if present
    +			using = function( props ) {
    +				var left = targetOffset.left - position.left,
    +					right = left + targetWidth - elemWidth,
    +					top = targetOffset.top - position.top,
    +					bottom = top + targetHeight - elemHeight,
    +					feedback = {
    +						target: {
    +							element: target,
    +							left: targetOffset.left,
    +							top: targetOffset.top,
    +							width: targetWidth,
    +							height: targetHeight
    +						},
    +						element: {
    +							element: elem,
    +							left: position.left,
    +							top: position.top,
    +							width: elemWidth,
    +							height: elemHeight
    +						},
    +						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
    +						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
    +					};
    +				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
    +					feedback.horizontal = "center";
    +				}
    +				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
    +					feedback.vertical = "middle";
    +				}
    +				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
    +					feedback.important = "horizontal";
    +				} else {
    +					feedback.important = "vertical";
    +				}
    +				options.using.call( this, props, feedback );
    +			};
    +		}
    +
    +		elem.offset( $.extend( position, { using: using } ) );
    +	} );
    +};
    +
    +$.ui.position = {
    +	fit: {
    +		left: function( position, data ) {
    +			var within = data.within,
    +				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
    +				outerWidth = within.width,
    +				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
    +				overLeft = withinOffset - collisionPosLeft,
    +				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
    +				newOverRight;
    +
    +			// Element is wider than within
    +			if ( data.collisionWidth > outerWidth ) {
    +
    +				// Element is initially over the left side of within
    +				if ( overLeft > 0 && overRight <= 0 ) {
    +					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
    +						withinOffset;
    +					position.left += overLeft - newOverRight;
    +
    +				// Element is initially over right side of within
    +				} else if ( overRight > 0 && overLeft <= 0 ) {
    +					position.left = withinOffset;
    +
    +				// Element is initially over both left and right sides of within
    +				} else {
    +					if ( overLeft > overRight ) {
    +						position.left = withinOffset + outerWidth - data.collisionWidth;
    +					} else {
    +						position.left = withinOffset;
    +					}
    +				}
    +
    +			// Too far left -> align with left edge
    +			} else if ( overLeft > 0 ) {
    +				position.left += overLeft;
    +
    +			// Too far right -> align with right edge
    +			} else if ( overRight > 0 ) {
    +				position.left -= overRight;
    +
    +			// Adjust based on position and margin
    +			} else {
    +				position.left = max( position.left - collisionPosLeft, position.left );
    +			}
    +		},
    +		top: function( position, data ) {
    +			var within = data.within,
    +				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
    +				outerHeight = data.within.height,
    +				collisionPosTop = position.top - data.collisionPosition.marginTop,
    +				overTop = withinOffset - collisionPosTop,
    +				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
    +				newOverBottom;
    +
    +			// Element is taller than within
    +			if ( data.collisionHeight > outerHeight ) {
    +
    +				// Element is initially over the top of within
    +				if ( overTop > 0 && overBottom <= 0 ) {
    +					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
    +						withinOffset;
    +					position.top += overTop - newOverBottom;
    +
    +				// Element is initially over bottom of within
    +				} else if ( overBottom > 0 && overTop <= 0 ) {
    +					position.top = withinOffset;
    +
    +				// Element is initially over both top and bottom of within
    +				} else {
    +					if ( overTop > overBottom ) {
    +						position.top = withinOffset + outerHeight - data.collisionHeight;
    +					} else {
    +						position.top = withinOffset;
    +					}
    +				}
    +
    +			// Too far up -> align with top
    +			} else if ( overTop > 0 ) {
    +				position.top += overTop;
    +
    +			// Too far down -> align with bottom edge
    +			} else if ( overBottom > 0 ) {
    +				position.top -= overBottom;
    +
    +			// Adjust based on position and margin
    +			} else {
    +				position.top = max( position.top - collisionPosTop, position.top );
    +			}
    +		}
    +	},
    +	flip: {
    +		left: function( position, data ) {
    +			var within = data.within,
    +				withinOffset = within.offset.left + within.scrollLeft,
    +				outerWidth = within.width,
    +				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
    +				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
    +				overLeft = collisionPosLeft - offsetLeft,
    +				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
    +				myOffset = data.my[ 0 ] === "left" ?
    +					-data.elemWidth :
    +					data.my[ 0 ] === "right" ?
    +						data.elemWidth :
    +						0,
    +				atOffset = data.at[ 0 ] === "left" ?
    +					data.targetWidth :
    +					data.at[ 0 ] === "right" ?
    +						-data.targetWidth :
    +						0,
    +				offset = -2 * data.offset[ 0 ],
    +				newOverRight,
    +				newOverLeft;
    +
    +			if ( overLeft < 0 ) {
    +				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
    +					outerWidth - withinOffset;
    +				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
    +					position.left += myOffset + atOffset + offset;
    +				}
    +			} else if ( overRight > 0 ) {
    +				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
    +					atOffset + offset - offsetLeft;
    +				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
    +					position.left += myOffset + atOffset + offset;
    +				}
    +			}
    +		},
    +		top: function( position, data ) {
    +			var within = data.within,
    +				withinOffset = within.offset.top + within.scrollTop,
    +				outerHeight = within.height,
    +				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
    +				collisionPosTop = position.top - data.collisionPosition.marginTop,
    +				overTop = collisionPosTop - offsetTop,
    +				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
    +				top = data.my[ 1 ] === "top",
    +				myOffset = top ?
    +					-data.elemHeight :
    +					data.my[ 1 ] === "bottom" ?
    +						data.elemHeight :
    +						0,
    +				atOffset = data.at[ 1 ] === "top" ?
    +					data.targetHeight :
    +					data.at[ 1 ] === "bottom" ?
    +						-data.targetHeight :
    +						0,
    +				offset = -2 * data.offset[ 1 ],
    +				newOverTop,
    +				newOverBottom;
    +			if ( overTop < 0 ) {
    +				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
    +					outerHeight - withinOffset;
    +				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
    +					position.top += myOffset + atOffset + offset;
    +				}
    +			} else if ( overBottom > 0 ) {
    +				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
    +					offset - offsetTop;
    +				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
    +					position.top += myOffset + atOffset + offset;
    +				}
    +			}
    +		}
    +	},
    +	flipfit: {
    +		left: function() {
    +			$.ui.position.flip.left.apply( this, arguments );
    +			$.ui.position.fit.left.apply( this, arguments );
    +		},
    +		top: function() {
    +			$.ui.position.flip.top.apply( this, arguments );
    +			$.ui.position.fit.top.apply( this, arguments );
    +		}
    +	}
    +};
    +
    +} )();
    +
    +var position = $.ui.position;
    +
    +
    +/*!
    + * jQuery UI :data 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: :data Selector
    +//>>group: Core
    +//>>description: Selects elements which have data stored under the specified key.
    +//>>docs: http://api.jqueryui.com/data-selector/
    +
    +
    +var data = $.extend( $.expr[ ":" ], {
    +	data: $.expr.createPseudo ?
    +		$.expr.createPseudo( function( dataName ) {
    +			return function( elem ) {
    +				return !!$.data( elem, dataName );
    +			};
    +		} ) :
    +
    +		// Support: jQuery <1.8
    +		function( elem, i, match ) {
    +			return !!$.data( elem, match[ 3 ] );
    +		}
    +} );
    +
    +/*!
    + * jQuery UI Disable Selection 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: disableSelection
    +//>>group: Core
    +//>>description: Disable selection of text content within the set of matched elements.
    +//>>docs: http://api.jqueryui.com/disableSelection/
    +
    +// This file is deprecated
    +
    +
    +var disableSelection = $.fn.extend( {
    +	disableSelection: ( function() {
    +		var eventType = "onselectstart" in document.createElement( "div" ) ?
    +			"selectstart" :
    +			"mousedown";
    +
    +		return function() {
    +			return this.on( eventType + ".ui-disableSelection", function( event ) {
    +				event.preventDefault();
    +			} );
    +		};
    +	} )(),
    +
    +	enableSelection: function() {
    +		return this.off( ".ui-disableSelection" );
    +	}
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Effects Core
    +//>>group: Effects
    +// jscs:disable maximumLineLength
    +//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
    +// jscs:enable maximumLineLength
    +//>>docs: http://api.jqueryui.com/category/effects-core/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var dataSpace = "ui-effects-",
    +	dataSpaceStyle = "ui-effects-style",
    +	dataSpaceAnimated = "ui-effects-animated",
    +
    +	// Create a local jQuery because jQuery Color relies on it and the
    +	// global may not exist with AMD and a custom build (#10199)
    +	jQuery = $;
    +
    +$.effects = {
    +	effect: {}
    +};
    +
    +/*!
    + * jQuery Color Animations v2.1.2
    + * https://github.com/jquery/jquery-color
    + *
    + * Copyright 2014 jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + *
    + * Date: Wed Jan 16 08:47:09 2013 -0600
    + */
    +( function( jQuery, undefined ) {
    +
    +	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
    +		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
    +
    +	// Plusequals test for += 100 -= 100
    +	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
    +
    +	// A set of RE's that can match strings and generate color tuples.
    +	stringParsers = [ {
    +			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
    +			parse: function( execResult ) {
    +				return [
    +					execResult[ 1 ],
    +					execResult[ 2 ],
    +					execResult[ 3 ],
    +					execResult[ 4 ]
    +				];
    +			}
    +		}, {
    +			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
    +			parse: function( execResult ) {
    +				return [
    +					execResult[ 1 ] * 2.55,
    +					execResult[ 2 ] * 2.55,
    +					execResult[ 3 ] * 2.55,
    +					execResult[ 4 ]
    +				];
    +			}
    +		}, {
    +
    +			// This regex ignores A-F because it's compared against an already lowercased string
    +			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
    +			parse: function( execResult ) {
    +				return [
    +					parseInt( execResult[ 1 ], 16 ),
    +					parseInt( execResult[ 2 ], 16 ),
    +					parseInt( execResult[ 3 ], 16 )
    +				];
    +			}
    +		}, {
    +
    +			// This regex ignores A-F because it's compared against an already lowercased string
    +			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
    +			parse: function( execResult ) {
    +				return [
    +					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
    +					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
    +					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
    +				];
    +			}
    +		}, {
    +			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
    +			space: "hsla",
    +			parse: function( execResult ) {
    +				return [
    +					execResult[ 1 ],
    +					execResult[ 2 ] / 100,
    +					execResult[ 3 ] / 100,
    +					execResult[ 4 ]
    +				];
    +			}
    +		} ],
    +
    +	// JQuery.Color( )
    +	color = jQuery.Color = function( color, green, blue, alpha ) {
    +		return new jQuery.Color.fn.parse( color, green, blue, alpha );
    +	},
    +	spaces = {
    +		rgba: {
    +			props: {
    +				red: {
    +					idx: 0,
    +					type: "byte"
    +				},
    +				green: {
    +					idx: 1,
    +					type: "byte"
    +				},
    +				blue: {
    +					idx: 2,
    +					type: "byte"
    +				}
    +			}
    +		},
    +
    +		hsla: {
    +			props: {
    +				hue: {
    +					idx: 0,
    +					type: "degrees"
    +				},
    +				saturation: {
    +					idx: 1,
    +					type: "percent"
    +				},
    +				lightness: {
    +					idx: 2,
    +					type: "percent"
    +				}
    +			}
    +		}
    +	},
    +	propTypes = {
    +		"byte": {
    +			floor: true,
    +			max: 255
    +		},
    +		"percent": {
    +			max: 1
    +		},
    +		"degrees": {
    +			mod: 360,
    +			floor: true
    +		}
    +	},
    +	support = color.support = {},
    +
    +	// Element for support tests
    +	supportElem = jQuery( "<p>" )[ 0 ],
    +
    +	// Colors = jQuery.Color.names
    +	colors,
    +
    +	// Local aliases of functions called often
    +	each = jQuery.each;
    +
    +// Determine rgba support immediately
    +supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
    +support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
    +
    +// Define cache name and alpha properties
    +// for rgba and hsla spaces
    +each( spaces, function( spaceName, space ) {
    +	space.cache = "_" + spaceName;
    +	space.props.alpha = {
    +		idx: 3,
    +		type: "percent",
    +		def: 1
    +	};
    +} );
    +
    +function clamp( value, prop, allowEmpty ) {
    +	var type = propTypes[ prop.type ] || {};
    +
    +	if ( value == null ) {
    +		return ( allowEmpty || !prop.def ) ? null : prop.def;
    +	}
    +
    +	// ~~ is an short way of doing floor for positive numbers
    +	value = type.floor ? ~~value : parseFloat( value );
    +
    +	// IE will pass in empty strings as value for alpha,
    +	// which will hit this case
    +	if ( isNaN( value ) ) {
    +		return prop.def;
    +	}
    +
    +	if ( type.mod ) {
    +
    +		// We add mod before modding to make sure that negatives values
    +		// get converted properly: -10 -> 350
    +		return ( value + type.mod ) % type.mod;
    +	}
    +
    +	// For now all property types without mod have min and max
    +	return 0 > value ? 0 : type.max < value ? type.max : value;
    +}
    +
    +function stringParse( string ) {
    +	var inst = color(),
    +		rgba = inst._rgba = [];
    +
    +	string = string.toLowerCase();
    +
    +	each( stringParsers, function( i, parser ) {
    +		var parsed,
    +			match = parser.re.exec( string ),
    +			values = match && parser.parse( match ),
    +			spaceName = parser.space || "rgba";
    +
    +		if ( values ) {
    +			parsed = inst[ spaceName ]( values );
    +
    +			// If this was an rgba parse the assignment might happen twice
    +			// oh well....
    +			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
    +			rgba = inst._rgba = parsed._rgba;
    +
    +			// Exit each( stringParsers ) here because we matched
    +			return false;
    +		}
    +	} );
    +
    +	// Found a stringParser that handled it
    +	if ( rgba.length ) {
    +
    +		// If this came from a parsed string, force "transparent" when alpha is 0
    +		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
    +		if ( rgba.join() === "0,0,0,0" ) {
    +			jQuery.extend( rgba, colors.transparent );
    +		}
    +		return inst;
    +	}
    +
    +	// Named colors
    +	return colors[ string ];
    +}
    +
    +color.fn = jQuery.extend( color.prototype, {
    +	parse: function( red, green, blue, alpha ) {
    +		if ( red === undefined ) {
    +			this._rgba = [ null, null, null, null ];
    +			return this;
    +		}
    +		if ( red.jquery || red.nodeType ) {
    +			red = jQuery( red ).css( green );
    +			green = undefined;
    +		}
    +
    +		var inst = this,
    +			type = jQuery.type( red ),
    +			rgba = this._rgba = [];
    +
    +		// More than 1 argument specified - assume ( red, green, blue, alpha )
    +		if ( green !== undefined ) {
    +			red = [ red, green, blue, alpha ];
    +			type = "array";
    +		}
    +
    +		if ( type === "string" ) {
    +			return this.parse( stringParse( red ) || colors._default );
    +		}
    +
    +		if ( type === "array" ) {
    +			each( spaces.rgba.props, function( key, prop ) {
    +				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
    +			} );
    +			return this;
    +		}
    +
    +		if ( type === "object" ) {
    +			if ( red instanceof color ) {
    +				each( spaces, function( spaceName, space ) {
    +					if ( red[ space.cache ] ) {
    +						inst[ space.cache ] = red[ space.cache ].slice();
    +					}
    +				} );
    +			} else {
    +				each( spaces, function( spaceName, space ) {
    +					var cache = space.cache;
    +					each( space.props, function( key, prop ) {
    +
    +						// If the cache doesn't exist, and we know how to convert
    +						if ( !inst[ cache ] && space.to ) {
    +
    +							// If the value was null, we don't need to copy it
    +							// if the key was alpha, we don't need to copy it either
    +							if ( key === "alpha" || red[ key ] == null ) {
    +								return;
    +							}
    +							inst[ cache ] = space.to( inst._rgba );
    +						}
    +
    +						// This is the only case where we allow nulls for ALL properties.
    +						// call clamp with alwaysAllowEmpty
    +						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
    +					} );
    +
    +					// Everything defined but alpha?
    +					if ( inst[ cache ] &&
    +							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
    +
    +						// Use the default of 1
    +						inst[ cache ][ 3 ] = 1;
    +						if ( space.from ) {
    +							inst._rgba = space.from( inst[ cache ] );
    +						}
    +					}
    +				} );
    +			}
    +			return this;
    +		}
    +	},
    +	is: function( compare ) {
    +		var is = color( compare ),
    +			same = true,
    +			inst = this;
    +
    +		each( spaces, function( _, space ) {
    +			var localCache,
    +				isCache = is[ space.cache ];
    +			if ( isCache ) {
    +				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
    +				each( space.props, function( _, prop ) {
    +					if ( isCache[ prop.idx ] != null ) {
    +						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
    +						return same;
    +					}
    +				} );
    +			}
    +			return same;
    +		} );
    +		return same;
    +	},
    +	_space: function() {
    +		var used = [],
    +			inst = this;
    +		each( spaces, function( spaceName, space ) {
    +			if ( inst[ space.cache ] ) {
    +				used.push( spaceName );
    +			}
    +		} );
    +		return used.pop();
    +	},
    +	transition: function( other, distance ) {
    +		var end = color( other ),
    +			spaceName = end._space(),
    +			space = spaces[ spaceName ],
    +			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
    +			start = startColor[ space.cache ] || space.to( startColor._rgba ),
    +			result = start.slice();
    +
    +		end = end[ space.cache ];
    +		each( space.props, function( key, prop ) {
    +			var index = prop.idx,
    +				startValue = start[ index ],
    +				endValue = end[ index ],
    +				type = propTypes[ prop.type ] || {};
    +
    +			// If null, don't override start value
    +			if ( endValue === null ) {
    +				return;
    +			}
    +
    +			// If null - use end
    +			if ( startValue === null ) {
    +				result[ index ] = endValue;
    +			} else {
    +				if ( type.mod ) {
    +					if ( endValue - startValue > type.mod / 2 ) {
    +						startValue += type.mod;
    +					} else if ( startValue - endValue > type.mod / 2 ) {
    +						startValue -= type.mod;
    +					}
    +				}
    +				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
    +			}
    +		} );
    +		return this[ spaceName ]( result );
    +	},
    +	blend: function( opaque ) {
    +
    +		// If we are already opaque - return ourself
    +		if ( this._rgba[ 3 ] === 1 ) {
    +			return this;
    +		}
    +
    +		var rgb = this._rgba.slice(),
    +			a = rgb.pop(),
    +			blend = color( opaque )._rgba;
    +
    +		return color( jQuery.map( rgb, function( v, i ) {
    +			return ( 1 - a ) * blend[ i ] + a * v;
    +		} ) );
    +	},
    +	toRgbaString: function() {
    +		var prefix = "rgba(",
    +			rgba = jQuery.map( this._rgba, function( v, i ) {
    +				return v == null ? ( i > 2 ? 1 : 0 ) : v;
    +			} );
    +
    +		if ( rgba[ 3 ] === 1 ) {
    +			rgba.pop();
    +			prefix = "rgb(";
    +		}
    +
    +		return prefix + rgba.join() + ")";
    +	},
    +	toHslaString: function() {
    +		var prefix = "hsla(",
    +			hsla = jQuery.map( this.hsla(), function( v, i ) {
    +				if ( v == null ) {
    +					v = i > 2 ? 1 : 0;
    +				}
    +
    +				// Catch 1 and 2
    +				if ( i && i < 3 ) {
    +					v = Math.round( v * 100 ) + "%";
    +				}
    +				return v;
    +			} );
    +
    +		if ( hsla[ 3 ] === 1 ) {
    +			hsla.pop();
    +			prefix = "hsl(";
    +		}
    +		return prefix + hsla.join() + ")";
    +	},
    +	toHexString: function( includeAlpha ) {
    +		var rgba = this._rgba.slice(),
    +			alpha = rgba.pop();
    +
    +		if ( includeAlpha ) {
    +			rgba.push( ~~( alpha * 255 ) );
    +		}
    +
    +		return "#" + jQuery.map( rgba, function( v ) {
    +
    +			// Default to 0 when nulls exist
    +			v = ( v || 0 ).toString( 16 );
    +			return v.length === 1 ? "0" + v : v;
    +		} ).join( "" );
    +	},
    +	toString: function() {
    +		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
    +	}
    +} );
    +color.fn.parse.prototype = color.fn;
    +
    +// Hsla conversions adapted from:
    +// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
    +
    +function hue2rgb( p, q, h ) {
    +	h = ( h + 1 ) % 1;
    +	if ( h * 6 < 1 ) {
    +		return p + ( q - p ) * h * 6;
    +	}
    +	if ( h * 2 < 1 ) {
    +		return q;
    +	}
    +	if ( h * 3 < 2 ) {
    +		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
    +	}
    +	return p;
    +}
    +
    +spaces.hsla.to = function( rgba ) {
    +	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
    +		return [ null, null, null, rgba[ 3 ] ];
    +	}
    +	var r = rgba[ 0 ] / 255,
    +		g = rgba[ 1 ] / 255,
    +		b = rgba[ 2 ] / 255,
    +		a = rgba[ 3 ],
    +		max = Math.max( r, g, b ),
    +		min = Math.min( r, g, b ),
    +		diff = max - min,
    +		add = max + min,
    +		l = add * 0.5,
    +		h, s;
    +
    +	if ( min === max ) {
    +		h = 0;
    +	} else if ( r === max ) {
    +		h = ( 60 * ( g - b ) / diff ) + 360;
    +	} else if ( g === max ) {
    +		h = ( 60 * ( b - r ) / diff ) + 120;
    +	} else {
    +		h = ( 60 * ( r - g ) / diff ) + 240;
    +	}
    +
    +	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
    +	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
    +	if ( diff === 0 ) {
    +		s = 0;
    +	} else if ( l <= 0.5 ) {
    +		s = diff / add;
    +	} else {
    +		s = diff / ( 2 - add );
    +	}
    +	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
    +};
    +
    +spaces.hsla.from = function( hsla ) {
    +	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
    +		return [ null, null, null, hsla[ 3 ] ];
    +	}
    +	var h = hsla[ 0 ] / 360,
    +		s = hsla[ 1 ],
    +		l = hsla[ 2 ],
    +		a = hsla[ 3 ],
    +		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
    +		p = 2 * l - q;
    +
    +	return [
    +		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
    +		Math.round( hue2rgb( p, q, h ) * 255 ),
    +		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
    +		a
    +	];
    +};
    +
    +each( spaces, function( spaceName, space ) {
    +	var props = space.props,
    +		cache = space.cache,
    +		to = space.to,
    +		from = space.from;
    +
    +	// Makes rgba() and hsla()
    +	color.fn[ spaceName ] = function( value ) {
    +
    +		// Generate a cache for this space if it doesn't exist
    +		if ( to && !this[ cache ] ) {
    +			this[ cache ] = to( this._rgba );
    +		}
    +		if ( value === undefined ) {
    +			return this[ cache ].slice();
    +		}
    +
    +		var ret,
    +			type = jQuery.type( value ),
    +			arr = ( type === "array" || type === "object" ) ? value : arguments,
    +			local = this[ cache ].slice();
    +
    +		each( props, function( key, prop ) {
    +			var val = arr[ type === "object" ? key : prop.idx ];
    +			if ( val == null ) {
    +				val = local[ prop.idx ];
    +			}
    +			local[ prop.idx ] = clamp( val, prop );
    +		} );
    +
    +		if ( from ) {
    +			ret = color( from( local ) );
    +			ret[ cache ] = local;
    +			return ret;
    +		} else {
    +			return color( local );
    +		}
    +	};
    +
    +	// Makes red() green() blue() alpha() hue() saturation() lightness()
    +	each( props, function( key, prop ) {
    +
    +		// Alpha is included in more than one space
    +		if ( color.fn[ key ] ) {
    +			return;
    +		}
    +		color.fn[ key ] = function( value ) {
    +			var vtype = jQuery.type( value ),
    +				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
    +				local = this[ fn ](),
    +				cur = local[ prop.idx ],
    +				match;
    +
    +			if ( vtype === "undefined" ) {
    +				return cur;
    +			}
    +
    +			if ( vtype === "function" ) {
    +				value = value.call( this, cur );
    +				vtype = jQuery.type( value );
    +			}
    +			if ( value == null && prop.empty ) {
    +				return this;
    +			}
    +			if ( vtype === "string" ) {
    +				match = rplusequals.exec( value );
    +				if ( match ) {
    +					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
    +				}
    +			}
    +			local[ prop.idx ] = value;
    +			return this[ fn ]( local );
    +		};
    +	} );
    +} );
    +
    +// Add cssHook and .fx.step function for each named hook.
    +// accept a space separated string of properties
    +color.hook = function( hook ) {
    +	var hooks = hook.split( " " );
    +	each( hooks, function( i, hook ) {
    +		jQuery.cssHooks[ hook ] = {
    +			set: function( elem, value ) {
    +				var parsed, curElem,
    +					backgroundColor = "";
    +
    +				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
    +						( parsed = stringParse( value ) ) ) ) {
    +					value = color( parsed || value );
    +					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
    +						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
    +						while (
    +							( backgroundColor === "" || backgroundColor === "transparent" ) &&
    +							curElem && curElem.style
    +						) {
    +							try {
    +								backgroundColor = jQuery.css( curElem, "backgroundColor" );
    +								curElem = curElem.parentNode;
    +							} catch ( e ) {
    +							}
    +						}
    +
    +						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
    +							backgroundColor :
    +							"_default" );
    +					}
    +
    +					value = value.toRgbaString();
    +				}
    +				try {
    +					elem.style[ hook ] = value;
    +				} catch ( e ) {
    +
    +					// Wrapped to prevent IE from throwing errors on "invalid" values like
    +					// 'auto' or 'inherit'
    +				}
    +			}
    +		};
    +		jQuery.fx.step[ hook ] = function( fx ) {
    +			if ( !fx.colorInit ) {
    +				fx.start = color( fx.elem, hook );
    +				fx.end = color( fx.end );
    +				fx.colorInit = true;
    +			}
    +			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
    +		};
    +	} );
    +
    +};
    +
    +color.hook( stepHooks );
    +
    +jQuery.cssHooks.borderColor = {
    +	expand: function( value ) {
    +		var expanded = {};
    +
    +		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
    +			expanded[ "border" + part + "Color" ] = value;
    +		} );
    +		return expanded;
    +	}
    +};
    +
    +// Basic color names only.
    +// Usage of any of the other color names requires adding yourself or including
    +// jquery.color.svg-names.js.
    +colors = jQuery.Color.names = {
    +
    +	// 4.1. Basic color keywords
    +	aqua: "#00ffff",
    +	black: "#000000",
    +	blue: "#0000ff",
    +	fuchsia: "#ff00ff",
    +	gray: "#808080",
    +	green: "#008000",
    +	lime: "#00ff00",
    +	maroon: "#800000",
    +	navy: "#000080",
    +	olive: "#808000",
    +	purple: "#800080",
    +	red: "#ff0000",
    +	silver: "#c0c0c0",
    +	teal: "#008080",
    +	white: "#ffffff",
    +	yellow: "#ffff00",
    +
    +	// 4.2.3. "transparent" color keyword
    +	transparent: [ null, null, null, 0 ],
    +
    +	_default: "#ffffff"
    +};
    +
    +} )( jQuery );
    +
    +/******************************************************************************/
    +/****************************** CLASS ANIMATIONS ******************************/
    +/******************************************************************************/
    +( function() {
    +
    +var classAnimationActions = [ "add", "remove", "toggle" ],
    +	shorthandStyles = {
    +		border: 1,
    +		borderBottom: 1,
    +		borderColor: 1,
    +		borderLeft: 1,
    +		borderRight: 1,
    +		borderTop: 1,
    +		borderWidth: 1,
    +		margin: 1,
    +		padding: 1
    +	};
    +
    +$.each(
    +	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
    +	function( _, prop ) {
    +		$.fx.step[ prop ] = function( fx ) {
    +			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
    +				jQuery.style( fx.elem, prop, fx.end );
    +				fx.setAttr = true;
    +			}
    +		};
    +	}
    +);
    +
    +function getElementStyles( elem ) {
    +	var key, len,
    +		style = elem.ownerDocument.defaultView ?
    +			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
    +			elem.currentStyle,
    +		styles = {};
    +
    +	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
    +		len = style.length;
    +		while ( len-- ) {
    +			key = style[ len ];
    +			if ( typeof style[ key ] === "string" ) {
    +				styles[ $.camelCase( key ) ] = style[ key ];
    +			}
    +		}
    +
    +	// Support: Opera, IE <9
    +	} else {
    +		for ( key in style ) {
    +			if ( typeof style[ key ] === "string" ) {
    +				styles[ key ] = style[ key ];
    +			}
    +		}
    +	}
    +
    +	return styles;
    +}
    +
    +function styleDifference( oldStyle, newStyle ) {
    +	var diff = {},
    +		name, value;
    +
    +	for ( name in newStyle ) {
    +		value = newStyle[ name ];
    +		if ( oldStyle[ name ] !== value ) {
    +			if ( !shorthandStyles[ name ] ) {
    +				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
    +					diff[ name ] = value;
    +				}
    +			}
    +		}
    +	}
    +
    +	return diff;
    +}
    +
    +// Support: jQuery <1.8
    +if ( !$.fn.addBack ) {
    +	$.fn.addBack = function( selector ) {
    +		return this.add( selector == null ?
    +			this.prevObject : this.prevObject.filter( selector )
    +		);
    +	};
    +}
    +
    +$.effects.animateClass = function( value, duration, easing, callback ) {
    +	var o = $.speed( duration, easing, callback );
    +
    +	return this.queue( function() {
    +		var animated = $( this ),
    +			baseClass = animated.attr( "class" ) || "",
    +			applyClassChange,
    +			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
    +
    +		// Map the animated objects to store the original styles.
    +		allAnimations = allAnimations.map( function() {
    +			var el = $( this );
    +			return {
    +				el: el,
    +				start: getElementStyles( this )
    +			};
    +		} );
    +
    +		// Apply class change
    +		applyClassChange = function() {
    +			$.each( classAnimationActions, function( i, action ) {
    +				if ( value[ action ] ) {
    +					animated[ action + "Class" ]( value[ action ] );
    +				}
    +			} );
    +		};
    +		applyClassChange();
    +
    +		// Map all animated objects again - calculate new styles and diff
    +		allAnimations = allAnimations.map( function() {
    +			this.end = getElementStyles( this.el[ 0 ] );
    +			this.diff = styleDifference( this.start, this.end );
    +			return this;
    +		} );
    +
    +		// Apply original class
    +		animated.attr( "class", baseClass );
    +
    +		// Map all animated objects again - this time collecting a promise
    +		allAnimations = allAnimations.map( function() {
    +			var styleInfo = this,
    +				dfd = $.Deferred(),
    +				opts = $.extend( {}, o, {
    +					queue: false,
    +					complete: function() {
    +						dfd.resolve( styleInfo );
    +					}
    +				} );
    +
    +			this.el.animate( this.diff, opts );
    +			return dfd.promise();
    +		} );
    +
    +		// Once all animations have completed:
    +		$.when.apply( $, allAnimations.get() ).done( function() {
    +
    +			// Set the final class
    +			applyClassChange();
    +
    +			// For each animated element,
    +			// clear all css properties that were animated
    +			$.each( arguments, function() {
    +				var el = this.el;
    +				$.each( this.diff, function( key ) {
    +					el.css( key, "" );
    +				} );
    +			} );
    +
    +			// This is guarnteed to be there if you use jQuery.speed()
    +			// it also handles dequeuing the next anim...
    +			o.complete.call( animated[ 0 ] );
    +		} );
    +	} );
    +};
    +
    +$.fn.extend( {
    +	addClass: ( function( orig ) {
    +		return function( classNames, speed, easing, callback ) {
    +			return speed ?
    +				$.effects.animateClass.call( this,
    +					{ add: classNames }, speed, easing, callback ) :
    +				orig.apply( this, arguments );
    +		};
    +	} )( $.fn.addClass ),
    +
    +	removeClass: ( function( orig ) {
    +		return function( classNames, speed, easing, callback ) {
    +			return arguments.length > 1 ?
    +				$.effects.animateClass.call( this,
    +					{ remove: classNames }, speed, easing, callback ) :
    +				orig.apply( this, arguments );
    +		};
    +	} )( $.fn.removeClass ),
    +
    +	toggleClass: ( function( orig ) {
    +		return function( classNames, force, speed, easing, callback ) {
    +			if ( typeof force === "boolean" || force === undefined ) {
    +				if ( !speed ) {
    +
    +					// Without speed parameter
    +					return orig.apply( this, arguments );
    +				} else {
    +					return $.effects.animateClass.call( this,
    +						( force ? { add: classNames } : { remove: classNames } ),
    +						speed, easing, callback );
    +				}
    +			} else {
    +
    +				// Without force parameter
    +				return $.effects.animateClass.call( this,
    +					{ toggle: classNames }, force, speed, easing );
    +			}
    +		};
    +	} )( $.fn.toggleClass ),
    +
    +	switchClass: function( remove, add, speed, easing, callback ) {
    +		return $.effects.animateClass.call( this, {
    +			add: add,
    +			remove: remove
    +		}, speed, easing, callback );
    +	}
    +} );
    +
    +} )();
    +
    +/******************************************************************************/
    +/*********************************** EFFECTS **********************************/
    +/******************************************************************************/
    +
    +( function() {
    +
    +if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
    +	$.expr.filters.animated = ( function( orig ) {
    +		return function( elem ) {
    +			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
    +		};
    +	} )( $.expr.filters.animated );
    +}
    +
    +if ( $.uiBackCompat !== false ) {
    +	$.extend( $.effects, {
    +
    +		// Saves a set of properties in a data storage
    +		save: function( element, set ) {
    +			var i = 0, length = set.length;
    +			for ( ; i < length; i++ ) {
    +				if ( set[ i ] !== null ) {
    +					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
    +				}
    +			}
    +		},
    +
    +		// Restores a set of previously saved properties from a data storage
    +		restore: function( element, set ) {
    +			var val, i = 0, length = set.length;
    +			for ( ; i < length; i++ ) {
    +				if ( set[ i ] !== null ) {
    +					val = element.data( dataSpace + set[ i ] );
    +					element.css( set[ i ], val );
    +				}
    +			}
    +		},
    +
    +		setMode: function( el, mode ) {
    +			if ( mode === "toggle" ) {
    +				mode = el.is( ":hidden" ) ? "show" : "hide";
    +			}
    +			return mode;
    +		},
    +
    +		// Wraps the element around a wrapper that copies position properties
    +		createWrapper: function( element ) {
    +
    +			// If the element is already wrapped, return it
    +			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
    +				return element.parent();
    +			}
    +
    +			// Wrap the element
    +			var props = {
    +					width: element.outerWidth( true ),
    +					height: element.outerHeight( true ),
    +					"float": element.css( "float" )
    +				},
    +				wrapper = $( "<div></div>" )
    +					.addClass( "ui-effects-wrapper" )
    +					.css( {
    +						fontSize: "100%",
    +						background: "transparent",
    +						border: "none",
    +						margin: 0,
    +						padding: 0
    +					} ),
    +
    +				// Store the size in case width/height are defined in % - Fixes #5245
    +				size = {
    +					width: element.width(),
    +					height: element.height()
    +				},
    +				active = document.activeElement;
    +
    +			// Support: Firefox
    +			// Firefox incorrectly exposes anonymous content
    +			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
    +			try {
    +				active.id;
    +			} catch ( e ) {
    +				active = document.body;
    +			}
    +
    +			element.wrap( wrapper );
    +
    +			// Fixes #7595 - Elements lose focus when wrapped.
    +			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
    +				$( active ).trigger( "focus" );
    +			}
    +
    +			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
    +			// lose the reference to the wrapped element
    +			wrapper = element.parent();
    +
    +			// Transfer positioning properties to the wrapper
    +			if ( element.css( "position" ) === "static" ) {
    +				wrapper.css( { position: "relative" } );
    +				element.css( { position: "relative" } );
    +			} else {
    +				$.extend( props, {
    +					position: element.css( "position" ),
    +					zIndex: element.css( "z-index" )
    +				} );
    +				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
    +					props[ pos ] = element.css( pos );
    +					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
    +						props[ pos ] = "auto";
    +					}
    +				} );
    +				element.css( {
    +					position: "relative",
    +					top: 0,
    +					left: 0,
    +					right: "auto",
    +					bottom: "auto"
    +				} );
    +			}
    +			element.css( size );
    +
    +			return wrapper.css( props ).show();
    +		},
    +
    +		removeWrapper: function( element ) {
    +			var active = document.activeElement;
    +
    +			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
    +				element.parent().replaceWith( element );
    +
    +				// Fixes #7595 - Elements lose focus when wrapped.
    +				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
    +					$( active ).trigger( "focus" );
    +				}
    +			}
    +
    +			return element;
    +		}
    +	} );
    +}
    +
    +$.extend( $.effects, {
    +	version: "1.12.1",
    +
    +	define: function( name, mode, effect ) {
    +		if ( !effect ) {
    +			effect = mode;
    +			mode = "effect";
    +		}
    +
    +		$.effects.effect[ name ] = effect;
    +		$.effects.effect[ name ].mode = mode;
    +
    +		return effect;
    +	},
    +
    +	scaledDimensions: function( element, percent, direction ) {
    +		if ( percent === 0 ) {
    +			return {
    +				height: 0,
    +				width: 0,
    +				outerHeight: 0,
    +				outerWidth: 0
    +			};
    +		}
    +
    +		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
    +			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
    +
    +		return {
    +			height: element.height() * y,
    +			width: element.width() * x,
    +			outerHeight: element.outerHeight() * y,
    +			outerWidth: element.outerWidth() * x
    +		};
    +
    +	},
    +
    +	clipToBox: function( animation ) {
    +		return {
    +			width: animation.clip.right - animation.clip.left,
    +			height: animation.clip.bottom - animation.clip.top,
    +			left: animation.clip.left,
    +			top: animation.clip.top
    +		};
    +	},
    +
    +	// Injects recently queued functions to be first in line (after "inprogress")
    +	unshift: function( element, queueLength, count ) {
    +		var queue = element.queue();
    +
    +		if ( queueLength > 1 ) {
    +			queue.splice.apply( queue,
    +				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
    +		}
    +		element.dequeue();
    +	},
    +
    +	saveStyle: function( element ) {
    +		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
    +	},
    +
    +	restoreStyle: function( element ) {
    +		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
    +		element.removeData( dataSpaceStyle );
    +	},
    +
    +	mode: function( element, mode ) {
    +		var hidden = element.is( ":hidden" );
    +
    +		if ( mode === "toggle" ) {
    +			mode = hidden ? "show" : "hide";
    +		}
    +		if ( hidden ? mode === "hide" : mode === "show" ) {
    +			mode = "none";
    +		}
    +		return mode;
    +	},
    +
    +	// Translates a [top,left] array into a baseline value
    +	getBaseline: function( origin, original ) {
    +		var y, x;
    +
    +		switch ( origin[ 0 ] ) {
    +		case "top":
    +			y = 0;
    +			break;
    +		case "middle":
    +			y = 0.5;
    +			break;
    +		case "bottom":
    +			y = 1;
    +			break;
    +		default:
    +			y = origin[ 0 ] / original.height;
    +		}
    +
    +		switch ( origin[ 1 ] ) {
    +		case "left":
    +			x = 0;
    +			break;
    +		case "center":
    +			x = 0.5;
    +			break;
    +		case "right":
    +			x = 1;
    +			break;
    +		default:
    +			x = origin[ 1 ] / original.width;
    +		}
    +
    +		return {
    +			x: x,
    +			y: y
    +		};
    +	},
    +
    +	// Creates a placeholder element so that the original element can be made absolute
    +	createPlaceholder: function( element ) {
    +		var placeholder,
    +			cssPosition = element.css( "position" ),
    +			position = element.position();
    +
    +		// Lock in margins first to account for form elements, which
    +		// will change margin if you explicitly set height
    +		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
    +		// Support: Safari
    +		element.css( {
    +			marginTop: element.css( "marginTop" ),
    +			marginBottom: element.css( "marginBottom" ),
    +			marginLeft: element.css( "marginLeft" ),
    +			marginRight: element.css( "marginRight" )
    +		} )
    +		.outerWidth( element.outerWidth() )
    +		.outerHeight( element.outerHeight() );
    +
    +		if ( /^(static|relative)/.test( cssPosition ) ) {
    +			cssPosition = "absolute";
    +
    +			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
    +
    +				// Convert inline to inline block to account for inline elements
    +				// that turn to inline block based on content (like img)
    +				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
    +					"inline-block" :
    +					"block",
    +				visibility: "hidden",
    +
    +				// Margins need to be set to account for margin collapse
    +				marginTop: element.css( "marginTop" ),
    +				marginBottom: element.css( "marginBottom" ),
    +				marginLeft: element.css( "marginLeft" ),
    +				marginRight: element.css( "marginRight" ),
    +				"float": element.css( "float" )
    +			} )
    +			.outerWidth( element.outerWidth() )
    +			.outerHeight( element.outerHeight() )
    +			.addClass( "ui-effects-placeholder" );
    +
    +			element.data( dataSpace + "placeholder", placeholder );
    +		}
    +
    +		element.css( {
    +			position: cssPosition,
    +			left: position.left,
    +			top: position.top
    +		} );
    +
    +		return placeholder;
    +	},
    +
    +	removePlaceholder: function( element ) {
    +		var dataKey = dataSpace + "placeholder",
    +				placeholder = element.data( dataKey );
    +
    +		if ( placeholder ) {
    +			placeholder.remove();
    +			element.removeData( dataKey );
    +		}
    +	},
    +
    +	// Removes a placeholder if it exists and restores
    +	// properties that were modified during placeholder creation
    +	cleanUp: function( element ) {
    +		$.effects.restoreStyle( element );
    +		$.effects.removePlaceholder( element );
    +	},
    +
    +	setTransition: function( element, list, factor, value ) {
    +		value = value || {};
    +		$.each( list, function( i, x ) {
    +			var unit = element.cssUnit( x );
    +			if ( unit[ 0 ] > 0 ) {
    +				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
    +			}
    +		} );
    +		return value;
    +	}
    +} );
    +
    +// Return an effect options object for the given parameters:
    +function _normalizeArguments( effect, options, speed, callback ) {
    +
    +	// Allow passing all options as the first parameter
    +	if ( $.isPlainObject( effect ) ) {
    +		options = effect;
    +		effect = effect.effect;
    +	}
    +
    +	// Convert to an object
    +	effect = { effect: effect };
    +
    +	// Catch (effect, null, ...)
    +	if ( options == null ) {
    +		options = {};
    +	}
    +
    +	// Catch (effect, callback)
    +	if ( $.isFunction( options ) ) {
    +		callback = options;
    +		speed = null;
    +		options = {};
    +	}
    +
    +	// Catch (effect, speed, ?)
    +	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
    +		callback = speed;
    +		speed = options;
    +		options = {};
    +	}
    +
    +	// Catch (effect, options, callback)
    +	if ( $.isFunction( speed ) ) {
    +		callback = speed;
    +		speed = null;
    +	}
    +
    +	// Add options to effect
    +	if ( options ) {
    +		$.extend( effect, options );
    +	}
    +
    +	speed = speed || options.duration;
    +	effect.duration = $.fx.off ? 0 :
    +		typeof speed === "number" ? speed :
    +		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
    +		$.fx.speeds._default;
    +
    +	effect.complete = callback || options.complete;
    +
    +	return effect;
    +}
    +
    +function standardAnimationOption( option ) {
    +
    +	// Valid standard speeds (nothing, number, named speed)
    +	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
    +		return true;
    +	}
    +
    +	// Invalid strings - treat as "normal" speed
    +	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
    +		return true;
    +	}
    +
    +	// Complete callback
    +	if ( $.isFunction( option ) ) {
    +		return true;
    +	}
    +
    +	// Options hash (but not naming an effect)
    +	if ( typeof option === "object" && !option.effect ) {
    +		return true;
    +	}
    +
    +	// Didn't match any standard API
    +	return false;
    +}
    +
    +$.fn.extend( {
    +	effect: function( /* effect, options, speed, callback */ ) {
    +		var args = _normalizeArguments.apply( this, arguments ),
    +			effectMethod = $.effects.effect[ args.effect ],
    +			defaultMode = effectMethod.mode,
    +			queue = args.queue,
    +			queueName = queue || "fx",
    +			complete = args.complete,
    +			mode = args.mode,
    +			modes = [],
    +			prefilter = function( next ) {
    +				var el = $( this ),
    +					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
    +
    +				// Sentinel for duck-punching the :animated psuedo-selector
    +				el.data( dataSpaceAnimated, true );
    +
    +				// Save effect mode for later use,
    +				// we can't just call $.effects.mode again later,
    +				// as the .show() below destroys the initial state
    +				modes.push( normalizedMode );
    +
    +				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
    +				if ( defaultMode && ( normalizedMode === "show" ||
    +						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
    +					el.show();
    +				}
    +
    +				if ( !defaultMode || normalizedMode !== "none" ) {
    +					$.effects.saveStyle( el );
    +				}
    +
    +				if ( $.isFunction( next ) ) {
    +					next();
    +				}
    +			};
    +
    +		if ( $.fx.off || !effectMethod ) {
    +
    +			// Delegate to the original method (e.g., .show()) if possible
    +			if ( mode ) {
    +				return this[ mode ]( args.duration, complete );
    +			} else {
    +				return this.each( function() {
    +					if ( complete ) {
    +						complete.call( this );
    +					}
    +				} );
    +			}
    +		}
    +
    +		function run( next ) {
    +			var elem = $( this );
    +
    +			function cleanup() {
    +				elem.removeData( dataSpaceAnimated );
    +
    +				$.effects.cleanUp( elem );
    +
    +				if ( args.mode === "hide" ) {
    +					elem.hide();
    +				}
    +
    +				done();
    +			}
    +
    +			function done() {
    +				if ( $.isFunction( complete ) ) {
    +					complete.call( elem[ 0 ] );
    +				}
    +
    +				if ( $.isFunction( next ) ) {
    +					next();
    +				}
    +			}
    +
    +			// Override mode option on a per element basis,
    +			// as toggle can be either show or hide depending on element state
    +			args.mode = modes.shift();
    +
    +			if ( $.uiBackCompat !== false && !defaultMode ) {
    +				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
    +
    +					// Call the core method to track "olddisplay" properly
    +					elem[ mode ]();
    +					done();
    +				} else {
    +					effectMethod.call( elem[ 0 ], args, done );
    +				}
    +			} else {
    +				if ( args.mode === "none" ) {
    +
    +					// Call the core method to track "olddisplay" properly
    +					elem[ mode ]();
    +					done();
    +				} else {
    +					effectMethod.call( elem[ 0 ], args, cleanup );
    +				}
    +			}
    +		}
    +
    +		// Run prefilter on all elements first to ensure that
    +		// any showing or hiding happens before placeholder creation,
    +		// which ensures that any layout changes are correctly captured.
    +		return queue === false ?
    +			this.each( prefilter ).each( run ) :
    +			this.queue( queueName, prefilter ).queue( queueName, run );
    +	},
    +
    +	show: ( function( orig ) {
    +		return function( option ) {
    +			if ( standardAnimationOption( option ) ) {
    +				return orig.apply( this, arguments );
    +			} else {
    +				var args = _normalizeArguments.apply( this, arguments );
    +				args.mode = "show";
    +				return this.effect.call( this, args );
    +			}
    +		};
    +	} )( $.fn.show ),
    +
    +	hide: ( function( orig ) {
    +		return function( option ) {
    +			if ( standardAnimationOption( option ) ) {
    +				return orig.apply( this, arguments );
    +			} else {
    +				var args = _normalizeArguments.apply( this, arguments );
    +				args.mode = "hide";
    +				return this.effect.call( this, args );
    +			}
    +		};
    +	} )( $.fn.hide ),
    +
    +	toggle: ( function( orig ) {
    +		return function( option ) {
    +			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
    +				return orig.apply( this, arguments );
    +			} else {
    +				var args = _normalizeArguments.apply( this, arguments );
    +				args.mode = "toggle";
    +				return this.effect.call( this, args );
    +			}
    +		};
    +	} )( $.fn.toggle ),
    +
    +	cssUnit: function( key ) {
    +		var style = this.css( key ),
    +			val = [];
    +
    +		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
    +			if ( style.indexOf( unit ) > 0 ) {
    +				val = [ parseFloat( style ), unit ];
    +			}
    +		} );
    +		return val;
    +	},
    +
    +	cssClip: function( clipObj ) {
    +		if ( clipObj ) {
    +			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
    +				clipObj.bottom + "px " + clipObj.left + "px)" );
    +		}
    +		return parseClip( this.css( "clip" ), this );
    +	},
    +
    +	transfer: function( options, done ) {
    +		var element = $( this ),
    +			target = $( options.to ),
    +			targetFixed = target.css( "position" ) === "fixed",
    +			body = $( "body" ),
    +			fixTop = targetFixed ? body.scrollTop() : 0,
    +			fixLeft = targetFixed ? body.scrollLeft() : 0,
    +			endPosition = target.offset(),
    +			animation = {
    +				top: endPosition.top - fixTop,
    +				left: endPosition.left - fixLeft,
    +				height: target.innerHeight(),
    +				width: target.innerWidth()
    +			},
    +			startPosition = element.offset(),
    +			transfer = $( "<div class='ui-effects-transfer'></div>" )
    +				.appendTo( "body" )
    +				.addClass( options.className )
    +				.css( {
    +					top: startPosition.top - fixTop,
    +					left: startPosition.left - fixLeft,
    +					height: element.innerHeight(),
    +					width: element.innerWidth(),
    +					position: targetFixed ? "fixed" : "absolute"
    +				} )
    +				.animate( animation, options.duration, options.easing, function() {
    +					transfer.remove();
    +					if ( $.isFunction( done ) ) {
    +						done();
    +					}
    +				} );
    +	}
    +} );
    +
    +function parseClip( str, element ) {
    +		var outerWidth = element.outerWidth(),
    +			outerHeight = element.outerHeight(),
    +			clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
    +			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
    +
    +		return {
    +			top: parseFloat( values[ 1 ] ) || 0,
    +			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
    +			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
    +			left: parseFloat( values[ 4 ] ) || 0
    +		};
    +}
    +
    +$.fx.step.clip = function( fx ) {
    +	if ( !fx.clipInit ) {
    +		fx.start = $( fx.elem ).cssClip();
    +		if ( typeof fx.end === "string" ) {
    +			fx.end = parseClip( fx.end, fx.elem );
    +		}
    +		fx.clipInit = true;
    +	}
    +
    +	$( fx.elem ).cssClip( {
    +		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
    +		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
    +		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
    +		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
    +	} );
    +};
    +
    +} )();
    +
    +/******************************************************************************/
    +/*********************************** EASING ***********************************/
    +/******************************************************************************/
    +
    +( function() {
    +
    +// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
    +
    +var baseEasings = {};
    +
    +$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
    +	baseEasings[ name ] = function( p ) {
    +		return Math.pow( p, i + 2 );
    +	};
    +} );
    +
    +$.extend( baseEasings, {
    +	Sine: function( p ) {
    +		return 1 - Math.cos( p * Math.PI / 2 );
    +	},
    +	Circ: function( p ) {
    +		return 1 - Math.sqrt( 1 - p * p );
    +	},
    +	Elastic: function( p ) {
    +		return p === 0 || p === 1 ? p :
    +			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
    +	},
    +	Back: function( p ) {
    +		return p * p * ( 3 * p - 2 );
    +	},
    +	Bounce: function( p ) {
    +		var pow2,
    +			bounce = 4;
    +
    +		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
    +		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
    +	}
    +} );
    +
    +$.each( baseEasings, function( name, easeIn ) {
    +	$.easing[ "easeIn" + name ] = easeIn;
    +	$.easing[ "easeOut" + name ] = function( p ) {
    +		return 1 - easeIn( 1 - p );
    +	};
    +	$.easing[ "easeInOut" + name ] = function( p ) {
    +		return p < 0.5 ?
    +			easeIn( p * 2 ) / 2 :
    +			1 - easeIn( p * -2 + 2 ) / 2;
    +	};
    +} );
    +
    +} )();
    +
    +var effect = $.effects;
    +
    +
    +/*!
    + * jQuery UI Effects Blind 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Blind Effect
    +//>>group: Effects
    +//>>description: Blinds the element.
    +//>>docs: http://api.jqueryui.com/blind-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
    +	var map = {
    +			up: [ "bottom", "top" ],
    +			vertical: [ "bottom", "top" ],
    +			down: [ "top", "bottom" ],
    +			left: [ "right", "left" ],
    +			horizontal: [ "right", "left" ],
    +			right: [ "left", "right" ]
    +		},
    +		element = $( this ),
    +		direction = options.direction || "up",
    +		start = element.cssClip(),
    +		animate = { clip: $.extend( {}, start ) },
    +		placeholder = $.effects.createPlaceholder( element );
    +
    +	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
    +
    +	if ( options.mode === "show" ) {
    +		element.cssClip( animate.clip );
    +		if ( placeholder ) {
    +			placeholder.css( $.effects.clipToBox( animate ) );
    +		}
    +
    +		animate.clip = start;
    +	}
    +
    +	if ( placeholder ) {
    +		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
    +	}
    +
    +	element.animate( animate, {
    +		queue: false,
    +		duration: options.duration,
    +		easing: options.easing,
    +		complete: done
    +	} );
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Bounce 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Bounce Effect
    +//>>group: Effects
    +//>>description: Bounces an element horizontally or vertically n times.
    +//>>docs: http://api.jqueryui.com/bounce-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
    +	var upAnim, downAnim, refValue,
    +		element = $( this ),
    +
    +		// Defaults:
    +		mode = options.mode,
    +		hide = mode === "hide",
    +		show = mode === "show",
    +		direction = options.direction || "up",
    +		distance = options.distance,
    +		times = options.times || 5,
    +
    +		// Number of internal animations
    +		anims = times * 2 + ( show || hide ? 1 : 0 ),
    +		speed = options.duration / anims,
    +		easing = options.easing,
    +
    +		// Utility:
    +		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
    +		motion = ( direction === "up" || direction === "left" ),
    +		i = 0,
    +
    +		queuelen = element.queue().length;
    +
    +	$.effects.createPlaceholder( element );
    +
    +	refValue = element.css( ref );
    +
    +	// Default distance for the BIGGEST bounce is the outer Distance / 3
    +	if ( !distance ) {
    +		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
    +	}
    +
    +	if ( show ) {
    +		downAnim = { opacity: 1 };
    +		downAnim[ ref ] = refValue;
    +
    +		// If we are showing, force opacity 0 and set the initial position
    +		// then do the "first" animation
    +		element
    +			.css( "opacity", 0 )
    +			.css( ref, motion ? -distance * 2 : distance * 2 )
    +			.animate( downAnim, speed, easing );
    +	}
    +
    +	// Start at the smallest distance if we are hiding
    +	if ( hide ) {
    +		distance = distance / Math.pow( 2, times - 1 );
    +	}
    +
    +	downAnim = {};
    +	downAnim[ ref ] = refValue;
    +
    +	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
    +	for ( ; i < times; i++ ) {
    +		upAnim = {};
    +		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
    +
    +		element
    +			.animate( upAnim, speed, easing )
    +			.animate( downAnim, speed, easing );
    +
    +		distance = hide ? distance * 2 : distance / 2;
    +	}
    +
    +	// Last Bounce when Hiding
    +	if ( hide ) {
    +		upAnim = { opacity: 0 };
    +		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
    +
    +		element.animate( upAnim, speed, easing );
    +	}
    +
    +	element.queue( done );
    +
    +	$.effects.unshift( element, queuelen, anims + 1 );
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Clip 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Clip Effect
    +//>>group: Effects
    +//>>description: Clips the element on and off like an old TV.
    +//>>docs: http://api.jqueryui.com/clip-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
    +	var start,
    +		animate = {},
    +		element = $( this ),
    +		direction = options.direction || "vertical",
    +		both = direction === "both",
    +		horizontal = both || direction === "horizontal",
    +		vertical = both || direction === "vertical";
    +
    +	start = element.cssClip();
    +	animate.clip = {
    +		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
    +		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
    +		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
    +		left: horizontal ? ( start.right - start.left ) / 2 : start.left
    +	};
    +
    +	$.effects.createPlaceholder( element );
    +
    +	if ( options.mode === "show" ) {
    +		element.cssClip( animate.clip );
    +		animate.clip = start;
    +	}
    +
    +	element.animate( animate, {
    +		queue: false,
    +		duration: options.duration,
    +		easing: options.easing,
    +		complete: done
    +	} );
    +
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Drop 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Drop Effect
    +//>>group: Effects
    +//>>description: Moves an element in one direction and hides it at the same time.
    +//>>docs: http://api.jqueryui.com/drop-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
    +
    +	var distance,
    +		element = $( this ),
    +		mode = options.mode,
    +		show = mode === "show",
    +		direction = options.direction || "left",
    +		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
    +		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
    +		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
    +		animation = {
    +			opacity: 0
    +		};
    +
    +	$.effects.createPlaceholder( element );
    +
    +	distance = options.distance ||
    +		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
    +
    +	animation[ ref ] = motion + distance;
    +
    +	if ( show ) {
    +		element.css( animation );
    +
    +		animation[ ref ] = oppositeMotion + distance;
    +		animation.opacity = 1;
    +	}
    +
    +	// Animate
    +	element.animate( animation, {
    +		queue: false,
    +		duration: options.duration,
    +		easing: options.easing,
    +		complete: done
    +	} );
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Explode 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Explode Effect
    +//>>group: Effects
    +// jscs:disable maximumLineLength
    +//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
    +// jscs:enable maximumLineLength
    +//>>docs: http://api.jqueryui.com/explode-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
    +
    +	var i, j, left, top, mx, my,
    +		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
    +		cells = rows,
    +		element = $( this ),
    +		mode = options.mode,
    +		show = mode === "show",
    +
    +		// Show and then visibility:hidden the element before calculating offset
    +		offset = element.show().css( "visibility", "hidden" ).offset(),
    +
    +		// Width and height of a piece
    +		width = Math.ceil( element.outerWidth() / cells ),
    +		height = Math.ceil( element.outerHeight() / rows ),
    +		pieces = [];
    +
    +	// Children animate complete:
    +	function childComplete() {
    +		pieces.push( this );
    +		if ( pieces.length === rows * cells ) {
    +			animComplete();
    +		}
    +	}
    +
    +	// Clone the element for each row and cell.
    +	for ( i = 0; i < rows; i++ ) { // ===>
    +		top = offset.top + i * height;
    +		my = i - ( rows - 1 ) / 2;
    +
    +		for ( j = 0; j < cells; j++ ) { // |||
    +			left = offset.left + j * width;
    +			mx = j - ( cells - 1 ) / 2;
    +
    +			// Create a clone of the now hidden main element that will be absolute positioned
    +			// within a wrapper div off the -left and -top equal to size of our pieces
    +			element
    +				.clone()
    +				.appendTo( "body" )
    +				.wrap( "<div></div>" )
    +				.css( {
    +					position: "absolute",
    +					visibility: "visible",
    +					left: -j * width,
    +					top: -i * height
    +				} )
    +
    +				// Select the wrapper - make it overflow: hidden and absolute positioned based on
    +				// where the original was located +left and +top equal to the size of pieces
    +				.parent()
    +					.addClass( "ui-effects-explode" )
    +					.css( {
    +						position: "absolute",
    +						overflow: "hidden",
    +						width: width,
    +						height: height,
    +						left: left + ( show ? mx * width : 0 ),
    +						top: top + ( show ? my * height : 0 ),
    +						opacity: show ? 0 : 1
    +					} )
    +					.animate( {
    +						left: left + ( show ? 0 : mx * width ),
    +						top: top + ( show ? 0 : my * height ),
    +						opacity: show ? 1 : 0
    +					}, options.duration || 500, options.easing, childComplete );
    +		}
    +	}
    +
    +	function animComplete() {
    +		element.css( {
    +			visibility: "visible"
    +		} );
    +		$( pieces ).remove();
    +		done();
    +	}
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Fade 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Fade Effect
    +//>>group: Effects
    +//>>description: Fades the element.
    +//>>docs: http://api.jqueryui.com/fade-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
    +	var show = options.mode === "show";
    +
    +	$( this )
    +		.css( "opacity", show ? 0 : 1 )
    +		.animate( {
    +			opacity: show ? 1 : 0
    +		}, {
    +			queue: false,
    +			duration: options.duration,
    +			easing: options.easing,
    +			complete: done
    +		} );
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Fold 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Fold Effect
    +//>>group: Effects
    +//>>description: Folds an element first horizontally and then vertically.
    +//>>docs: http://api.jqueryui.com/fold-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
    +
    +	// Create element
    +	var element = $( this ),
    +		mode = options.mode,
    +		show = mode === "show",
    +		hide = mode === "hide",
    +		size = options.size || 15,
    +		percent = /([0-9]+)%/.exec( size ),
    +		horizFirst = !!options.horizFirst,
    +		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
    +		duration = options.duration / 2,
    +
    +		placeholder = $.effects.createPlaceholder( element ),
    +
    +		start = element.cssClip(),
    +		animation1 = { clip: $.extend( {}, start ) },
    +		animation2 = { clip: $.extend( {}, start ) },
    +
    +		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
    +
    +		queuelen = element.queue().length;
    +
    +	if ( percent ) {
    +		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
    +	}
    +	animation1.clip[ ref[ 0 ] ] = size;
    +	animation2.clip[ ref[ 0 ] ] = size;
    +	animation2.clip[ ref[ 1 ] ] = 0;
    +
    +	if ( show ) {
    +		element.cssClip( animation2.clip );
    +		if ( placeholder ) {
    +			placeholder.css( $.effects.clipToBox( animation2 ) );
    +		}
    +
    +		animation2.clip = start;
    +	}
    +
    +	// Animate
    +	element
    +		.queue( function( next ) {
    +			if ( placeholder ) {
    +				placeholder
    +					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
    +					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
    +			}
    +
    +			next();
    +		} )
    +		.animate( animation1, duration, options.easing )
    +		.animate( animation2, duration, options.easing )
    +		.queue( done );
    +
    +	$.effects.unshift( element, queuelen, 4 );
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Highlight 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Highlight Effect
    +//>>group: Effects
    +//>>description: Highlights the background of an element in a defined color for a custom duration.
    +//>>docs: http://api.jqueryui.com/highlight-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
    +	var element = $( this ),
    +		animation = {
    +			backgroundColor: element.css( "backgroundColor" )
    +		};
    +
    +	if ( options.mode === "hide" ) {
    +		animation.opacity = 0;
    +	}
    +
    +	$.effects.saveStyle( element );
    +
    +	element
    +		.css( {
    +			backgroundImage: "none",
    +			backgroundColor: options.color || "#ffff99"
    +		} )
    +		.animate( animation, {
    +			queue: false,
    +			duration: options.duration,
    +			easing: options.easing,
    +			complete: done
    +		} );
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Size 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Size Effect
    +//>>group: Effects
    +//>>description: Resize an element to a specified width and height.
    +//>>docs: http://api.jqueryui.com/size-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectSize = $.effects.define( "size", function( options, done ) {
    +
    +	// Create element
    +	var baseline, factor, temp,
    +		element = $( this ),
    +
    +		// Copy for children
    +		cProps = [ "fontSize" ],
    +		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
    +		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
    +
    +		// Set options
    +		mode = options.mode,
    +		restore = mode !== "effect",
    +		scale = options.scale || "both",
    +		origin = options.origin || [ "middle", "center" ],
    +		position = element.css( "position" ),
    +		pos = element.position(),
    +		original = $.effects.scaledDimensions( element ),
    +		from = options.from || original,
    +		to = options.to || $.effects.scaledDimensions( element, 0 );
    +
    +	$.effects.createPlaceholder( element );
    +
    +	if ( mode === "show" ) {
    +		temp = from;
    +		from = to;
    +		to = temp;
    +	}
    +
    +	// Set scaling factor
    +	factor = {
    +		from: {
    +			y: from.height / original.height,
    +			x: from.width / original.width
    +		},
    +		to: {
    +			y: to.height / original.height,
    +			x: to.width / original.width
    +		}
    +	};
    +
    +	// Scale the css box
    +	if ( scale === "box" || scale === "both" ) {
    +
    +		// Vertical props scaling
    +		if ( factor.from.y !== factor.to.y ) {
    +			from = $.effects.setTransition( element, vProps, factor.from.y, from );
    +			to = $.effects.setTransition( element, vProps, factor.to.y, to );
    +		}
    +
    +		// Horizontal props scaling
    +		if ( factor.from.x !== factor.to.x ) {
    +			from = $.effects.setTransition( element, hProps, factor.from.x, from );
    +			to = $.effects.setTransition( element, hProps, factor.to.x, to );
    +		}
    +	}
    +
    +	// Scale the content
    +	if ( scale === "content" || scale === "both" ) {
    +
    +		// Vertical props scaling
    +		if ( factor.from.y !== factor.to.y ) {
    +			from = $.effects.setTransition( element, cProps, factor.from.y, from );
    +			to = $.effects.setTransition( element, cProps, factor.to.y, to );
    +		}
    +	}
    +
    +	// Adjust the position properties based on the provided origin points
    +	if ( origin ) {
    +		baseline = $.effects.getBaseline( origin, original );
    +		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
    +		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
    +		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
    +		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
    +	}
    +	element.css( from );
    +
    +	// Animate the children if desired
    +	if ( scale === "content" || scale === "both" ) {
    +
    +		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
    +		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
    +
    +		// Only animate children with width attributes specified
    +		// TODO: is this right? should we include anything with css width specified as well
    +		element.find( "*[width]" ).each( function() {
    +			var child = $( this ),
    +				childOriginal = $.effects.scaledDimensions( child ),
    +				childFrom = {
    +					height: childOriginal.height * factor.from.y,
    +					width: childOriginal.width * factor.from.x,
    +					outerHeight: childOriginal.outerHeight * factor.from.y,
    +					outerWidth: childOriginal.outerWidth * factor.from.x
    +				},
    +				childTo = {
    +					height: childOriginal.height * factor.to.y,
    +					width: childOriginal.width * factor.to.x,
    +					outerHeight: childOriginal.height * factor.to.y,
    +					outerWidth: childOriginal.width * factor.to.x
    +				};
    +
    +			// Vertical props scaling
    +			if ( factor.from.y !== factor.to.y ) {
    +				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
    +				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
    +			}
    +
    +			// Horizontal props scaling
    +			if ( factor.from.x !== factor.to.x ) {
    +				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
    +				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
    +			}
    +
    +			if ( restore ) {
    +				$.effects.saveStyle( child );
    +			}
    +
    +			// Animate children
    +			child.css( childFrom );
    +			child.animate( childTo, options.duration, options.easing, function() {
    +
    +				// Restore children
    +				if ( restore ) {
    +					$.effects.restoreStyle( child );
    +				}
    +			} );
    +		} );
    +	}
    +
    +	// Animate
    +	element.animate( to, {
    +		queue: false,
    +		duration: options.duration,
    +		easing: options.easing,
    +		complete: function() {
    +
    +			var offset = element.offset();
    +
    +			if ( to.opacity === 0 ) {
    +				element.css( "opacity", from.opacity );
    +			}
    +
    +			if ( !restore ) {
    +				element
    +					.css( "position", position === "static" ? "relative" : position )
    +					.offset( offset );
    +
    +				// Need to save style here so that automatic style restoration
    +				// doesn't restore to the original styles from before the animation.
    +				$.effects.saveStyle( element );
    +			}
    +
    +			done();
    +		}
    +	} );
    +
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Scale 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Scale Effect
    +//>>group: Effects
    +//>>description: Grows or shrinks an element and its content.
    +//>>docs: http://api.jqueryui.com/scale-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
    +
    +	// Create element
    +	var el = $( this ),
    +		mode = options.mode,
    +		percent = parseInt( options.percent, 10 ) ||
    +			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
    +
    +		newOptions = $.extend( true, {
    +			from: $.effects.scaledDimensions( el ),
    +			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
    +			origin: options.origin || [ "middle", "center" ]
    +		}, options );
    +
    +	// Fade option to support puff
    +	if ( options.fade ) {
    +		newOptions.from.opacity = 1;
    +		newOptions.to.opacity = 0;
    +	}
    +
    +	$.effects.effect.size.call( this, newOptions, done );
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Puff 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Puff Effect
    +//>>group: Effects
    +//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
    +//>>docs: http://api.jqueryui.com/puff-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
    +	var newOptions = $.extend( true, {}, options, {
    +		fade: true,
    +		percent: parseInt( options.percent, 10 ) || 150
    +	} );
    +
    +	$.effects.effect.scale.call( this, newOptions, done );
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Pulsate 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Pulsate Effect
    +//>>group: Effects
    +//>>description: Pulsates an element n times by changing the opacity to zero and back.
    +//>>docs: http://api.jqueryui.com/pulsate-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
    +	var element = $( this ),
    +		mode = options.mode,
    +		show = mode === "show",
    +		hide = mode === "hide",
    +		showhide = show || hide,
    +
    +		// Showing or hiding leaves off the "last" animation
    +		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
    +		duration = options.duration / anims,
    +		animateTo = 0,
    +		i = 1,
    +		queuelen = element.queue().length;
    +
    +	if ( show || !element.is( ":visible" ) ) {
    +		element.css( "opacity", 0 ).show();
    +		animateTo = 1;
    +	}
    +
    +	// Anims - 1 opacity "toggles"
    +	for ( ; i < anims; i++ ) {
    +		element.animate( { opacity: animateTo }, duration, options.easing );
    +		animateTo = 1 - animateTo;
    +	}
    +
    +	element.animate( { opacity: animateTo }, duration, options.easing );
    +
    +	element.queue( done );
    +
    +	$.effects.unshift( element, queuelen, anims + 1 );
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Shake 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Shake Effect
    +//>>group: Effects
    +//>>description: Shakes an element horizontally or vertically n times.
    +//>>docs: http://api.jqueryui.com/shake-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
    +
    +	var i = 1,
    +		element = $( this ),
    +		direction = options.direction || "left",
    +		distance = options.distance || 20,
    +		times = options.times || 3,
    +		anims = times * 2 + 1,
    +		speed = Math.round( options.duration / anims ),
    +		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
    +		positiveMotion = ( direction === "up" || direction === "left" ),
    +		animation = {},
    +		animation1 = {},
    +		animation2 = {},
    +
    +		queuelen = element.queue().length;
    +
    +	$.effects.createPlaceholder( element );
    +
    +	// Animation
    +	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
    +	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
    +	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
    +
    +	// Animate
    +	element.animate( animation, speed, options.easing );
    +
    +	// Shakes
    +	for ( ; i < times; i++ ) {
    +		element
    +			.animate( animation1, speed, options.easing )
    +			.animate( animation2, speed, options.easing );
    +	}
    +
    +	element
    +		.animate( animation1, speed, options.easing )
    +		.animate( animation, speed / 2, options.easing )
    +		.queue( done );
    +
    +	$.effects.unshift( element, queuelen, anims + 1 );
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Slide 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Slide Effect
    +//>>group: Effects
    +//>>description: Slides an element in and out of the viewport.
    +//>>docs: http://api.jqueryui.com/slide-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
    +	var startClip, startRef,
    +		element = $( this ),
    +		map = {
    +			up: [ "bottom", "top" ],
    +			down: [ "top", "bottom" ],
    +			left: [ "right", "left" ],
    +			right: [ "left", "right" ]
    +		},
    +		mode = options.mode,
    +		direction = options.direction || "left",
    +		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
    +		positiveMotion = ( direction === "up" || direction === "left" ),
    +		distance = options.distance ||
    +			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
    +		animation = {};
    +
    +	$.effects.createPlaceholder( element );
    +
    +	startClip = element.cssClip();
    +	startRef = element.position()[ ref ];
    +
    +	// Define hide animation
    +	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
    +	animation.clip = element.cssClip();
    +	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
    +
    +	// Reverse the animation if we're showing
    +	if ( mode === "show" ) {
    +		element.cssClip( animation.clip );
    +		element.css( ref, animation[ ref ] );
    +		animation.clip = startClip;
    +		animation[ ref ] = startRef;
    +	}
    +
    +	// Actually animate
    +	element.animate( animation, {
    +		queue: false,
    +		duration: options.duration,
    +		easing: options.easing,
    +		complete: done
    +	} );
    +} );
    +
    +
    +/*!
    + * jQuery UI Effects Transfer 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Transfer Effect
    +//>>group: Effects
    +//>>description: Displays a transfer effect from one element to another.
    +//>>docs: http://api.jqueryui.com/transfer-effect/
    +//>>demos: http://jqueryui.com/effect/
    +
    +
    +
    +var effect;
    +if ( $.uiBackCompat !== false ) {
    +	effect = $.effects.define( "transfer", function( options, done ) {
    +		$( this ).transfer( options, done );
    +	} );
    +}
    +var effectsEffectTransfer = effect;
    +
    +
    +/*!
    + * jQuery UI Focusable 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: :focusable Selector
    +//>>group: Core
    +//>>description: Selects elements which can be focused.
    +//>>docs: http://api.jqueryui.com/focusable-selector/
    +
    +
    +
    +// Selectors
    +$.ui.focusable = function( element, hasTabindex ) {
    +	var map, mapName, img, focusableIfVisible, fieldset,
    +		nodeName = element.nodeName.toLowerCase();
    +
    +	if ( "area" === nodeName ) {
    +		map = element.parentNode;
    +		mapName = map.name;
    +		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
    +			return false;
    +		}
    +		img = $( "img[usemap='#" + mapName + "']" );
    +		return img.length > 0 && img.is( ":visible" );
    +	}
    +
    +	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
    +		focusableIfVisible = !element.disabled;
    +
    +		if ( focusableIfVisible ) {
    +
    +			// Form controls within a disabled fieldset are disabled.
    +			// However, controls within the fieldset's legend do not get disabled.
    +			// Since controls generally aren't placed inside legends, we skip
    +			// this portion of the check.
    +			fieldset = $( element ).closest( "fieldset" )[ 0 ];
    +			if ( fieldset ) {
    +				focusableIfVisible = !fieldset.disabled;
    +			}
    +		}
    +	} else if ( "a" === nodeName ) {
    +		focusableIfVisible = element.href || hasTabindex;
    +	} else {
    +		focusableIfVisible = hasTabindex;
    +	}
    +
    +	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
    +};
    +
    +// Support: IE 8 only
    +// IE 8 doesn't resolve inherit to visible/hidden for computed values
    +function visible( element ) {
    +	var visibility = element.css( "visibility" );
    +	while ( visibility === "inherit" ) {
    +		element = element.parent();
    +		visibility = element.css( "visibility" );
    +	}
    +	return visibility !== "hidden";
    +}
    +
    +$.extend( $.expr[ ":" ], {
    +	focusable: function( element ) {
    +		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
    +	}
    +} );
    +
    +var focusable = $.ui.focusable;
    +
    +
    +
    +
    +// Support: IE8 Only
    +// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
    +// with a string, so we need to find the proper form.
    +var form = $.fn.form = function() {
    +	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
    +};
    +
    +
    +/*!
    + * jQuery UI Form Reset Mixin 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Form Reset Mixin
    +//>>group: Core
    +//>>description: Refresh input widgets when their form is reset
    +//>>docs: http://api.jqueryui.com/form-reset-mixin/
    +
    +
    +
    +var formResetMixin = $.ui.formResetMixin = {
    +	_formResetHandler: function() {
    +		var form = $( this );
    +
    +		// Wait for the form reset to actually happen before refreshing
    +		setTimeout( function() {
    +			var instances = form.data( "ui-form-reset-instances" );
    +			$.each( instances, function() {
    +				this.refresh();
    +			} );
    +		} );
    +	},
    +
    +	_bindFormResetHandler: function() {
    +		this.form = this.element.form();
    +		if ( !this.form.length ) {
    +			return;
    +		}
    +
    +		var instances = this.form.data( "ui-form-reset-instances" ) || [];
    +		if ( !instances.length ) {
    +
    +			// We don't use _on() here because we use a single event handler per form
    +			this.form.on( "reset.ui-form-reset", this._formResetHandler );
    +		}
    +		instances.push( this );
    +		this.form.data( "ui-form-reset-instances", instances );
    +	},
    +
    +	_unbindFormResetHandler: function() {
    +		if ( !this.form.length ) {
    +			return;
    +		}
    +
    +		var instances = this.form.data( "ui-form-reset-instances" );
    +		instances.splice( $.inArray( this, instances ), 1 );
    +		if ( instances.length ) {
    +			this.form.data( "ui-form-reset-instances", instances );
    +		} else {
    +			this.form
    +				.removeData( "ui-form-reset-instances" )
    +				.off( "reset.ui-form-reset" );
    +		}
    +	}
    +};
    +
    +
    +/*!
    + * jQuery UI Support for jQuery core 1.7.x 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + *
    + */
    +
    +//>>label: jQuery 1.7 Support
    +//>>group: Core
    +//>>description: Support version 1.7.x of jQuery core
    +
    +
    +
    +// Support: jQuery 1.7 only
    +// Not a great way to check versions, but since we only support 1.7+ and only
    +// need to detect <1.8, this is a simple check that should suffice. Checking
    +// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
    +// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
    +// 1.7 anymore). See #11197 for why we're not using feature detection.
    +if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
    +
    +	// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
    +	// Unlike jQuery Core 1.8+, these only support numeric values to set the
    +	// dimensions in pixels
    +	$.each( [ "Width", "Height" ], function( i, name ) {
    +		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
    +			type = name.toLowerCase(),
    +			orig = {
    +				innerWidth: $.fn.innerWidth,
    +				innerHeight: $.fn.innerHeight,
    +				outerWidth: $.fn.outerWidth,
    +				outerHeight: $.fn.outerHeight
    +			};
    +
    +		function reduce( elem, size, border, margin ) {
    +			$.each( side, function() {
    +				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
    +				if ( border ) {
    +					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
    +				}
    +				if ( margin ) {
    +					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
    +				}
    +			} );
    +			return size;
    +		}
    +
    +		$.fn[ "inner" + name ] = function( size ) {
    +			if ( size === undefined ) {
    +				return orig[ "inner" + name ].call( this );
    +			}
    +
    +			return this.each( function() {
    +				$( this ).css( type, reduce( this, size ) + "px" );
    +			} );
    +		};
    +
    +		$.fn[ "outer" + name ] = function( size, margin ) {
    +			if ( typeof size !== "number" ) {
    +				return orig[ "outer" + name ].call( this, size );
    +			}
    +
    +			return this.each( function() {
    +				$( this ).css( type, reduce( this, size, true, margin ) + "px" );
    +			} );
    +		};
    +	} );
    +
    +	$.fn.addBack = function( selector ) {
    +		return this.add( selector == null ?
    +			this.prevObject : this.prevObject.filter( selector )
    +		);
    +	};
    +}
    +
    +;
    +/*!
    + * jQuery UI Keycode 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Keycode
    +//>>group: Core
    +//>>description: Provide keycodes as keynames
    +//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
    +
    +
    +var keycode = $.ui.keyCode = {
    +	BACKSPACE: 8,
    +	COMMA: 188,
    +	DELETE: 46,
    +	DOWN: 40,
    +	END: 35,
    +	ENTER: 13,
    +	ESCAPE: 27,
    +	HOME: 36,
    +	LEFT: 37,
    +	PAGE_DOWN: 34,
    +	PAGE_UP: 33,
    +	PERIOD: 190,
    +	RIGHT: 39,
    +	SPACE: 32,
    +	TAB: 9,
    +	UP: 38
    +};
    +
    +
    +
    +
    +// Internal use only
    +var escapeSelector = $.ui.escapeSelector = ( function() {
    +	var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
    +	return function( selector ) {
    +		return selector.replace( selectorEscape, "\\$1" );
    +	};
    +} )();
    +
    +
    +/*!
    + * jQuery UI Labels 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: labels
    +//>>group: Core
    +//>>description: Find all the labels associated with a given input
    +//>>docs: http://api.jqueryui.com/labels/
    +
    +
    +
    +var labels = $.fn.labels = function() {
    +	var ancestor, selector, id, labels, ancestors;
    +
    +	// Check control.labels first
    +	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
    +		return this.pushStack( this[ 0 ].labels );
    +	}
    +
    +	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
    +	// Above browsers do not support control.labels. Everything below is to support them
    +	// as well as document fragments. control.labels does not work on document fragments
    +	labels = this.eq( 0 ).parents( "label" );
    +
    +	// Look for the label based on the id
    +	id = this.attr( "id" );
    +	if ( id ) {
    +
    +		// We don't search against the document in case the element
    +		// is disconnected from the DOM
    +		ancestor = this.eq( 0 ).parents().last();
    +
    +		// Get a full set of top level ancestors
    +		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
    +
    +		// Create a selector for the label based on the id
    +		selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
    +
    +		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
    +
    +	}
    +
    +	// Return whatever we have found for labels
    +	return this.pushStack( labels );
    +};
    +
    +
    +/*!
    + * jQuery UI Scroll Parent 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: scrollParent
    +//>>group: Core
    +//>>description: Get the closest ancestor element that is scrollable.
    +//>>docs: http://api.jqueryui.com/scrollParent/
    +
    +
    +
    +var scrollParent = $.fn.scrollParent = function( includeHidden ) {
    +	var position = this.css( "position" ),
    +		excludeStaticParent = position === "absolute",
    +		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
    +		scrollParent = this.parents().filter( function() {
    +			var parent = $( this );
    +			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
    +				return false;
    +			}
    +			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
    +				parent.css( "overflow-x" ) );
    +		} ).eq( 0 );
    +
    +	return position === "fixed" || !scrollParent.length ?
    +		$( this[ 0 ].ownerDocument || document ) :
    +		scrollParent;
    +};
    +
    +
    +/*!
    + * jQuery UI Tabbable 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: :tabbable Selector
    +//>>group: Core
    +//>>description: Selects elements which can be tabbed to.
    +//>>docs: http://api.jqueryui.com/tabbable-selector/
    +
    +
    +
    +var tabbable = $.extend( $.expr[ ":" ], {
    +	tabbable: function( element ) {
    +		var tabIndex = $.attr( element, "tabindex" ),
    +			hasTabindex = tabIndex != null;
    +		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
    +	}
    +} );
    +
    +
    +/*!
    + * jQuery UI Unique ID 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: uniqueId
    +//>>group: Core
    +//>>description: Functions to generate and remove uniqueId's
    +//>>docs: http://api.jqueryui.com/uniqueId/
    +
    +
    +
    +var uniqueId = $.fn.extend( {
    +	uniqueId: ( function() {
    +		var uuid = 0;
    +
    +		return function() {
    +			return this.each( function() {
    +				if ( !this.id ) {
    +					this.id = "ui-id-" + ( ++uuid );
    +				}
    +			} );
    +		};
    +	} )(),
    +
    +	removeUniqueId: function() {
    +		return this.each( function() {
    +			if ( /^ui-id-\d+$/.test( this.id ) ) {
    +				$( this ).removeAttr( "id" );
    +			}
    +		} );
    +	}
    +} );
    +
    +
    +/*!
    + * jQuery UI Accordion 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Accordion
    +//>>group: Widgets
    +// jscs:disable maximumLineLength
    +//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
    +// jscs:enable maximumLineLength
    +//>>docs: http://api.jqueryui.com/accordion/
    +//>>demos: http://jqueryui.com/accordion/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/accordion.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +var widgetsAccordion = $.widget( "ui.accordion", {
    +	version: "1.12.1",
    +	options: {
    +		active: 0,
    +		animate: {},
    +		classes: {
    +			"ui-accordion-header": "ui-corner-top",
    +			"ui-accordion-header-collapsed": "ui-corner-all",
    +			"ui-accordion-content": "ui-corner-bottom"
    +		},
    +		collapsible: false,
    +		event: "click",
    +		header: "> li > :first-child, > :not(li):even",
    +		heightStyle: "auto",
    +		icons: {
    +			activeHeader: "ui-icon-triangle-1-s",
    +			header: "ui-icon-triangle-1-e"
    +		},
    +
    +		// Callbacks
    +		activate: null,
    +		beforeActivate: null
    +	},
    +
    +	hideProps: {
    +		borderTopWidth: "hide",
    +		borderBottomWidth: "hide",
    +		paddingTop: "hide",
    +		paddingBottom: "hide",
    +		height: "hide"
    +	},
    +
    +	showProps: {
    +		borderTopWidth: "show",
    +		borderBottomWidth: "show",
    +		paddingTop: "show",
    +		paddingBottom: "show",
    +		height: "show"
    +	},
    +
    +	_create: function() {
    +		var options = this.options;
    +
    +		this.prevShow = this.prevHide = $();
    +		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
    +		this.element.attr( "role", "tablist" );
    +
    +		// Don't allow collapsible: false and active: false / null
    +		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
    +			options.active = 0;
    +		}
    +
    +		this._processPanels();
    +
    +		// handle negative values
    +		if ( options.active < 0 ) {
    +			options.active += this.headers.length;
    +		}
    +		this._refresh();
    +	},
    +
    +	_getCreateEventData: function() {
    +		return {
    +			header: this.active,
    +			panel: !this.active.length ? $() : this.active.next()
    +		};
    +	},
    +
    +	_createIcons: function() {
    +		var icon, children,
    +			icons = this.options.icons;
    +
    +		if ( icons ) {
    +			icon = $( "<span>" );
    +			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
    +			icon.prependTo( this.headers );
    +			children = this.active.children( ".ui-accordion-header-icon" );
    +			this._removeClass( children, icons.header )
    +				._addClass( children, null, icons.activeHeader )
    +				._addClass( this.headers, "ui-accordion-icons" );
    +		}
    +	},
    +
    +	_destroyIcons: function() {
    +		this._removeClass( this.headers, "ui-accordion-icons" );
    +		this.headers.children( ".ui-accordion-header-icon" ).remove();
    +	},
    +
    +	_destroy: function() {
    +		var contents;
    +
    +		// Clean up main element
    +		this.element.removeAttr( "role" );
    +
    +		// Clean up headers
    +		this.headers
    +			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
    +			.removeUniqueId();
    +
    +		this._destroyIcons();
    +
    +		// Clean up content panels
    +		contents = this.headers.next()
    +			.css( "display", "" )
    +			.removeAttr( "role aria-hidden aria-labelledby" )
    +			.removeUniqueId();
    +
    +		if ( this.options.heightStyle !== "content" ) {
    +			contents.css( "height", "" );
    +		}
    +	},
    +
    +	_setOption: function( key, value ) {
    +		if ( key === "active" ) {
    +
    +			// _activate() will handle invalid values and update this.options
    +			this._activate( value );
    +			return;
    +		}
    +
    +		if ( key === "event" ) {
    +			if ( this.options.event ) {
    +				this._off( this.headers, this.options.event );
    +			}
    +			this._setupEvents( value );
    +		}
    +
    +		this._super( key, value );
    +
    +		// Setting collapsible: false while collapsed; open first panel
    +		if ( key === "collapsible" && !value && this.options.active === false ) {
    +			this._activate( 0 );
    +		}
    +
    +		if ( key === "icons" ) {
    +			this._destroyIcons();
    +			if ( value ) {
    +				this._createIcons();
    +			}
    +		}
    +	},
    +
    +	_setOptionDisabled: function( value ) {
    +		this._super( value );
    +
    +		this.element.attr( "aria-disabled", value );
    +
    +		// Support: IE8 Only
    +		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
    +		// so we need to add the disabled class to the headers and panels
    +		this._toggleClass( null, "ui-state-disabled", !!value );
    +		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
    +			!!value );
    +	},
    +
    +	_keydown: function( event ) {
    +		if ( event.altKey || event.ctrlKey ) {
    +			return;
    +		}
    +
    +		var keyCode = $.ui.keyCode,
    +			length = this.headers.length,
    +			currentIndex = this.headers.index( event.target ),
    +			toFocus = false;
    +
    +		switch ( event.keyCode ) {
    +		case keyCode.RIGHT:
    +		case keyCode.DOWN:
    +			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
    +			break;
    +		case keyCode.LEFT:
    +		case keyCode.UP:
    +			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
    +			break;
    +		case keyCode.SPACE:
    +		case keyCode.ENTER:
    +			this._eventHandler( event );
    +			break;
    +		case keyCode.HOME:
    +			toFocus = this.headers[ 0 ];
    +			break;
    +		case keyCode.END:
    +			toFocus = this.headers[ length - 1 ];
    +			break;
    +		}
    +
    +		if ( toFocus ) {
    +			$( event.target ).attr( "tabIndex", -1 );
    +			$( toFocus ).attr( "tabIndex", 0 );
    +			$( toFocus ).trigger( "focus" );
    +			event.preventDefault();
    +		}
    +	},
    +
    +	_panelKeyDown: function( event ) {
    +		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
    +			$( event.currentTarget ).prev().trigger( "focus" );
    +		}
    +	},
    +
    +	refresh: function() {
    +		var options = this.options;
    +		this._processPanels();
    +
    +		// Was collapsed or no panel
    +		if ( ( options.active === false && options.collapsible === true ) ||
    +				!this.headers.length ) {
    +			options.active = false;
    +			this.active = $();
    +
    +		// active false only when collapsible is true
    +		} else if ( options.active === false ) {
    +			this._activate( 0 );
    +
    +		// was active, but active panel is gone
    +		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
    +
    +			// all remaining panel are disabled
    +			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
    +				options.active = false;
    +				this.active = $();
    +
    +			// activate previous panel
    +			} else {
    +				this._activate( Math.max( 0, options.active - 1 ) );
    +			}
    +
    +		// was active, active panel still exists
    +		} else {
    +
    +			// make sure active index is correct
    +			options.active = this.headers.index( this.active );
    +		}
    +
    +		this._destroyIcons();
    +
    +		this._refresh();
    +	},
    +
    +	_processPanels: function() {
    +		var prevHeaders = this.headers,
    +			prevPanels = this.panels;
    +
    +		this.headers = this.element.find( this.options.header );
    +		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
    +			"ui-state-default" );
    +
    +		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
    +		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
    +
    +		// Avoid memory leaks (#10056)
    +		if ( prevPanels ) {
    +			this._off( prevHeaders.not( this.headers ) );
    +			this._off( prevPanels.not( this.panels ) );
    +		}
    +	},
    +
    +	_refresh: function() {
    +		var maxHeight,
    +			options = this.options,
    +			heightStyle = options.heightStyle,
    +			parent = this.element.parent();
    +
    +		this.active = this._findActive( options.active );
    +		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
    +			._removeClass( this.active, "ui-accordion-header-collapsed" );
    +		this._addClass( this.active.next(), "ui-accordion-content-active" );
    +		this.active.next().show();
    +
    +		this.headers
    +			.attr( "role", "tab" )
    +			.each( function() {
    +				var header = $( this ),
    +					headerId = header.uniqueId().attr( "id" ),
    +					panel = header.next(),
    +					panelId = panel.uniqueId().attr( "id" );
    +				header.attr( "aria-controls", panelId );
    +				panel.attr( "aria-labelledby", headerId );
    +			} )
    +			.next()
    +				.attr( "role", "tabpanel" );
    +
    +		this.headers
    +			.not( this.active )
    +				.attr( {
    +					"aria-selected": "false",
    +					"aria-expanded": "false",
    +					tabIndex: -1
    +				} )
    +				.next()
    +					.attr( {
    +						"aria-hidden": "true"
    +					} )
    +					.hide();
    +
    +		// Make sure at least one header is in the tab order
    +		if ( !this.active.length ) {
    +			this.headers.eq( 0 ).attr( "tabIndex", 0 );
    +		} else {
    +			this.active.attr( {
    +				"aria-selected": "true",
    +				"aria-expanded": "true",
    +				tabIndex: 0
    +			} )
    +				.next()
    +					.attr( {
    +						"aria-hidden": "false"
    +					} );
    +		}
    +
    +		this._createIcons();
    +
    +		this._setupEvents( options.event );
    +
    +		if ( heightStyle === "fill" ) {
    +			maxHeight = parent.height();
    +			this.element.siblings( ":visible" ).each( function() {
    +				var elem = $( this ),
    +					position = elem.css( "position" );
    +
    +				if ( position === "absolute" || position === "fixed" ) {
    +					return;
    +				}
    +				maxHeight -= elem.outerHeight( true );
    +			} );
    +
    +			this.headers.each( function() {
    +				maxHeight -= $( this ).outerHeight( true );
    +			} );
    +
    +			this.headers.next()
    +				.each( function() {
    +					$( this ).height( Math.max( 0, maxHeight -
    +						$( this ).innerHeight() + $( this ).height() ) );
    +				} )
    +				.css( "overflow", "auto" );
    +		} else if ( heightStyle === "auto" ) {
    +			maxHeight = 0;
    +			this.headers.next()
    +				.each( function() {
    +					var isVisible = $( this ).is( ":visible" );
    +					if ( !isVisible ) {
    +						$( this ).show();
    +					}
    +					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
    +					if ( !isVisible ) {
    +						$( this ).hide();
    +					}
    +				} )
    +				.height( maxHeight );
    +		}
    +	},
    +
    +	_activate: function( index ) {
    +		var active = this._findActive( index )[ 0 ];
    +
    +		// Trying to activate the already active panel
    +		if ( active === this.active[ 0 ] ) {
    +			return;
    +		}
    +
    +		// Trying to collapse, simulate a click on the currently active header
    +		active = active || this.active[ 0 ];
    +
    +		this._eventHandler( {
    +			target: active,
    +			currentTarget: active,
    +			preventDefault: $.noop
    +		} );
    +	},
    +
    +	_findActive: function( selector ) {
    +		return typeof selector === "number" ? this.headers.eq( selector ) : $();
    +	},
    +
    +	_setupEvents: function( event ) {
    +		var events = {
    +			keydown: "_keydown"
    +		};
    +		if ( event ) {
    +			$.each( event.split( " " ), function( index, eventName ) {
    +				events[ eventName ] = "_eventHandler";
    +			} );
    +		}
    +
    +		this._off( this.headers.add( this.headers.next() ) );
    +		this._on( this.headers, events );
    +		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
    +		this._hoverable( this.headers );
    +		this._focusable( this.headers );
    +	},
    +
    +	_eventHandler: function( event ) {
    +		var activeChildren, clickedChildren,
    +			options = this.options,
    +			active = this.active,
    +			clicked = $( event.currentTarget ),
    +			clickedIsActive = clicked[ 0 ] === active[ 0 ],
    +			collapsing = clickedIsActive && options.collapsible,
    +			toShow = collapsing ? $() : clicked.next(),
    +			toHide = active.next(),
    +			eventData = {
    +				oldHeader: active,
    +				oldPanel: toHide,
    +				newHeader: collapsing ? $() : clicked,
    +				newPanel: toShow
    +			};
    +
    +		event.preventDefault();
    +
    +		if (
    +
    +				// click on active header, but not collapsible
    +				( clickedIsActive && !options.collapsible ) ||
    +
    +				// allow canceling activation
    +				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
    +			return;
    +		}
    +
    +		options.active = collapsing ? false : this.headers.index( clicked );
    +
    +		// When the call to ._toggle() comes after the class changes
    +		// it causes a very odd bug in IE 8 (see #6720)
    +		this.active = clickedIsActive ? $() : clicked;
    +		this._toggle( eventData );
    +
    +		// Switch classes
    +		// corner classes on the previously active header stay after the animation
    +		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
    +		if ( options.icons ) {
    +			activeChildren = active.children( ".ui-accordion-header-icon" );
    +			this._removeClass( activeChildren, null, options.icons.activeHeader )
    +				._addClass( activeChildren, null, options.icons.header );
    +		}
    +
    +		if ( !clickedIsActive ) {
    +			this._removeClass( clicked, "ui-accordion-header-collapsed" )
    +				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
    +			if ( options.icons ) {
    +				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
    +				this._removeClass( clickedChildren, null, options.icons.header )
    +					._addClass( clickedChildren, null, options.icons.activeHeader );
    +			}
    +
    +			this._addClass( clicked.next(), "ui-accordion-content-active" );
    +		}
    +	},
    +
    +	_toggle: function( data ) {
    +		var toShow = data.newPanel,
    +			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
    +
    +		// Handle activating a panel during the animation for another activation
    +		this.prevShow.add( this.prevHide ).stop( true, true );
    +		this.prevShow = toShow;
    +		this.prevHide = toHide;
    +
    +		if ( this.options.animate ) {
    +			this._animate( toShow, toHide, data );
    +		} else {
    +			toHide.hide();
    +			toShow.show();
    +			this._toggleComplete( data );
    +		}
    +
    +		toHide.attr( {
    +			"aria-hidden": "true"
    +		} );
    +		toHide.prev().attr( {
    +			"aria-selected": "false",
    +			"aria-expanded": "false"
    +		} );
    +
    +		// if we're switching panels, remove the old header from the tab order
    +		// if we're opening from collapsed state, remove the previous header from the tab order
    +		// if we're collapsing, then keep the collapsing header in the tab order
    +		if ( toShow.length && toHide.length ) {
    +			toHide.prev().attr( {
    +				"tabIndex": -1,
    +				"aria-expanded": "false"
    +			} );
    +		} else if ( toShow.length ) {
    +			this.headers.filter( function() {
    +				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
    +			} )
    +				.attr( "tabIndex", -1 );
    +		}
    +
    +		toShow
    +			.attr( "aria-hidden", "false" )
    +			.prev()
    +				.attr( {
    +					"aria-selected": "true",
    +					"aria-expanded": "true",
    +					tabIndex: 0
    +				} );
    +	},
    +
    +	_animate: function( toShow, toHide, data ) {
    +		var total, easing, duration,
    +			that = this,
    +			adjust = 0,
    +			boxSizing = toShow.css( "box-sizing" ),
    +			down = toShow.length &&
    +				( !toHide.length || ( toShow.index() < toHide.index() ) ),
    +			animate = this.options.animate || {},
    +			options = down && animate.down || animate,
    +			complete = function() {
    +				that._toggleComplete( data );
    +			};
    +
    +		if ( typeof options === "number" ) {
    +			duration = options;
    +		}
    +		if ( typeof options === "string" ) {
    +			easing = options;
    +		}
    +
    +		// fall back from options to animation in case of partial down settings
    +		easing = easing || options.easing || animate.easing;
    +		duration = duration || options.duration || animate.duration;
    +
    +		if ( !toHide.length ) {
    +			return toShow.animate( this.showProps, duration, easing, complete );
    +		}
    +		if ( !toShow.length ) {
    +			return toHide.animate( this.hideProps, duration, easing, complete );
    +		}
    +
    +		total = toShow.show().outerHeight();
    +		toHide.animate( this.hideProps, {
    +			duration: duration,
    +			easing: easing,
    +			step: function( now, fx ) {
    +				fx.now = Math.round( now );
    +			}
    +		} );
    +		toShow
    +			.hide()
    +			.animate( this.showProps, {
    +				duration: duration,
    +				easing: easing,
    +				complete: complete,
    +				step: function( now, fx ) {
    +					fx.now = Math.round( now );
    +					if ( fx.prop !== "height" ) {
    +						if ( boxSizing === "content-box" ) {
    +							adjust += fx.now;
    +						}
    +					} else if ( that.options.heightStyle !== "content" ) {
    +						fx.now = Math.round( total - toHide.outerHeight() - adjust );
    +						adjust = 0;
    +					}
    +				}
    +			} );
    +	},
    +
    +	_toggleComplete: function( data ) {
    +		var toHide = data.oldPanel,
    +			prev = toHide.prev();
    +
    +		this._removeClass( toHide, "ui-accordion-content-active" );
    +		this._removeClass( prev, "ui-accordion-header-active" )
    +			._addClass( prev, "ui-accordion-header-collapsed" );
    +
    +		// Work around for rendering bug in IE (#5421)
    +		if ( toHide.length ) {
    +			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
    +		}
    +		this._trigger( "activate", null, data );
    +	}
    +} );
    +
    +
    +
    +var safeActiveElement = $.ui.safeActiveElement = function( document ) {
    +	var activeElement;
    +
    +	// Support: IE 9 only
    +	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
    +	try {
    +		activeElement = document.activeElement;
    +	} catch ( error ) {
    +		activeElement = document.body;
    +	}
    +
    +	// Support: IE 9 - 11 only
    +	// IE may return null instead of an element
    +	// Interestingly, this only seems to occur when NOT in an iframe
    +	if ( !activeElement ) {
    +		activeElement = document.body;
    +	}
    +
    +	// Support: IE 11 only
    +	// IE11 returns a seemingly empty object in some cases when accessing
    +	// document.activeElement from an <iframe>
    +	if ( !activeElement.nodeName ) {
    +		activeElement = document.body;
    +	}
    +
    +	return activeElement;
    +};
    +
    +
    +/*!
    + * jQuery UI Menu 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Menu
    +//>>group: Widgets
    +//>>description: Creates nestable menus.
    +//>>docs: http://api.jqueryui.com/menu/
    +//>>demos: http://jqueryui.com/menu/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/menu.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +var widgetsMenu = $.widget( "ui.menu", {
    +	version: "1.12.1",
    +	defaultElement: "<ul>",
    +	delay: 300,
    +	options: {
    +		icons: {
    +			submenu: "ui-icon-caret-1-e"
    +		},
    +		items: "> *",
    +		menus: "ul",
    +		position: {
    +			my: "left top",
    +			at: "right top"
    +		},
    +		role: "menu",
    +
    +		// Callbacks
    +		blur: null,
    +		focus: null,
    +		select: null
    +	},
    +
    +	_create: function() {
    +		this.activeMenu = this.element;
    +
    +		// Flag used to prevent firing of the click handler
    +		// as the event bubbles up through nested menus
    +		this.mouseHandled = false;
    +		this.element
    +			.uniqueId()
    +			.attr( {
    +				role: this.options.role,
    +				tabIndex: 0
    +			} );
    +
    +		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
    +		this._on( {
    +
    +			// Prevent focus from sticking to links inside menu after clicking
    +			// them (focus should always stay on UL during navigation).
    +			"mousedown .ui-menu-item": function( event ) {
    +				event.preventDefault();
    +			},
    +			"click .ui-menu-item": function( event ) {
    +				var target = $( event.target );
    +				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
    +				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
    +					this.select( event );
    +
    +					// Only set the mouseHandled flag if the event will bubble, see #9469.
    +					if ( !event.isPropagationStopped() ) {
    +						this.mouseHandled = true;
    +					}
    +
    +					// Open submenu on click
    +					if ( target.has( ".ui-menu" ).length ) {
    +						this.expand( event );
    +					} else if ( !this.element.is( ":focus" ) &&
    +							active.closest( ".ui-menu" ).length ) {
    +
    +						// Redirect focus to the menu
    +						this.element.trigger( "focus", [ true ] );
    +
    +						// If the active item is on the top level, let it stay active.
    +						// Otherwise, blur the active item since it is no longer visible.
    +						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
    +							clearTimeout( this.timer );
    +						}
    +					}
    +				}
    +			},
    +			"mouseenter .ui-menu-item": function( event ) {
    +
    +				// Ignore mouse events while typeahead is active, see #10458.
    +				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
    +				// is over an item in the menu
    +				if ( this.previousFilter ) {
    +					return;
    +				}
    +
    +				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
    +					target = $( event.currentTarget );
    +
    +				// Ignore bubbled events on parent items, see #11641
    +				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
    +					return;
    +				}
    +
    +				// Remove ui-state-active class from siblings of the newly focused menu item
    +				// to avoid a jump caused by adjacent elements both having a class with a border
    +				this._removeClass( target.siblings().children( ".ui-state-active" ),
    +					null, "ui-state-active" );
    +				this.focus( event, target );
    +			},
    +			mouseleave: "collapseAll",
    +			"mouseleave .ui-menu": "collapseAll",
    +			focus: function( event, keepActiveItem ) {
    +
    +				// If there's already an active item, keep it active
    +				// If not, activate the first item
    +				var item = this.active || this.element.find( this.options.items ).eq( 0 );
    +
    +				if ( !keepActiveItem ) {
    +					this.focus( event, item );
    +				}
    +			},
    +			blur: function( event ) {
    +				this._delay( function() {
    +					var notContained = !$.contains(
    +						this.element[ 0 ],
    +						$.ui.safeActiveElement( this.document[ 0 ] )
    +					);
    +					if ( notContained ) {
    +						this.collapseAll( event );
    +					}
    +				} );
    +			},
    +			keydown: "_keydown"
    +		} );
    +
    +		this.refresh();
    +
    +		// Clicks outside of a menu collapse any open menus
    +		this._on( this.document, {
    +			click: function( event ) {
    +				if ( this._closeOnDocumentClick( event ) ) {
    +					this.collapseAll( event );
    +				}
    +
    +				// Reset the mouseHandled flag
    +				this.mouseHandled = false;
    +			}
    +		} );
    +	},
    +
    +	_destroy: function() {
    +		var items = this.element.find( ".ui-menu-item" )
    +				.removeAttr( "role aria-disabled" ),
    +			submenus = items.children( ".ui-menu-item-wrapper" )
    +				.removeUniqueId()
    +				.removeAttr( "tabIndex role aria-haspopup" );
    +
    +		// Destroy (sub)menus
    +		this.element
    +			.removeAttr( "aria-activedescendant" )
    +			.find( ".ui-menu" ).addBack()
    +				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
    +					"tabIndex" )
    +				.removeUniqueId()
    +				.show();
    +
    +		submenus.children().each( function() {
    +			var elem = $( this );
    +			if ( elem.data( "ui-menu-submenu-caret" ) ) {
    +				elem.remove();
    +			}
    +		} );
    +	},
    +
    +	_keydown: function( event ) {
    +		var match, prev, character, skip,
    +			preventDefault = true;
    +
    +		switch ( event.keyCode ) {
    +		case $.ui.keyCode.PAGE_UP:
    +			this.previousPage( event );
    +			break;
    +		case $.ui.keyCode.PAGE_DOWN:
    +			this.nextPage( event );
    +			break;
    +		case $.ui.keyCode.HOME:
    +			this._move( "first", "first", event );
    +			break;
    +		case $.ui.keyCode.END:
    +			this._move( "last", "last", event );
    +			break;
    +		case $.ui.keyCode.UP:
    +			this.previous( event );
    +			break;
    +		case $.ui.keyCode.DOWN:
    +			this.next( event );
    +			break;
    +		case $.ui.keyCode.LEFT:
    +			this.collapse( event );
    +			break;
    +		case $.ui.keyCode.RIGHT:
    +			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
    +				this.expand( event );
    +			}
    +			break;
    +		case $.ui.keyCode.ENTER:
    +		case $.ui.keyCode.SPACE:
    +			this._activate( event );
    +			break;
    +		case $.ui.keyCode.ESCAPE:
    +			this.collapse( event );
    +			break;
    +		default:
    +			preventDefault = false;
    +			prev = this.previousFilter || "";
    +			skip = false;
    +
    +			// Support number pad values
    +			character = event.keyCode >= 96 && event.keyCode <= 105 ?
    +				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
    +
    +			clearTimeout( this.filterTimer );
    +
    +			if ( character === prev ) {
    +				skip = true;
    +			} else {
    +				character = prev + character;
    +			}
    +
    +			match = this._filterMenuItems( character );
    +			match = skip && match.index( this.active.next() ) !== -1 ?
    +				this.active.nextAll( ".ui-menu-item" ) :
    +				match;
    +
    +			// If no matches on the current filter, reset to the last character pressed
    +			// to move down the menu to the first item that starts with that character
    +			if ( !match.length ) {
    +				character = String.fromCharCode( event.keyCode );
    +				match = this._filterMenuItems( character );
    +			}
    +
    +			if ( match.length ) {
    +				this.focus( event, match );
    +				this.previousFilter = character;
    +				this.filterTimer = this._delay( function() {
    +					delete this.previousFilter;
    +				}, 1000 );
    +			} else {
    +				delete this.previousFilter;
    +			}
    +		}
    +
    +		if ( preventDefault ) {
    +			event.preventDefault();
    +		}
    +	},
    +
    +	_activate: function( event ) {
    +		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
    +			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
    +				this.expand( event );
    +			} else {
    +				this.select( event );
    +			}
    +		}
    +	},
    +
    +	refresh: function() {
    +		var menus, items, newSubmenus, newItems, newWrappers,
    +			that = this,
    +			icon = this.options.icons.submenu,
    +			submenus = this.element.find( this.options.menus );
    +
    +		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
    +
    +		// Initialize nested menus
    +		newSubmenus = submenus.filter( ":not(.ui-menu)" )
    +			.hide()
    +			.attr( {
    +				role: this.options.role,
    +				"aria-hidden": "true",
    +				"aria-expanded": "false"
    +			} )
    +			.each( function() {
    +				var menu = $( this ),
    +					item = menu.prev(),
    +					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
    +
    +				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
    +				item
    +					.attr( "aria-haspopup", "true" )
    +					.prepend( submenuCaret );
    +				menu.attr( "aria-labelledby", item.attr( "id" ) );
    +			} );
    +
    +		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
    +
    +		menus = submenus.add( this.element );
    +		items = menus.find( this.options.items );
    +
    +		// Initialize menu-items containing spaces and/or dashes only as dividers
    +		items.not( ".ui-menu-item" ).each( function() {
    +			var item = $( this );
    +			if ( that._isDivider( item ) ) {
    +				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
    +			}
    +		} );
    +
    +		// Don't refresh list items that are already adapted
    +		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
    +		newWrappers = newItems.children()
    +			.not( ".ui-menu" )
    +				.uniqueId()
    +				.attr( {
    +					tabIndex: -1,
    +					role: this._itemRole()
    +				} );
    +		this._addClass( newItems, "ui-menu-item" )
    +			._addClass( newWrappers, "ui-menu-item-wrapper" );
    +
    +		// Add aria-disabled attribute to any disabled menu item
    +		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
    +
    +		// If the active item has been removed, blur the menu
    +		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
    +			this.blur();
    +		}
    +	},
    +
    +	_itemRole: function() {
    +		return {
    +			menu: "menuitem",
    +			listbox: "option"
    +		}[ this.options.role ];
    +	},
    +
    +	_setOption: function( key, value ) {
    +		if ( key === "icons" ) {
    +			var icons = this.element.find( ".ui-menu-icon" );
    +			this._removeClass( icons, null, this.options.icons.submenu )
    +				._addClass( icons, null, value.submenu );
    +		}
    +		this._super( key, value );
    +	},
    +
    +	_setOptionDisabled: function( value ) {
    +		this._super( value );
    +
    +		this.element.attr( "aria-disabled", String( value ) );
    +		this._toggleClass( null, "ui-state-disabled", !!value );
    +	},
    +
    +	focus: function( event, item ) {
    +		var nested, focused, activeParent;
    +		this.blur( event, event && event.type === "focus" );
    +
    +		this._scrollIntoView( item );
    +
    +		this.active = item.first();
    +
    +		focused = this.active.children( ".ui-menu-item-wrapper" );
    +		this._addClass( focused, null, "ui-state-active" );
    +
    +		// Only update aria-activedescendant if there's a role
    +		// otherwise we assume focus is managed elsewhere
    +		if ( this.options.role ) {
    +			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
    +		}
    +
    +		// Highlight active parent menu item, if any
    +		activeParent = this.active
    +			.parent()
    +				.closest( ".ui-menu-item" )
    +					.children( ".ui-menu-item-wrapper" );
    +		this._addClass( activeParent, null, "ui-state-active" );
    +
    +		if ( event && event.type === "keydown" ) {
    +			this._close();
    +		} else {
    +			this.timer = this._delay( function() {
    +				this._close();
    +			}, this.delay );
    +		}
    +
    +		nested = item.children( ".ui-menu" );
    +		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
    +			this._startOpening( nested );
    +		}
    +		this.activeMenu = item.parent();
    +
    +		this._trigger( "focus", event, { item: item } );
    +	},
    +
    +	_scrollIntoView: function( item ) {
    +		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
    +		if ( this._hasScroll() ) {
    +			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
    +			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
    +			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
    +			scroll = this.activeMenu.scrollTop();
    +			elementHeight = this.activeMenu.height();
    +			itemHeight = item.outerHeight();
    +
    +			if ( offset < 0 ) {
    +				this.activeMenu.scrollTop( scroll + offset );
    +			} else if ( offset + itemHeight > elementHeight ) {
    +				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
    +			}
    +		}
    +	},
    +
    +	blur: function( event, fromFocus ) {
    +		if ( !fromFocus ) {
    +			clearTimeout( this.timer );
    +		}
    +
    +		if ( !this.active ) {
    +			return;
    +		}
    +
    +		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
    +			null, "ui-state-active" );
    +
    +		this._trigger( "blur", event, { item: this.active } );
    +		this.active = null;
    +	},
    +
    +	_startOpening: function( submenu ) {
    +		clearTimeout( this.timer );
    +
    +		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
    +		// shift in the submenu position when mousing over the caret icon
    +		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
    +			return;
    +		}
    +
    +		this.timer = this._delay( function() {
    +			this._close();
    +			this._open( submenu );
    +		}, this.delay );
    +	},
    +
    +	_open: function( submenu ) {
    +		var position = $.extend( {
    +			of: this.active
    +		}, this.options.position );
    +
    +		clearTimeout( this.timer );
    +		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
    +			.hide()
    +			.attr( "aria-hidden", "true" );
    +
    +		submenu
    +			.show()
    +			.removeAttr( "aria-hidden" )
    +			.attr( "aria-expanded", "true" )
    +			.position( position );
    +	},
    +
    +	collapseAll: function( event, all ) {
    +		clearTimeout( this.timer );
    +		this.timer = this._delay( function() {
    +
    +			// If we were passed an event, look for the submenu that contains the event
    +			var currentMenu = all ? this.element :
    +				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
    +
    +			// If we found no valid submenu ancestor, use the main menu to close all
    +			// sub menus anyway
    +			if ( !currentMenu.length ) {
    +				currentMenu = this.element;
    +			}
    +
    +			this._close( currentMenu );
    +
    +			this.blur( event );
    +
    +			// Work around active item staying active after menu is blurred
    +			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
    +
    +			this.activeMenu = currentMenu;
    +		}, this.delay );
    +	},
    +
    +	// With no arguments, closes the currently active menu - if nothing is active
    +	// it closes all menus.  If passed an argument, it will search for menus BELOW
    +	_close: function( startMenu ) {
    +		if ( !startMenu ) {
    +			startMenu = this.active ? this.active.parent() : this.element;
    +		}
    +
    +		startMenu.find( ".ui-menu" )
    +			.hide()
    +			.attr( "aria-hidden", "true" )
    +			.attr( "aria-expanded", "false" );
    +	},
    +
    +	_closeOnDocumentClick: function( event ) {
    +		return !$( event.target ).closest( ".ui-menu" ).length;
    +	},
    +
    +	_isDivider: function( item ) {
    +
    +		// Match hyphen, em dash, en dash
    +		return !/[^\-\u2014\u2013\s]/.test( item.text() );
    +	},
    +
    +	collapse: function( event ) {
    +		var newItem = this.active &&
    +			this.active.parent().closest( ".ui-menu-item", this.element );
    +		if ( newItem && newItem.length ) {
    +			this._close();
    +			this.focus( event, newItem );
    +		}
    +	},
    +
    +	expand: function( event ) {
    +		var newItem = this.active &&
    +			this.active
    +				.children( ".ui-menu " )
    +					.find( this.options.items )
    +						.first();
    +
    +		if ( newItem && newItem.length ) {
    +			this._open( newItem.parent() );
    +
    +			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
    +			this._delay( function() {
    +				this.focus( event, newItem );
    +			} );
    +		}
    +	},
    +
    +	next: function( event ) {
    +		this._move( "next", "first", event );
    +	},
    +
    +	previous: function( event ) {
    +		this._move( "prev", "last", event );
    +	},
    +
    +	isFirstItem: function() {
    +		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
    +	},
    +
    +	isLastItem: function() {
    +		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
    +	},
    +
    +	_move: function( direction, filter, event ) {
    +		var next;
    +		if ( this.active ) {
    +			if ( direction === "first" || direction === "last" ) {
    +				next = this.active
    +					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
    +					.eq( -1 );
    +			} else {
    +				next = this.active
    +					[ direction + "All" ]( ".ui-menu-item" )
    +					.eq( 0 );
    +			}
    +		}
    +		if ( !next || !next.length || !this.active ) {
    +			next = this.activeMenu.find( this.options.items )[ filter ]();
    +		}
    +
    +		this.focus( event, next );
    +	},
    +
    +	nextPage: function( event ) {
    +		var item, base, height;
    +
    +		if ( !this.active ) {
    +			this.next( event );
    +			return;
    +		}
    +		if ( this.isLastItem() ) {
    +			return;
    +		}
    +		if ( this._hasScroll() ) {
    +			base = this.active.offset().top;
    +			height = this.element.height();
    +			this.active.nextAll( ".ui-menu-item" ).each( function() {
    +				item = $( this );
    +				return item.offset().top - base - height < 0;
    +			} );
    +
    +			this.focus( event, item );
    +		} else {
    +			this.focus( event, this.activeMenu.find( this.options.items )
    +				[ !this.active ? "first" : "last" ]() );
    +		}
    +	},
    +
    +	previousPage: function( event ) {
    +		var item, base, height;
    +		if ( !this.active ) {
    +			this.next( event );
    +			return;
    +		}
    +		if ( this.isFirstItem() ) {
    +			return;
    +		}
    +		if ( this._hasScroll() ) {
    +			base = this.active.offset().top;
    +			height = this.element.height();
    +			this.active.prevAll( ".ui-menu-item" ).each( function() {
    +				item = $( this );
    +				return item.offset().top - base + height > 0;
    +			} );
    +
    +			this.focus( event, item );
    +		} else {
    +			this.focus( event, this.activeMenu.find( this.options.items ).first() );
    +		}
    +	},
    +
    +	_hasScroll: function() {
    +		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
    +	},
    +
    +	select: function( event ) {
    +
    +		// TODO: It should never be possible to not have an active item at this
    +		// point, but the tests don't trigger mouseenter before click.
    +		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
    +		var ui = { item: this.active };
    +		if ( !this.active.has( ".ui-menu" ).length ) {
    +			this.collapseAll( event, true );
    +		}
    +		this._trigger( "select", event, ui );
    +	},
    +
    +	_filterMenuItems: function( character ) {
    +		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
    +			regex = new RegExp( "^" + escapedCharacter, "i" );
    +
    +		return this.activeMenu
    +			.find( this.options.items )
    +
    +				// Only match on items, not dividers or other content (#10571)
    +				.filter( ".ui-menu-item" )
    +					.filter( function() {
    +						return regex.test(
    +							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
    +					} );
    +	}
    +} );
    +
    +
    +/*!
    + * jQuery UI Autocomplete 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Autocomplete
    +//>>group: Widgets
    +//>>description: Lists suggested words as the user is typing.
    +//>>docs: http://api.jqueryui.com/autocomplete/
    +//>>demos: http://jqueryui.com/autocomplete/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/autocomplete.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +$.widget( "ui.autocomplete", {
    +	version: "1.12.1",
    +	defaultElement: "<input>",
    +	options: {
    +		appendTo: null,
    +		autoFocus: false,
    +		delay: 300,
    +		minLength: 1,
    +		position: {
    +			my: "left top",
    +			at: "left bottom",
    +			collision: "none"
    +		},
    +		source: null,
    +
    +		// Callbacks
    +		change: null,
    +		close: null,
    +		focus: null,
    +		open: null,
    +		response: null,
    +		search: null,
    +		select: null
    +	},
    +
    +	requestIndex: 0,
    +	pending: 0,
    +
    +	_create: function() {
    +
    +		// Some browsers only repeat keydown events, not keypress events,
    +		// so we use the suppressKeyPress flag to determine if we've already
    +		// handled the keydown event. #7269
    +		// Unfortunately the code for & in keypress is the same as the up arrow,
    +		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
    +		// events when we know the keydown event was used to modify the
    +		// search term. #7799
    +		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
    +			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
    +			isTextarea = nodeName === "textarea",
    +			isInput = nodeName === "input";
    +
    +		// Textareas are always multi-line
    +		// Inputs are always single-line, even if inside a contentEditable element
    +		// IE also treats inputs as contentEditable
    +		// All other element types are determined by whether or not they're contentEditable
    +		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
    +
    +		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
    +		this.isNewMenu = true;
    +
    +		this._addClass( "ui-autocomplete-input" );
    +		this.element.attr( "autocomplete", "off" );
    +
    +		this._on( this.element, {
    +			keydown: function( event ) {
    +				if ( this.element.prop( "readOnly" ) ) {
    +					suppressKeyPress = true;
    +					suppressInput = true;
    +					suppressKeyPressRepeat = true;
    +					return;
    +				}
    +
    +				suppressKeyPress = false;
    +				suppressInput = false;
    +				suppressKeyPressRepeat = false;
    +				var keyCode = $.ui.keyCode;
    +				switch ( event.keyCode ) {
    +				case keyCode.PAGE_UP:
    +					suppressKeyPress = true;
    +					this._move( "previousPage", event );
    +					break;
    +				case keyCode.PAGE_DOWN:
    +					suppressKeyPress = true;
    +					this._move( "nextPage", event );
    +					break;
    +				case keyCode.UP:
    +					suppressKeyPress = true;
    +					this._keyEvent( "previous", event );
    +					break;
    +				case keyCode.DOWN:
    +					suppressKeyPress = true;
    +					this._keyEvent( "next", event );
    +					break;
    +				case keyCode.ENTER:
    +
    +					// when menu is open and has focus
    +					if ( this.menu.active ) {
    +
    +						// #6055 - Opera still allows the keypress to occur
    +						// which causes forms to submit
    +						suppressKeyPress = true;
    +						event.preventDefault();
    +						this.menu.select( event );
    +					}
    +					break;
    +				case keyCode.TAB:
    +					if ( this.menu.active ) {
    +						this.menu.select( event );
    +					}
    +					break;
    +				case keyCode.ESCAPE:
    +					if ( this.menu.element.is( ":visible" ) ) {
    +						if ( !this.isMultiLine ) {
    +							this._value( this.term );
    +						}
    +						this.close( event );
    +
    +						// Different browsers have different default behavior for escape
    +						// Single press can mean undo or clear
    +						// Double press in IE means clear the whole form
    +						event.preventDefault();
    +					}
    +					break;
    +				default:
    +					suppressKeyPressRepeat = true;
    +
    +					// search timeout should be triggered before the input value is changed
    +					this._searchTimeout( event );
    +					break;
    +				}
    +			},
    +			keypress: function( event ) {
    +				if ( suppressKeyPress ) {
    +					suppressKeyPress = false;
    +					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
    +						event.preventDefault();
    +					}
    +					return;
    +				}
    +				if ( suppressKeyPressRepeat ) {
    +					return;
    +				}
    +
    +				// Replicate some key handlers to allow them to repeat in Firefox and Opera
    +				var keyCode = $.ui.keyCode;
    +				switch ( event.keyCode ) {
    +				case keyCode.PAGE_UP:
    +					this._move( "previousPage", event );
    +					break;
    +				case keyCode.PAGE_DOWN:
    +					this._move( "nextPage", event );
    +					break;
    +				case keyCode.UP:
    +					this._keyEvent( "previous", event );
    +					break;
    +				case keyCode.DOWN:
    +					this._keyEvent( "next", event );
    +					break;
    +				}
    +			},
    +			input: function( event ) {
    +				if ( suppressInput ) {
    +					suppressInput = false;
    +					event.preventDefault();
    +					return;
    +				}
    +				this._searchTimeout( event );
    +			},
    +			focus: function() {
    +				this.selectedItem = null;
    +				this.previous = this._value();
    +			},
    +			blur: function( event ) {
    +				if ( this.cancelBlur ) {
    +					delete this.cancelBlur;
    +					return;
    +				}
    +
    +				clearTimeout( this.searching );
    +				this.close( event );
    +				this._change( event );
    +			}
    +		} );
    +
    +		this._initSource();
    +		this.menu = $( "<ul>" )
    +			.appendTo( this._appendTo() )
    +			.menu( {
    +
    +				// disable ARIA support, the live region takes care of that
    +				role: null
    +			} )
    +			.hide()
    +			.menu( "instance" );
    +
    +		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
    +		this._on( this.menu.element, {
    +			mousedown: function( event ) {
    +
    +				// prevent moving focus out of the text field
    +				event.preventDefault();
    +
    +				// IE doesn't prevent moving focus even with event.preventDefault()
    +				// so we set a flag to know when we should ignore the blur event
    +				this.cancelBlur = true;
    +				this._delay( function() {
    +					delete this.cancelBlur;
    +
    +					// Support: IE 8 only
    +					// Right clicking a menu item or selecting text from the menu items will
    +					// result in focus moving out of the input. However, we've already received
    +					// and ignored the blur event because of the cancelBlur flag set above. So
    +					// we restore focus to ensure that the menu closes properly based on the user's
    +					// next actions.
    +					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
    +						this.element.trigger( "focus" );
    +					}
    +				} );
    +			},
    +			menufocus: function( event, ui ) {
    +				var label, item;
    +
    +				// support: Firefox
    +				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
    +				if ( this.isNewMenu ) {
    +					this.isNewMenu = false;
    +					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
    +						this.menu.blur();
    +
    +						this.document.one( "mousemove", function() {
    +							$( event.target ).trigger( event.originalEvent );
    +						} );
    +
    +						return;
    +					}
    +				}
    +
    +				item = ui.item.data( "ui-autocomplete-item" );
    +				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
    +
    +					// use value to match what will end up in the input, if it was a key event
    +					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
    +						this._value( item.value );
    +					}
    +				}
    +
    +				// Announce the value in the liveRegion
    +				label = ui.item.attr( "aria-label" ) || item.value;
    +				if ( label && $.trim( label ).length ) {
    +					this.liveRegion.children().hide();
    +					$( "<div>" ).text( label ).appendTo( this.liveRegion );
    +				}
    +			},
    +			menuselect: function( event, ui ) {
    +				var item = ui.item.data( "ui-autocomplete-item" ),
    +					previous = this.previous;
    +
    +				// Only trigger when focus was lost (click on menu)
    +				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
    +					this.element.trigger( "focus" );
    +					this.previous = previous;
    +
    +					// #6109 - IE triggers two focus events and the second
    +					// is asynchronous, so we need to reset the previous
    +					// term synchronously and asynchronously :-(
    +					this._delay( function() {
    +						this.previous = previous;
    +						this.selectedItem = item;
    +					} );
    +				}
    +
    +				if ( false !== this._trigger( "select", event, { item: item } ) ) {
    +					this._value( item.value );
    +				}
    +
    +				// reset the term after the select event
    +				// this allows custom select handling to work properly
    +				this.term = this._value();
    +
    +				this.close( event );
    +				this.selectedItem = item;
    +			}
    +		} );
    +
    +		this.liveRegion = $( "<div>", {
    +			role: "status",
    +			"aria-live": "assertive",
    +			"aria-relevant": "additions"
    +		} )
    +			.appendTo( this.document[ 0 ].body );
    +
    +		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
    +
    +		// Turning off autocomplete prevents the browser from remembering the
    +		// value when navigating through history, so we re-enable autocomplete
    +		// if the page is unloaded before the widget is destroyed. #7790
    +		this._on( this.window, {
    +			beforeunload: function() {
    +				this.element.removeAttr( "autocomplete" );
    +			}
    +		} );
    +	},
    +
    +	_destroy: function() {
    +		clearTimeout( this.searching );
    +		this.element.removeAttr( "autocomplete" );
    +		this.menu.element.remove();
    +		this.liveRegion.remove();
    +	},
    +
    +	_setOption: function( key, value ) {
    +		this._super( key, value );
    +		if ( key === "source" ) {
    +			this._initSource();
    +		}
    +		if ( key === "appendTo" ) {
    +			this.menu.element.appendTo( this._appendTo() );
    +		}
    +		if ( key === "disabled" && value && this.xhr ) {
    +			this.xhr.abort();
    +		}
    +	},
    +
    +	_isEventTargetInWidget: function( event ) {
    +		var menuElement = this.menu.element[ 0 ];
    +
    +		return event.target === this.element[ 0 ] ||
    +			event.target === menuElement ||
    +			$.contains( menuElement, event.target );
    +	},
    +
    +	_closeOnClickOutside: function( event ) {
    +		if ( !this._isEventTargetInWidget( event ) ) {
    +			this.close();
    +		}
    +	},
    +
    +	_appendTo: function() {
    +		var element = this.options.appendTo;
    +
    +		if ( element ) {
    +			element = element.jquery || element.nodeType ?
    +				$( element ) :
    +				this.document.find( element ).eq( 0 );
    +		}
    +
    +		if ( !element || !element[ 0 ] ) {
    +			element = this.element.closest( ".ui-front, dialog" );
    +		}
    +
    +		if ( !element.length ) {
    +			element = this.document[ 0 ].body;
    +		}
    +
    +		return element;
    +	},
    +
    +	_initSource: function() {
    +		var array, url,
    +			that = this;
    +		if ( $.isArray( this.options.source ) ) {
    +			array = this.options.source;
    +			this.source = function( request, response ) {
    +				response( $.ui.autocomplete.filter( array, request.term ) );
    +			};
    +		} else if ( typeof this.options.source === "string" ) {
    +			url = this.options.source;
    +			this.source = function( request, response ) {
    +				if ( that.xhr ) {
    +					that.xhr.abort();
    +				}
    +				that.xhr = $.ajax( {
    +					url: url,
    +					data: request,
    +					dataType: "json",
    +					success: function( data ) {
    +						response( data );
    +					},
    +					error: function() {
    +						response( [] );
    +					}
    +				} );
    +			};
    +		} else {
    +			this.source = this.options.source;
    +		}
    +	},
    +
    +	_searchTimeout: function( event ) {
    +		clearTimeout( this.searching );
    +		this.searching = this._delay( function() {
    +
    +			// Search if the value has changed, or if the user retypes the same value (see #7434)
    +			var equalValues = this.term === this._value(),
    +				menuVisible = this.menu.element.is( ":visible" ),
    +				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
    +
    +			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
    +				this.selectedItem = null;
    +				this.search( null, event );
    +			}
    +		}, this.options.delay );
    +	},
    +
    +	search: function( value, event ) {
    +		value = value != null ? value : this._value();
    +
    +		// Always save the actual value, not the one passed as an argument
    +		this.term = this._value();
    +
    +		if ( value.length < this.options.minLength ) {
    +			return this.close( event );
    +		}
    +
    +		if ( this._trigger( "search", event ) === false ) {
    +			return;
    +		}
    +
    +		return this._search( value );
    +	},
    +
    +	_search: function( value ) {
    +		this.pending++;
    +		this._addClass( "ui-autocomplete-loading" );
    +		this.cancelSearch = false;
    +
    +		this.source( { term: value }, this._response() );
    +	},
    +
    +	_response: function() {
    +		var index = ++this.requestIndex;
    +
    +		return $.proxy( function( content ) {
    +			if ( index === this.requestIndex ) {
    +				this.__response( content );
    +			}
    +
    +			this.pending--;
    +			if ( !this.pending ) {
    +				this._removeClass( "ui-autocomplete-loading" );
    +			}
    +		}, this );
    +	},
    +
    +	__response: function( content ) {
    +		if ( content ) {
    +			content = this._normalize( content );
    +		}
    +		this._trigger( "response", null, { content: content } );
    +		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
    +			this._suggest( content );
    +			this._trigger( "open" );
    +		} else {
    +
    +			// use ._close() instead of .close() so we don't cancel future searches
    +			this._close();
    +		}
    +	},
    +
    +	close: function( event ) {
    +		this.cancelSearch = true;
    +		this._close( event );
    +	},
    +
    +	_close: function( event ) {
    +
    +		// Remove the handler that closes the menu on outside clicks
    +		this._off( this.document, "mousedown" );
    +
    +		if ( this.menu.element.is( ":visible" ) ) {
    +			this.menu.element.hide();
    +			this.menu.blur();
    +			this.isNewMenu = true;
    +			this._trigger( "close", event );
    +		}
    +	},
    +
    +	_change: function( event ) {
    +		if ( this.previous !== this._value() ) {
    +			this._trigger( "change", event, { item: this.selectedItem } );
    +		}
    +	},
    +
    +	_normalize: function( items ) {
    +
    +		// assume all items have the right format when the first item is complete
    +		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
    +			return items;
    +		}
    +		return $.map( items, function( item ) {
    +			if ( typeof item === "string" ) {
    +				return {
    +					label: item,
    +					value: item
    +				};
    +			}
    +			return $.extend( {}, item, {
    +				label: item.label || item.value,
    +				value: item.value || item.label
    +			} );
    +		} );
    +	},
    +
    +	_suggest: function( items ) {
    +		var ul = this.menu.element.empty();
    +		this._renderMenu( ul, items );
    +		this.isNewMenu = true;
    +		this.menu.refresh();
    +
    +		// Size and position menu
    +		ul.show();
    +		this._resizeMenu();
    +		ul.position( $.extend( {
    +			of: this.element
    +		}, this.options.position ) );
    +
    +		if ( this.options.autoFocus ) {
    +			this.menu.next();
    +		}
    +
    +		// Listen for interactions outside of the widget (#6642)
    +		this._on( this.document, {
    +			mousedown: "_closeOnClickOutside"
    +		} );
    +	},
    +
    +	_resizeMenu: function() {
    +		var ul = this.menu.element;
    +		ul.outerWidth( Math.max(
    +
    +			// Firefox wraps long text (possibly a rounding bug)
    +			// so we add 1px to avoid the wrapping (#7513)
    +			ul.width( "" ).outerWidth() + 1,
    +			this.element.outerWidth()
    +		) );
    +	},
    +
    +	_renderMenu: function( ul, items ) {
    +		var that = this;
    +		$.each( items, function( index, item ) {
    +			that._renderItemData( ul, item );
    +		} );
    +	},
    +
    +	_renderItemData: function( ul, item ) {
    +		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
    +	},
    +
    +	_renderItem: function( ul, item ) {
    +		return $( "<li>" )
    +			.append( $( "<div>" ).text( item.label ) )
    +			.appendTo( ul );
    +	},
    +
    +	_move: function( direction, event ) {
    +		if ( !this.menu.element.is( ":visible" ) ) {
    +			this.search( null, event );
    +			return;
    +		}
    +		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
    +				this.menu.isLastItem() && /^next/.test( direction ) ) {
    +
    +			if ( !this.isMultiLine ) {
    +				this._value( this.term );
    +			}
    +
    +			this.menu.blur();
    +			return;
    +		}
    +		this.menu[ direction ]( event );
    +	},
    +
    +	widget: function() {
    +		return this.menu.element;
    +	},
    +
    +	_value: function() {
    +		return this.valueMethod.apply( this.element, arguments );
    +	},
    +
    +	_keyEvent: function( keyEvent, event ) {
    +		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
    +			this._move( keyEvent, event );
    +
    +			// Prevents moving cursor to beginning/end of the text field in some browsers
    +			event.preventDefault();
    +		}
    +	},
    +
    +	// Support: Chrome <=50
    +	// We should be able to just use this.element.prop( "isContentEditable" )
    +	// but hidden elements always report false in Chrome.
    +	// https://code.google.com/p/chromium/issues/detail?id=313082
    +	_isContentEditable: function( element ) {
    +		if ( !element.length ) {
    +			return false;
    +		}
    +
    +		var editable = element.prop( "contentEditable" );
    +
    +		if ( editable === "inherit" ) {
    +		  return this._isContentEditable( element.parent() );
    +		}
    +
    +		return editable === "true";
    +	}
    +} );
    +
    +$.extend( $.ui.autocomplete, {
    +	escapeRegex: function( value ) {
    +		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
    +	},
    +	filter: function( array, term ) {
    +		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
    +		return $.grep( array, function( value ) {
    +			return matcher.test( value.label || value.value || value );
    +		} );
    +	}
    +} );
    +
    +// Live region extension, adding a `messages` option
    +// NOTE: This is an experimental API. We are still investigating
    +// a full solution for string manipulation and internationalization.
    +$.widget( "ui.autocomplete", $.ui.autocomplete, {
    +	options: {
    +		messages: {
    +			noResults: "No search results.",
    +			results: function( amount ) {
    +				return amount + ( amount > 1 ? " results are" : " result is" ) +
    +					" available, use up and down arrow keys to navigate.";
    +			}
    +		}
    +	},
    +
    +	__response: function( content ) {
    +		var message;
    +		this._superApply( arguments );
    +		if ( this.options.disabled || this.cancelSearch ) {
    +			return;
    +		}
    +		if ( content && content.length ) {
    +			message = this.options.messages.results( content.length );
    +		} else {
    +			message = this.options.messages.noResults;
    +		}
    +		this.liveRegion.children().hide();
    +		$( "<div>" ).text( message ).appendTo( this.liveRegion );
    +	}
    +} );
    +
    +var widgetsAutocomplete = $.ui.autocomplete;
    +
    +
    +/*!
    + * jQuery UI Controlgroup 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Controlgroup
    +//>>group: Widgets
    +//>>description: Visually groups form control widgets
    +//>>docs: http://api.jqueryui.com/controlgroup/
    +//>>demos: http://jqueryui.com/controlgroup/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/controlgroup.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
    +
    +var widgetsControlgroup = $.widget( "ui.controlgroup", {
    +	version: "1.12.1",
    +	defaultElement: "<div>",
    +	options: {
    +		direction: "horizontal",
    +		disabled: null,
    +		onlyVisible: true,
    +		items: {
    +			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
    +			"controlgroupLabel": ".ui-controlgroup-label",
    +			"checkboxradio": "input[type='checkbox'], input[type='radio']",
    +			"selectmenu": "select",
    +			"spinner": ".ui-spinner-input"
    +		}
    +	},
    +
    +	_create: function() {
    +		this._enhance();
    +	},
    +
    +	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
    +	_enhance: function() {
    +		this.element.attr( "role", "toolbar" );
    +		this.refresh();
    +	},
    +
    +	_destroy: function() {
    +		this._callChildMethod( "destroy" );
    +		this.childWidgets.removeData( "ui-controlgroup-data" );
    +		this.element.removeAttr( "role" );
    +		if ( this.options.items.controlgroupLabel ) {
    +			this.element
    +				.find( this.options.items.controlgroupLabel )
    +				.find( ".ui-controlgroup-label-contents" )
    +				.contents().unwrap();
    +		}
    +	},
    +
    +	_initWidgets: function() {
    +		var that = this,
    +			childWidgets = [];
    +
    +		// First we iterate over each of the items options
    +		$.each( this.options.items, function( widget, selector ) {
    +			var labels;
    +			var options = {};
    +
    +			// Make sure the widget has a selector set
    +			if ( !selector ) {
    +				return;
    +			}
    +
    +			if ( widget === "controlgroupLabel" ) {
    +				labels = that.element.find( selector );
    +				labels.each( function() {
    +					var element = $( this );
    +
    +					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
    +						return;
    +					}
    +					element.contents()
    +						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
    +				} );
    +				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
    +				childWidgets = childWidgets.concat( labels.get() );
    +				return;
    +			}
    +
    +			// Make sure the widget actually exists
    +			if ( !$.fn[ widget ] ) {
    +				return;
    +			}
    +
    +			// We assume everything is in the middle to start because we can't determine
    +			// first / last elements until all enhancments are done.
    +			if ( that[ "_" + widget + "Options" ] ) {
    +				options = that[ "_" + widget + "Options" ]( "middle" );
    +			} else {
    +				options = { classes: {} };
    +			}
    +
    +			// Find instances of this widget inside controlgroup and init them
    +			that.element
    +				.find( selector )
    +				.each( function() {
    +					var element = $( this );
    +					var instance = element[ widget ]( "instance" );
    +
    +					// We need to clone the default options for this type of widget to avoid
    +					// polluting the variable options which has a wider scope than a single widget.
    +					var instanceOptions = $.widget.extend( {}, options );
    +
    +					// If the button is the child of a spinner ignore it
    +					// TODO: Find a more generic solution
    +					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
    +						return;
    +					}
    +
    +					// Create the widget if it doesn't exist
    +					if ( !instance ) {
    +						instance = element[ widget ]()[ widget ]( "instance" );
    +					}
    +					if ( instance ) {
    +						instanceOptions.classes =
    +							that._resolveClassesValues( instanceOptions.classes, instance );
    +					}
    +					element[ widget ]( instanceOptions );
    +
    +					// Store an instance of the controlgroup to be able to reference
    +					// from the outermost element for changing options and refresh
    +					var widgetElement = element[ widget ]( "widget" );
    +					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
    +						instance ? instance : element[ widget ]( "instance" ) );
    +
    +					childWidgets.push( widgetElement[ 0 ] );
    +				} );
    +		} );
    +
    +		this.childWidgets = $( $.unique( childWidgets ) );
    +		this._addClass( this.childWidgets, "ui-controlgroup-item" );
    +	},
    +
    +	_callChildMethod: function( method ) {
    +		this.childWidgets.each( function() {
    +			var element = $( this ),
    +				data = element.data( "ui-controlgroup-data" );
    +			if ( data && data[ method ] ) {
    +				data[ method ]();
    +			}
    +		} );
    +	},
    +
    +	_updateCornerClass: function( element, position ) {
    +		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
    +		var add = this._buildSimpleOptions( position, "label" ).classes.label;
    +
    +		this._removeClass( element, null, remove );
    +		this._addClass( element, null, add );
    +	},
    +
    +	_buildSimpleOptions: function( position, key ) {
    +		var direction = this.options.direction === "vertical";
    +		var result = {
    +			classes: {}
    +		};
    +		result.classes[ key ] = {
    +			"middle": "",
    +			"first": "ui-corner-" + ( direction ? "top" : "left" ),
    +			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
    +			"only": "ui-corner-all"
    +		}[ position ];
    +
    +		return result;
    +	},
    +
    +	_spinnerOptions: function( position ) {
    +		var options = this._buildSimpleOptions( position, "ui-spinner" );
    +
    +		options.classes[ "ui-spinner-up" ] = "";
    +		options.classes[ "ui-spinner-down" ] = "";
    +
    +		return options;
    +	},
    +
    +	_buttonOptions: function( position ) {
    +		return this._buildSimpleOptions( position, "ui-button" );
    +	},
    +
    +	_checkboxradioOptions: function( position ) {
    +		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
    +	},
    +
    +	_selectmenuOptions: function( position ) {
    +		var direction = this.options.direction === "vertical";
    +		return {
    +			width: direction ? "auto" : false,
    +			classes: {
    +				middle: {
    +					"ui-selectmenu-button-open": "",
    +					"ui-selectmenu-button-closed": ""
    +				},
    +				first: {
    +					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
    +					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
    +				},
    +				last: {
    +					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
    +					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
    +				},
    +				only: {
    +					"ui-selectmenu-button-open": "ui-corner-top",
    +					"ui-selectmenu-button-closed": "ui-corner-all"
    +				}
    +
    +			}[ position ]
    +		};
    +	},
    +
    +	_resolveClassesValues: function( classes, instance ) {
    +		var result = {};
    +		$.each( classes, function( key ) {
    +			var current = instance.options.classes[ key ] || "";
    +			current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
    +			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
    +		} );
    +		return result;
    +	},
    +
    +	_setOption: function( key, value ) {
    +		if ( key === "direction" ) {
    +			this._removeClass( "ui-controlgroup-" + this.options.direction );
    +		}
    +
    +		this._super( key, value );
    +		if ( key === "disabled" ) {
    +			this._callChildMethod( value ? "disable" : "enable" );
    +			return;
    +		}
    +
    +		this.refresh();
    +	},
    +
    +	refresh: function() {
    +		var children,
    +			that = this;
    +
    +		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
    +
    +		if ( this.options.direction === "horizontal" ) {
    +			this._addClass( null, "ui-helper-clearfix" );
    +		}
    +		this._initWidgets();
    +
    +		children = this.childWidgets;
    +
    +		// We filter here because we need to track all childWidgets not just the visible ones
    +		if ( this.options.onlyVisible ) {
    +			children = children.filter( ":visible" );
    +		}
    +
    +		if ( children.length ) {
    +
    +			// We do this last because we need to make sure all enhancment is done
    +			// before determining first and last
    +			$.each( [ "first", "last" ], function( index, value ) {
    +				var instance = children[ value ]().data( "ui-controlgroup-data" );
    +
    +				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
    +					var options = that[ "_" + instance.widgetName + "Options" ](
    +						children.length === 1 ? "only" : value
    +					);
    +					options.classes = that._resolveClassesValues( options.classes, instance );
    +					instance.element[ instance.widgetName ]( options );
    +				} else {
    +					that._updateCornerClass( children[ value ](), value );
    +				}
    +			} );
    +
    +			// Finally call the refresh method on each of the child widgets.
    +			this._callChildMethod( "refresh" );
    +		}
    +	}
    +} );
    +
    +/*!
    + * jQuery UI Checkboxradio 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Checkboxradio
    +//>>group: Widgets
    +//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
    +//>>docs: http://api.jqueryui.com/checkboxradio/
    +//>>demos: http://jqueryui.com/checkboxradio/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/button.css
    +//>>css.structure: ../../themes/base/checkboxradio.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
    +	version: "1.12.1",
    +	options: {
    +		disabled: null,
    +		label: null,
    +		icon: true,
    +		classes: {
    +			"ui-checkboxradio-label": "ui-corner-all",
    +			"ui-checkboxradio-icon": "ui-corner-all"
    +		}
    +	},
    +
    +	_getCreateOptions: function() {
    +		var disabled, labels;
    +		var that = this;
    +		var options = this._super() || {};
    +
    +		// We read the type here, because it makes more sense to throw a element type error first,
    +		// rather then the error for lack of a label. Often if its the wrong type, it
    +		// won't have a label (e.g. calling on a div, btn, etc)
    +		this._readType();
    +
    +		labels = this.element.labels();
    +
    +		// If there are multiple labels, use the last one
    +		this.label = $( labels[ labels.length - 1 ] );
    +		if ( !this.label.length ) {
    +			$.error( "No label found for checkboxradio widget" );
    +		}
    +
    +		this.originalLabel = "";
    +
    +		// We need to get the label text but this may also need to make sure it does not contain the
    +		// input itself.
    +		this.label.contents().not( this.element[ 0 ] ).each( function() {
    +
    +			// The label contents could be text, html, or a mix. We concat each element to get a
    +			// string representation of the label, without the input as part of it.
    +			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
    +		} );
    +
    +		// Set the label option if we found label text
    +		if ( this.originalLabel ) {
    +			options.label = this.originalLabel;
    +		}
    +
    +		disabled = this.element[ 0 ].disabled;
    +		if ( disabled != null ) {
    +			options.disabled = disabled;
    +		}
    +		return options;
    +	},
    +
    +	_create: function() {
    +		var checked = this.element[ 0 ].checked;
    +
    +		this._bindFormResetHandler();
    +
    +		if ( this.options.disabled == null ) {
    +			this.options.disabled = this.element[ 0 ].disabled;
    +		}
    +
    +		this._setOption( "disabled", this.options.disabled );
    +		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
    +		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
    +
    +		if ( this.type === "radio" ) {
    +			this._addClass( this.label, "ui-checkboxradio-radio-label" );
    +		}
    +
    +		if ( this.options.label && this.options.label !== this.originalLabel ) {
    +			this._updateLabel();
    +		} else if ( this.originalLabel ) {
    +			this.options.label = this.originalLabel;
    +		}
    +
    +		this._enhance();
    +
    +		if ( checked ) {
    +			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
    +			if ( this.icon ) {
    +				this._addClass( this.icon, null, "ui-state-hover" );
    +			}
    +		}
    +
    +		this._on( {
    +			change: "_toggleClasses",
    +			focus: function() {
    +				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
    +			},
    +			blur: function() {
    +				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
    +			}
    +		} );
    +	},
    +
    +	_readType: function() {
    +		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
    +		this.type = this.element[ 0 ].type;
    +		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
    +			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
    +				" and element.type=" + this.type );
    +		}
    +	},
    +
    +	// Support jQuery Mobile enhanced option
    +	_enhance: function() {
    +		this._updateIcon( this.element[ 0 ].checked );
    +	},
    +
    +	widget: function() {
    +		return this.label;
    +	},
    +
    +	_getRadioGroup: function() {
    +		var group;
    +		var name = this.element[ 0 ].name;
    +		var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
    +
    +		if ( !name ) {
    +			return $( [] );
    +		}
    +
    +		if ( this.form.length ) {
    +			group = $( this.form[ 0 ].elements ).filter( nameSelector );
    +		} else {
    +
    +			// Not inside a form, check all inputs that also are not inside a form
    +			group = $( nameSelector ).filter( function() {
    +				return $( this ).form().length === 0;
    +			} );
    +		}
    +
    +		return group.not( this.element );
    +	},
    +
    +	_toggleClasses: function() {
    +		var checked = this.element[ 0 ].checked;
    +		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
    +
    +		if ( this.options.icon && this.type === "checkbox" ) {
    +			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
    +				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
    +		}
    +
    +		if ( this.type === "radio" ) {
    +			this._getRadioGroup()
    +				.each( function() {
    +					var instance = $( this ).checkboxradio( "instance" );
    +
    +					if ( instance ) {
    +						instance._removeClass( instance.label,
    +							"ui-checkboxradio-checked", "ui-state-active" );
    +					}
    +				} );
    +		}
    +	},
    +
    +	_destroy: function() {
    +		this._unbindFormResetHandler();
    +
    +		if ( this.icon ) {
    +			this.icon.remove();
    +			this.iconSpace.remove();
    +		}
    +	},
    +
    +	_setOption: function( key, value ) {
    +
    +		// We don't allow the value to be set to nothing
    +		if ( key === "label" && !value ) {
    +			return;
    +		}
    +
    +		this._super( key, value );
    +
    +		if ( key === "disabled" ) {
    +			this._toggleClass( this.label, null, "ui-state-disabled", value );
    +			this.element[ 0 ].disabled = value;
    +
    +			// Don't refresh when setting disabled
    +			return;
    +		}
    +		this.refresh();
    +	},
    +
    +	_updateIcon: function( checked ) {
    +		var toAdd = "ui-icon ui-icon-background ";
    +
    +		if ( this.options.icon ) {
    +			if ( !this.icon ) {
    +				this.icon = $( "<span>" );
    +				this.iconSpace = $( "<span> </span>" );
    +				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
    +			}
    +
    +			if ( this.type === "checkbox" ) {
    +				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
    +				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
    +			} else {
    +				toAdd += "ui-icon-blank";
    +			}
    +			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
    +			if ( !checked ) {
    +				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
    +			}
    +			this.icon.prependTo( this.label ).after( this.iconSpace );
    +		} else if ( this.icon !== undefined ) {
    +			this.icon.remove();
    +			this.iconSpace.remove();
    +			delete this.icon;
    +		}
    +	},
    +
    +	_updateLabel: function() {
    +
    +		// Remove the contents of the label ( minus the icon, icon space, and input )
    +		var contents = this.label.contents().not( this.element[ 0 ] );
    +		if ( this.icon ) {
    +			contents = contents.not( this.icon[ 0 ] );
    +		}
    +		if ( this.iconSpace ) {
    +			contents = contents.not( this.iconSpace[ 0 ] );
    +		}
    +		contents.remove();
    +
    +		this.label.append( this.options.label );
    +	},
    +
    +	refresh: function() {
    +		var checked = this.element[ 0 ].checked,
    +			isDisabled = this.element[ 0 ].disabled;
    +
    +		this._updateIcon( checked );
    +		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
    +		if ( this.options.label !== null ) {
    +			this._updateLabel();
    +		}
    +
    +		if ( isDisabled !== this.options.disabled ) {
    +			this._setOptions( { "disabled": isDisabled } );
    +		}
    +	}
    +
    +} ] );
    +
    +var widgetsCheckboxradio = $.ui.checkboxradio;
    +
    +
    +/*!
    + * jQuery UI Button 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Button
    +//>>group: Widgets
    +//>>description: Enhances a form with themeable buttons.
    +//>>docs: http://api.jqueryui.com/button/
    +//>>demos: http://jqueryui.com/button/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/button.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +$.widget( "ui.button", {
    +	version: "1.12.1",
    +	defaultElement: "<button>",
    +	options: {
    +		classes: {
    +			"ui-button": "ui-corner-all"
    +		},
    +		disabled: null,
    +		icon: null,
    +		iconPosition: "beginning",
    +		label: null,
    +		showLabel: true
    +	},
    +
    +	_getCreateOptions: function() {
    +		var disabled,
    +
    +			// This is to support cases like in jQuery Mobile where the base widget does have
    +			// an implementation of _getCreateOptions
    +			options = this._super() || {};
    +
    +		this.isInput = this.element.is( "input" );
    +
    +		disabled = this.element[ 0 ].disabled;
    +		if ( disabled != null ) {
    +			options.disabled = disabled;
    +		}
    +
    +		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
    +		if ( this.originalLabel ) {
    +			options.label = this.originalLabel;
    +		}
    +
    +		return options;
    +	},
    +
    +	_create: function() {
    +		if ( !this.option.showLabel & !this.options.icon ) {
    +			this.options.showLabel = true;
    +		}
    +
    +		// We have to check the option again here even though we did in _getCreateOptions,
    +		// because null may have been passed on init which would override what was set in
    +		// _getCreateOptions
    +		if ( this.options.disabled == null ) {
    +			this.options.disabled = this.element[ 0 ].disabled || false;
    +		}
    +
    +		this.hasTitle = !!this.element.attr( "title" );
    +
    +		// Check to see if the label needs to be set or if its already correct
    +		if ( this.options.label && this.options.label !== this.originalLabel ) {
    +			if ( this.isInput ) {
    +				this.element.val( this.options.label );
    +			} else {
    +				this.element.html( this.options.label );
    +			}
    +		}
    +		this._addClass( "ui-button", "ui-widget" );
    +		this._setOption( "disabled", this.options.disabled );
    +		this._enhance();
    +
    +		if ( this.element.is( "a" ) ) {
    +			this._on( {
    +				"keyup": function( event ) {
    +					if ( event.keyCode === $.ui.keyCode.SPACE ) {
    +						event.preventDefault();
    +
    +						// Support: PhantomJS <= 1.9, IE 8 Only
    +						// If a native click is available use it so we actually cause navigation
    +						// otherwise just trigger a click event
    +						if ( this.element[ 0 ].click ) {
    +							this.element[ 0 ].click();
    +						} else {
    +							this.element.trigger( "click" );
    +						}
    +					}
    +				}
    +			} );
    +		}
    +	},
    +
    +	_enhance: function() {
    +		if ( !this.element.is( "button" ) ) {
    +			this.element.attr( "role", "button" );
    +		}
    +
    +		if ( this.options.icon ) {
    +			this._updateIcon( "icon", this.options.icon );
    +			this._updateTooltip();
    +		}
    +	},
    +
    +	_updateTooltip: function() {
    +		this.title = this.element.attr( "title" );
    +
    +		if ( !this.options.showLabel && !this.title ) {
    +			this.element.attr( "title", this.options.label );
    +		}
    +	},
    +
    +	_updateIcon: function( option, value ) {
    +		var icon = option !== "iconPosition",
    +			position = icon ? this.options.iconPosition : value,
    +			displayBlock = position === "top" || position === "bottom";
    +
    +		// Create icon
    +		if ( !this.icon ) {
    +			this.icon = $( "<span>" );
    +
    +			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
    +
    +			if ( !this.options.showLabel ) {
    +				this._addClass( "ui-button-icon-only" );
    +			}
    +		} else if ( icon ) {
    +
    +			// If we are updating the icon remove the old icon class
    +			this._removeClass( this.icon, null, this.options.icon );
    +		}
    +
    +		// If we are updating the icon add the new icon class
    +		if ( icon ) {
    +			this._addClass( this.icon, null, value );
    +		}
    +
    +		this._attachIcon( position );
    +
    +		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
    +		// the iconSpace if there is one.
    +		if ( displayBlock ) {
    +			this._addClass( this.icon, null, "ui-widget-icon-block" );
    +			if ( this.iconSpace ) {
    +				this.iconSpace.remove();
    +			}
    +		} else {
    +
    +			// Position is beginning or end so remove the ui-widget-icon-block class and add the
    +			// space if it does not exist
    +			if ( !this.iconSpace ) {
    +				this.iconSpace = $( "<span> </span>" );
    +				this._addClass( this.iconSpace, "ui-button-icon-space" );
    +			}
    +			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
    +			this._attachIconSpace( position );
    +		}
    +	},
    +
    +	_destroy: function() {
    +		this.element.removeAttr( "role" );
    +
    +		if ( this.icon ) {
    +			this.icon.remove();
    +		}
    +		if ( this.iconSpace ) {
    +			this.iconSpace.remove();
    +		}
    +		if ( !this.hasTitle ) {
    +			this.element.removeAttr( "title" );
    +		}
    +	},
    +
    +	_attachIconSpace: function( iconPosition ) {
    +		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
    +	},
    +
    +	_attachIcon: function( iconPosition ) {
    +		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
    +	},
    +
    +	_setOptions: function( options ) {
    +		var newShowLabel = options.showLabel === undefined ?
    +				this.options.showLabel :
    +				options.showLabel,
    +			newIcon = options.icon === undefined ? this.options.icon : options.icon;
    +
    +		if ( !newShowLabel && !newIcon ) {
    +			options.showLabel = true;
    +		}
    +		this._super( options );
    +	},
    +
    +	_setOption: function( key, value ) {
    +		if ( key === "icon" ) {
    +			if ( value ) {
    +				this._updateIcon( key, value );
    +			} else if ( this.icon ) {
    +				this.icon.remove();
    +				if ( this.iconSpace ) {
    +					this.iconSpace.remove();
    +				}
    +			}
    +		}
    +
    +		if ( key === "iconPosition" ) {
    +			this._updateIcon( key, value );
    +		}
    +
    +		// Make sure we can't end up with a button that has neither text nor icon
    +		if ( key === "showLabel" ) {
    +				this._toggleClass( "ui-button-icon-only", null, !value );
    +				this._updateTooltip();
    +		}
    +
    +		if ( key === "label" ) {
    +			if ( this.isInput ) {
    +				this.element.val( value );
    +			} else {
    +
    +				// If there is an icon, append it, else nothing then append the value
    +				// this avoids removal of the icon when setting label text
    +				this.element.html( value );
    +				if ( this.icon ) {
    +					this._attachIcon( this.options.iconPosition );
    +					this._attachIconSpace( this.options.iconPosition );
    +				}
    +			}
    +		}
    +
    +		this._super( key, value );
    +
    +		if ( key === "disabled" ) {
    +			this._toggleClass( null, "ui-state-disabled", value );
    +			this.element[ 0 ].disabled = value;
    +			if ( value ) {
    +				this.element.blur();
    +			}
    +		}
    +	},
    +
    +	refresh: function() {
    +
    +		// Make sure to only check disabled if its an element that supports this otherwise
    +		// check for the disabled class to determine state
    +		var isDisabled = this.element.is( "input, button" ) ?
    +			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
    +
    +		if ( isDisabled !== this.options.disabled ) {
    +			this._setOptions( { disabled: isDisabled } );
    +		}
    +
    +		this._updateTooltip();
    +	}
    +} );
    +
    +// DEPRECATED
    +if ( $.uiBackCompat !== false ) {
    +
    +	// Text and Icons options
    +	$.widget( "ui.button", $.ui.button, {
    +		options: {
    +			text: true,
    +			icons: {
    +				primary: null,
    +				secondary: null
    +			}
    +		},
    +
    +		_create: function() {
    +			if ( this.options.showLabel && !this.options.text ) {
    +				this.options.showLabel = this.options.text;
    +			}
    +			if ( !this.options.showLabel && this.options.text ) {
    +				this.options.text = this.options.showLabel;
    +			}
    +			if ( !this.options.icon && ( this.options.icons.primary ||
    +					this.options.icons.secondary ) ) {
    +				if ( this.options.icons.primary ) {
    +					this.options.icon = this.options.icons.primary;
    +				} else {
    +					this.options.icon = this.options.icons.secondary;
    +					this.options.iconPosition = "end";
    +				}
    +			} else if ( this.options.icon ) {
    +				this.options.icons.primary = this.options.icon;
    +			}
    +			this._super();
    +		},
    +
    +		_setOption: function( key, value ) {
    +			if ( key === "text" ) {
    +				this._super( "showLabel", value );
    +				return;
    +			}
    +			if ( key === "showLabel" ) {
    +				this.options.text = value;
    +			}
    +			if ( key === "icon" ) {
    +				this.options.icons.primary = value;
    +			}
    +			if ( key === "icons" ) {
    +				if ( value.primary ) {
    +					this._super( "icon", value.primary );
    +					this._super( "iconPosition", "beginning" );
    +				} else if ( value.secondary ) {
    +					this._super( "icon", value.secondary );
    +					this._super( "iconPosition", "end" );
    +				}
    +			}
    +			this._superApply( arguments );
    +		}
    +	} );
    +
    +	$.fn.button = ( function( orig ) {
    +		return function() {
    +			if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
    +					( this.length && this[ 0 ].tagName === "INPUT" && (
    +						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
    +					) ) ) {
    +				return orig.apply( this, arguments );
    +			}
    +			if ( !$.ui.checkboxradio ) {
    +				$.error( "Checkboxradio widget missing" );
    +			}
    +			if ( arguments.length === 0 ) {
    +				return this.checkboxradio( {
    +					"icon": false
    +				} );
    +			}
    +			return this.checkboxradio.apply( this, arguments );
    +		};
    +	} )( $.fn.button );
    +
    +	$.fn.buttonset = function() {
    +		if ( !$.ui.controlgroup ) {
    +			$.error( "Controlgroup widget missing" );
    +		}
    +		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
    +			return this.controlgroup.apply( this,
    +				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
    +		}
    +		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
    +			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
    +		}
    +		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
    +			arguments[ 0 ].items = {
    +				button: arguments[ 0 ].items
    +			};
    +		}
    +		return this.controlgroup.apply( this, arguments );
    +	};
    +}
    +
    +var widgetsButton = $.ui.button;
    +
    +
    +// jscs:disable maximumLineLength
    +/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
    +/*!
    + * jQuery UI Datepicker 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Datepicker
    +//>>group: Widgets
    +//>>description: Displays a calendar from an input or inline for selecting dates.
    +//>>docs: http://api.jqueryui.com/datepicker/
    +//>>demos: http://jqueryui.com/datepicker/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/datepicker.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +$.extend( $.ui, { datepicker: { version: "1.12.1" } } );
    +
    +var datepicker_instActive;
    +
    +function datepicker_getZindex( elem ) {
    +	var position, value;
    +	while ( elem.length && elem[ 0 ] !== document ) {
    +
    +		// Ignore z-index if position is set to a value where z-index is ignored by the browser
    +		// This makes behavior of this function consistent across browsers
    +		// WebKit always returns auto if the element is positioned
    +		position = elem.css( "position" );
    +		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
    +
    +			// IE returns 0 when zIndex is not specified
    +			// other browsers return a string
    +			// we ignore the case of nested elements with an explicit value of 0
    +			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
    +			value = parseInt( elem.css( "zIndex" ), 10 );
    +			if ( !isNaN( value ) && value !== 0 ) {
    +				return value;
    +			}
    +		}
    +		elem = elem.parent();
    +	}
    +
    +	return 0;
    +}
    +/* Date picker manager.
    +   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
    +   Settings for (groups of) date pickers are maintained in an instance object,
    +   allowing multiple different settings on the same page. */
    +
    +function Datepicker() {
    +	this._curInst = null; // The current instance in use
    +	this._keyEvent = false; // If the last event was a key event
    +	this._disabledInputs = []; // List of date picker inputs that have been disabled
    +	this._datepickerShowing = false; // True if the popup picker is showing , false if not
    +	this._inDialog = false; // True if showing within a "dialog", false if not
    +	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
    +	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
    +	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
    +	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
    +	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
    +	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
    +	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
    +	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
    +	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
    +	this.regional = []; // Available regional settings, indexed by language code
    +	this.regional[ "" ] = { // Default regional settings
    +		closeText: "Done", // Display text for close link
    +		prevText: "Prev", // Display text for previous month link
    +		nextText: "Next", // Display text for next month link
    +		currentText: "Today", // Display text for current month link
    +		monthNames: [ "January","February","March","April","May","June",
    +			"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
    +		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
    +		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
    +		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
    +		dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
    +		weekHeader: "Wk", // Column header for week of the year
    +		dateFormat: "mm/dd/yy", // See format options on parseDate
    +		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
    +		isRTL: false, // True if right-to-left language, false if left-to-right
    +		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
    +		yearSuffix: "" // Additional text to append to the year in the month headers
    +	};
    +	this._defaults = { // Global defaults for all the date picker instances
    +		showOn: "focus", // "focus" for popup on focus,
    +			// "button" for trigger button, or "both" for either
    +		showAnim: "fadeIn", // Name of jQuery animation for popup
    +		showOptions: {}, // Options for enhanced animations
    +		defaultDate: null, // Used when field is blank: actual date,
    +			// +/-number for offset from today, null for today
    +		appendText: "", // Display text following the input box, e.g. showing the format
    +		buttonText: "...", // Text for trigger button
    +		buttonImage: "", // URL for trigger button image
    +		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
    +		hideIfNoPrevNext: false, // True to hide next/previous month links
    +			// if not applicable, false to just disable them
    +		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
    +		gotoCurrent: false, // True if today link goes back to current selection instead
    +		changeMonth: false, // True if month can be selected directly, false if only prev/next
    +		changeYear: false, // True if year can be selected directly, false if only prev/next
    +		yearRange: "c-10:c+10", // Range of years to display in drop-down,
    +			// either relative to today's year (-nn:+nn), relative to currently displayed year
    +			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
    +		showOtherMonths: false, // True to show dates in other months, false to leave blank
    +		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
    +		showWeek: false, // True to show week of the year, false to not show it
    +		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
    +			// takes a Date and returns the number of the week for it
    +		shortYearCutoff: "+10", // Short year values < this are in the current century,
    +			// > this are in the previous century,
    +			// string value starting with "+" for current year + value
    +		minDate: null, // The earliest selectable date, or null for no limit
    +		maxDate: null, // The latest selectable date, or null for no limit
    +		duration: "fast", // Duration of display/closure
    +		beforeShowDay: null, // Function that takes a date and returns an array with
    +			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
    +			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
    +		beforeShow: null, // Function that takes an input field and
    +			// returns a set of custom settings for the date picker
    +		onSelect: null, // Define a callback function when a date is selected
    +		onChangeMonthYear: null, // Define a callback function when the month or year is changed
    +		onClose: null, // Define a callback function when the datepicker is closed
    +		numberOfMonths: 1, // Number of months to show at a time
    +		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
    +		stepMonths: 1, // Number of months to step back/forward
    +		stepBigMonths: 12, // Number of months to step back/forward for the big links
    +		altField: "", // Selector for an alternate field to store selected dates into
    +		altFormat: "", // The date format to use for the alternate field
    +		constrainInput: true, // The input is constrained by the current date format
    +		showButtonPanel: false, // True to show button panel, false to not show it
    +		autoSize: false, // True to size the input for the date format, false to leave as is
    +		disabled: false // The initial disabled state
    +	};
    +	$.extend( this._defaults, this.regional[ "" ] );
    +	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
    +	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
    +	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
    +}
    +
    +$.extend( Datepicker.prototype, {
    +	/* Class name added to elements to indicate already configured with a date picker. */
    +	markerClassName: "hasDatepicker",
    +
    +	//Keep track of the maximum number of rows displayed (see #7043)
    +	maxRows: 4,
    +
    +	// TODO rename to "widget" when switching to widget factory
    +	_widgetDatepicker: function() {
    +		return this.dpDiv;
    +	},
    +
    +	/* Override the default settings for all instances of the date picker.
    +	 * @param  settings  object - the new settings to use as defaults (anonymous object)
    +	 * @return the manager object
    +	 */
    +	setDefaults: function( settings ) {
    +		datepicker_extendRemove( this._defaults, settings || {} );
    +		return this;
    +	},
    +
    +	/* Attach the date picker to a jQuery selection.
    +	 * @param  target	element - the target input field or division or span
    +	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
    +	 */
    +	_attachDatepicker: function( target, settings ) {
    +		var nodeName, inline, inst;
    +		nodeName = target.nodeName.toLowerCase();
    +		inline = ( nodeName === "div" || nodeName === "span" );
    +		if ( !target.id ) {
    +			this.uuid += 1;
    +			target.id = "dp" + this.uuid;
    +		}
    +		inst = this._newInst( $( target ), inline );
    +		inst.settings = $.extend( {}, settings || {} );
    +		if ( nodeName === "input" ) {
    +			this._connectDatepicker( target, inst );
    +		} else if ( inline ) {
    +			this._inlineDatepicker( target, inst );
    +		}
    +	},
    +
    +	/* Create a new instance object. */
    +	_newInst: function( target, inline ) {
    +		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
    +		return { id: id, input: target, // associated target
    +			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
    +			drawMonth: 0, drawYear: 0, // month being drawn
    +			inline: inline, // is datepicker inline or not
    +			dpDiv: ( !inline ? this.dpDiv : // presentation div
    +			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
    +	},
    +
    +	/* Attach the date picker to an input field. */
    +	_connectDatepicker: function( target, inst ) {
    +		var input = $( target );
    +		inst.append = $( [] );
    +		inst.trigger = $( [] );
    +		if ( input.hasClass( this.markerClassName ) ) {
    +			return;
    +		}
    +		this._attachments( input, inst );
    +		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
    +			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
    +		this._autoSize( inst );
    +		$.data( target, "datepicker", inst );
    +
    +		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
    +		if ( inst.settings.disabled ) {
    +			this._disableDatepicker( target );
    +		}
    +	},
    +
    +	/* Make attachments based on settings. */
    +	_attachments: function( input, inst ) {
    +		var showOn, buttonText, buttonImage,
    +			appendText = this._get( inst, "appendText" ),
    +			isRTL = this._get( inst, "isRTL" );
    +
    +		if ( inst.append ) {
    +			inst.append.remove();
    +		}
    +		if ( appendText ) {
    +			inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
    +			input[ isRTL ? "before" : "after" ]( inst.append );
    +		}
    +
    +		input.off( "focus", this._showDatepicker );
    +
    +		if ( inst.trigger ) {
    +			inst.trigger.remove();
    +		}
    +
    +		showOn = this._get( inst, "showOn" );
    +		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
    +			input.on( "focus", this._showDatepicker );
    +		}
    +		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
    +			buttonText = this._get( inst, "buttonText" );
    +			buttonImage = this._get( inst, "buttonImage" );
    +			inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
    +				$( "<img/>" ).addClass( this._triggerClass ).
    +					attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
    +				$( "<button type='button'></button>" ).addClass( this._triggerClass ).
    +					html( !buttonImage ? buttonText : $( "<img/>" ).attr(
    +					{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
    +			input[ isRTL ? "before" : "after" ]( inst.trigger );
    +			inst.trigger.on( "click", function() {
    +				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
    +					$.datepicker._hideDatepicker();
    +				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
    +					$.datepicker._hideDatepicker();
    +					$.datepicker._showDatepicker( input[ 0 ] );
    +				} else {
    +					$.datepicker._showDatepicker( input[ 0 ] );
    +				}
    +				return false;
    +			} );
    +		}
    +	},
    +
    +	/* Apply the maximum length for the date format. */
    +	_autoSize: function( inst ) {
    +		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
    +			var findMax, max, maxI, i,
    +				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
    +				dateFormat = this._get( inst, "dateFormat" );
    +
    +			if ( dateFormat.match( /[DM]/ ) ) {
    +				findMax = function( names ) {
    +					max = 0;
    +					maxI = 0;
    +					for ( i = 0; i < names.length; i++ ) {
    +						if ( names[ i ].length > max ) {
    +							max = names[ i ].length;
    +							maxI = i;
    +						}
    +					}
    +					return maxI;
    +				};
    +				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
    +					"monthNames" : "monthNamesShort" ) ) ) );
    +				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
    +					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
    +			}
    +			inst.input.attr( "size", this._formatDate( inst, date ).length );
    +		}
    +	},
    +
    +	/* Attach an inline date picker to a div. */
    +	_inlineDatepicker: function( target, inst ) {
    +		var divSpan = $( target );
    +		if ( divSpan.hasClass( this.markerClassName ) ) {
    +			return;
    +		}
    +		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
    +		$.data( target, "datepicker", inst );
    +		this._setDate( inst, this._getDefaultDate( inst ), true );
    +		this._updateDatepicker( inst );
    +		this._updateAlternate( inst );
    +
    +		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
    +		if ( inst.settings.disabled ) {
    +			this._disableDatepicker( target );
    +		}
    +
    +		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
    +		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
    +		inst.dpDiv.css( "display", "block" );
    +	},
    +
    +	/* Pop-up the date picker in a "dialog" box.
    +	 * @param  input element - ignored
    +	 * @param  date	string or Date - the initial date to display
    +	 * @param  onSelect  function - the function to call when a date is selected
    +	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
    +	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
    +	 *					event - with x/y coordinates or
    +	 *					leave empty for default (screen centre)
    +	 * @return the manager object
    +	 */
    +	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
    +		var id, browserWidth, browserHeight, scrollX, scrollY,
    +			inst = this._dialogInst; // internal instance
    +
    +		if ( !inst ) {
    +			this.uuid += 1;
    +			id = "dp" + this.uuid;
    +			this._dialogInput = $( "<input type='text' id='" + id +
    +				"' style='position: absolute; top: -100px; width: 0px;'/>" );
    +			this._dialogInput.on( "keydown", this._doKeyDown );
    +			$( "body" ).append( this._dialogInput );
    +			inst = this._dialogInst = this._newInst( this._dialogInput, false );
    +			inst.settings = {};
    +			$.data( this._dialogInput[ 0 ], "datepicker", inst );
    +		}
    +		datepicker_extendRemove( inst.settings, settings || {} );
    +		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
    +		this._dialogInput.val( date );
    +
    +		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
    +		if ( !this._pos ) {
    +			browserWidth = document.documentElement.clientWidth;
    +			browserHeight = document.documentElement.clientHeight;
    +			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
    +			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
    +			this._pos = // should use actual width/height below
    +				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
    +		}
    +
    +		// Move input on screen for focus, but hidden behind dialog
    +		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
    +		inst.settings.onSelect = onSelect;
    +		this._inDialog = true;
    +		this.dpDiv.addClass( this._dialogClass );
    +		this._showDatepicker( this._dialogInput[ 0 ] );
    +		if ( $.blockUI ) {
    +			$.blockUI( this.dpDiv );
    +		}
    +		$.data( this._dialogInput[ 0 ], "datepicker", inst );
    +		return this;
    +	},
    +
    +	/* Detach a datepicker from its control.
    +	 * @param  target	element - the target input field or division or span
    +	 */
    +	_destroyDatepicker: function( target ) {
    +		var nodeName,
    +			$target = $( target ),
    +			inst = $.data( target, "datepicker" );
    +
    +		if ( !$target.hasClass( this.markerClassName ) ) {
    +			return;
    +		}
    +
    +		nodeName = target.nodeName.toLowerCase();
    +		$.removeData( target, "datepicker" );
    +		if ( nodeName === "input" ) {
    +			inst.append.remove();
    +			inst.trigger.remove();
    +			$target.removeClass( this.markerClassName ).
    +				off( "focus", this._showDatepicker ).
    +				off( "keydown", this._doKeyDown ).
    +				off( "keypress", this._doKeyPress ).
    +				off( "keyup", this._doKeyUp );
    +		} else if ( nodeName === "div" || nodeName === "span" ) {
    +			$target.removeClass( this.markerClassName ).empty();
    +		}
    +
    +		if ( datepicker_instActive === inst ) {
    +			datepicker_instActive = null;
    +		}
    +	},
    +
    +	/* Enable the date picker to a jQuery selection.
    +	 * @param  target	element - the target input field or division or span
    +	 */
    +	_enableDatepicker: function( target ) {
    +		var nodeName, inline,
    +			$target = $( target ),
    +			inst = $.data( target, "datepicker" );
    +
    +		if ( !$target.hasClass( this.markerClassName ) ) {
    +			return;
    +		}
    +
    +		nodeName = target.nodeName.toLowerCase();
    +		if ( nodeName === "input" ) {
    +			target.disabled = false;
    +			inst.trigger.filter( "button" ).
    +				each( function() { this.disabled = false; } ).end().
    +				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
    +		} else if ( nodeName === "div" || nodeName === "span" ) {
    +			inline = $target.children( "." + this._inlineClass );
    +			inline.children().removeClass( "ui-state-disabled" );
    +			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
    +				prop( "disabled", false );
    +		}
    +		this._disabledInputs = $.map( this._disabledInputs,
    +			function( value ) { return ( value === target ? null : value ); } ); // delete entry
    +	},
    +
    +	/* Disable the date picker to a jQuery selection.
    +	 * @param  target	element - the target input field or division or span
    +	 */
    +	_disableDatepicker: function( target ) {
    +		var nodeName, inline,
    +			$target = $( target ),
    +			inst = $.data( target, "datepicker" );
    +
    +		if ( !$target.hasClass( this.markerClassName ) ) {
    +			return;
    +		}
    +
    +		nodeName = target.nodeName.toLowerCase();
    +		if ( nodeName === "input" ) {
    +			target.disabled = true;
    +			inst.trigger.filter( "button" ).
    +				each( function() { this.disabled = true; } ).end().
    +				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
    +		} else if ( nodeName === "div" || nodeName === "span" ) {
    +			inline = $target.children( "." + this._inlineClass );
    +			inline.children().addClass( "ui-state-disabled" );
    +			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
    +				prop( "disabled", true );
    +		}
    +		this._disabledInputs = $.map( this._disabledInputs,
    +			function( value ) { return ( value === target ? null : value ); } ); // delete entry
    +		this._disabledInputs[ this._disabledInputs.length ] = target;
    +	},
    +
    +	/* Is the first field in a jQuery collection disabled as a datepicker?
    +	 * @param  target	element - the target input field or division or span
    +	 * @return boolean - true if disabled, false if enabled
    +	 */
    +	_isDisabledDatepicker: function( target ) {
    +		if ( !target ) {
    +			return false;
    +		}
    +		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
    +			if ( this._disabledInputs[ i ] === target ) {
    +				return true;
    +			}
    +		}
    +		return false;
    +	},
    +
    +	/* Retrieve the instance data for the target control.
    +	 * @param  target  element - the target input field or division or span
    +	 * @return  object - the associated instance data
    +	 * @throws  error if a jQuery problem getting data
    +	 */
    +	_getInst: function( target ) {
    +		try {
    +			return $.data( target, "datepicker" );
    +		}
    +		catch ( err ) {
    +			throw "Missing instance data for this datepicker";
    +		}
    +	},
    +
    +	/* Update or retrieve the settings for a date picker attached to an input field or division.
    +	 * @param  target  element - the target input field or division or span
    +	 * @param  name	object - the new settings to update or
    +	 *				string - the name of the setting to change or retrieve,
    +	 *				when retrieving also "all" for all instance settings or
    +	 *				"defaults" for all global defaults
    +	 * @param  value   any - the new value for the setting
    +	 *				(omit if above is an object or to retrieve a value)
    +	 */
    +	_optionDatepicker: function( target, name, value ) {
    +		var settings, date, minDate, maxDate,
    +			inst = this._getInst( target );
    +
    +		if ( arguments.length === 2 && typeof name === "string" ) {
    +			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
    +				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
    +				this._get( inst, name ) ) : null ) );
    +		}
    +
    +		settings = name || {};
    +		if ( typeof name === "string" ) {
    +			settings = {};
    +			settings[ name ] = value;
    +		}
    +
    +		if ( inst ) {
    +			if ( this._curInst === inst ) {
    +				this._hideDatepicker();
    +			}
    +
    +			date = this._getDateDatepicker( target, true );
    +			minDate = this._getMinMaxDate( inst, "min" );
    +			maxDate = this._getMinMaxDate( inst, "max" );
    +			datepicker_extendRemove( inst.settings, settings );
    +
    +			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
    +			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
    +				inst.settings.minDate = this._formatDate( inst, minDate );
    +			}
    +			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
    +				inst.settings.maxDate = this._formatDate( inst, maxDate );
    +			}
    +			if ( "disabled" in settings ) {
    +				if ( settings.disabled ) {
    +					this._disableDatepicker( target );
    +				} else {
    +					this._enableDatepicker( target );
    +				}
    +			}
    +			this._attachments( $( target ), inst );
    +			this._autoSize( inst );
    +			this._setDate( inst, date );
    +			this._updateAlternate( inst );
    +			this._updateDatepicker( inst );
    +		}
    +	},
    +
    +	// Change method deprecated
    +	_changeDatepicker: function( target, name, value ) {
    +		this._optionDatepicker( target, name, value );
    +	},
    +
    +	/* Redraw the date picker attached to an input field or division.
    +	 * @param  target  element - the target input field or division or span
    +	 */
    +	_refreshDatepicker: function( target ) {
    +		var inst = this._getInst( target );
    +		if ( inst ) {
    +			this._updateDatepicker( inst );
    +		}
    +	},
    +
    +	/* Set the dates for a jQuery selection.
    +	 * @param  target element - the target input field or division or span
    +	 * @param  date	Date - the new date
    +	 */
    +	_setDateDatepicker: function( target, date ) {
    +		var inst = this._getInst( target );
    +		if ( inst ) {
    +			this._setDate( inst, date );
    +			this._updateDatepicker( inst );
    +			this._updateAlternate( inst );
    +		}
    +	},
    +
    +	/* Get the date(s) for the first entry in a jQuery selection.
    +	 * @param  target element - the target input field or division or span
    +	 * @param  noDefault boolean - true if no default date is to be used
    +	 * @return Date - the current date
    +	 */
    +	_getDateDatepicker: function( target, noDefault ) {
    +		var inst = this._getInst( target );
    +		if ( inst && !inst.inline ) {
    +			this._setDateFromField( inst, noDefault );
    +		}
    +		return ( inst ? this._getDate( inst ) : null );
    +	},
    +
    +	/* Handle keystrokes. */
    +	_doKeyDown: function( event ) {
    +		var onSelect, dateStr, sel,
    +			inst = $.datepicker._getInst( event.target ),
    +			handled = true,
    +			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
    +
    +		inst._keyEvent = true;
    +		if ( $.datepicker._datepickerShowing ) {
    +			switch ( event.keyCode ) {
    +				case 9: $.datepicker._hideDatepicker();
    +						handled = false;
    +						break; // hide on tab out
    +				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
    +									$.datepicker._currentClass + ")", inst.dpDiv );
    +						if ( sel[ 0 ] ) {
    +							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
    +						}
    +
    +						onSelect = $.datepicker._get( inst, "onSelect" );
    +						if ( onSelect ) {
    +							dateStr = $.datepicker._formatDate( inst );
    +
    +							// Trigger custom callback
    +							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
    +						} else {
    +							$.datepicker._hideDatepicker();
    +						}
    +
    +						return false; // don't submit the form
    +				case 27: $.datepicker._hideDatepicker();
    +						break; // hide on escape
    +				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
    +							-$.datepicker._get( inst, "stepBigMonths" ) :
    +							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
    +						break; // previous month/year on page up/+ ctrl
    +				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
    +							+$.datepicker._get( inst, "stepBigMonths" ) :
    +							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
    +						break; // next month/year on page down/+ ctrl
    +				case 35: if ( event.ctrlKey || event.metaKey ) {
    +							$.datepicker._clearDate( event.target );
    +						}
    +						handled = event.ctrlKey || event.metaKey;
    +						break; // clear on ctrl or command +end
    +				case 36: if ( event.ctrlKey || event.metaKey ) {
    +							$.datepicker._gotoToday( event.target );
    +						}
    +						handled = event.ctrlKey || event.metaKey;
    +						break; // current on ctrl or command +home
    +				case 37: if ( event.ctrlKey || event.metaKey ) {
    +							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
    +						}
    +						handled = event.ctrlKey || event.metaKey;
    +
    +						// -1 day on ctrl or command +left
    +						if ( event.originalEvent.altKey ) {
    +							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
    +								-$.datepicker._get( inst, "stepBigMonths" ) :
    +								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
    +						}
    +
    +						// next month/year on alt +left on Mac
    +						break;
    +				case 38: if ( event.ctrlKey || event.metaKey ) {
    +							$.datepicker._adjustDate( event.target, -7, "D" );
    +						}
    +						handled = event.ctrlKey || event.metaKey;
    +						break; // -1 week on ctrl or command +up
    +				case 39: if ( event.ctrlKey || event.metaKey ) {
    +							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
    +						}
    +						handled = event.ctrlKey || event.metaKey;
    +
    +						// +1 day on ctrl or command +right
    +						if ( event.originalEvent.altKey ) {
    +							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
    +								+$.datepicker._get( inst, "stepBigMonths" ) :
    +								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
    +						}
    +
    +						// next month/year on alt +right
    +						break;
    +				case 40: if ( event.ctrlKey || event.metaKey ) {
    +							$.datepicker._adjustDate( event.target, +7, "D" );
    +						}
    +						handled = event.ctrlKey || event.metaKey;
    +						break; // +1 week on ctrl or command +down
    +				default: handled = false;
    +			}
    +		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
    +			$.datepicker._showDatepicker( this );
    +		} else {
    +			handled = false;
    +		}
    +
    +		if ( handled ) {
    +			event.preventDefault();
    +			event.stopPropagation();
    +		}
    +	},
    +
    +	/* Filter entered characters - based on date format. */
    +	_doKeyPress: function( event ) {
    +		var chars, chr,
    +			inst = $.datepicker._getInst( event.target );
    +
    +		if ( $.datepicker._get( inst, "constrainInput" ) ) {
    +			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
    +			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
    +			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
    +		}
    +	},
    +
    +	/* Synchronise manual entry and field/alternate field. */
    +	_doKeyUp: function( event ) {
    +		var date,
    +			inst = $.datepicker._getInst( event.target );
    +
    +		if ( inst.input.val() !== inst.lastVal ) {
    +			try {
    +				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
    +					( inst.input ? inst.input.val() : null ),
    +					$.datepicker._getFormatConfig( inst ) );
    +
    +				if ( date ) { // only if valid
    +					$.datepicker._setDateFromField( inst );
    +					$.datepicker._updateAlternate( inst );
    +					$.datepicker._updateDatepicker( inst );
    +				}
    +			}
    +			catch ( err ) {
    +			}
    +		}
    +		return true;
    +	},
    +
    +	/* Pop-up the date picker for a given input field.
    +	 * If false returned from beforeShow event handler do not show.
    +	 * @param  input  element - the input field attached to the date picker or
    +	 *					event - if triggered by focus
    +	 */
    +	_showDatepicker: function( input ) {
    +		input = input.target || input;
    +		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
    +			input = $( "input", input.parentNode )[ 0 ];
    +		}
    +
    +		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
    +			return;
    +		}
    +
    +		var inst, beforeShow, beforeShowSettings, isFixed,
    +			offset, showAnim, duration;
    +
    +		inst = $.datepicker._getInst( input );
    +		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
    +			$.datepicker._curInst.dpDiv.stop( true, true );
    +			if ( inst && $.datepicker._datepickerShowing ) {
    +				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
    +			}
    +		}
    +
    +		beforeShow = $.datepicker._get( inst, "beforeShow" );
    +		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
    +		if ( beforeShowSettings === false ) {
    +			return;
    +		}
    +		datepicker_extendRemove( inst.settings, beforeShowSettings );
    +
    +		inst.lastVal = null;
    +		$.datepicker._lastInput = input;
    +		$.datepicker._setDateFromField( inst );
    +
    +		if ( $.datepicker._inDialog ) { // hide cursor
    +			input.value = "";
    +		}
    +		if ( !$.datepicker._pos ) { // position below input
    +			$.datepicker._pos = $.datepicker._findPos( input );
    +			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
    +		}
    +
    +		isFixed = false;
    +		$( input ).parents().each( function() {
    +			isFixed |= $( this ).css( "position" ) === "fixed";
    +			return !isFixed;
    +		} );
    +
    +		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
    +		$.datepicker._pos = null;
    +
    +		//to avoid flashes on Firefox
    +		inst.dpDiv.empty();
    +
    +		// determine sizing offscreen
    +		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
    +		$.datepicker._updateDatepicker( inst );
    +
    +		// fix width for dynamic number of date pickers
    +		// and adjust position before showing
    +		offset = $.datepicker._checkOffset( inst, offset, isFixed );
    +		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
    +			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
    +			left: offset.left + "px", top: offset.top + "px" } );
    +
    +		if ( !inst.inline ) {
    +			showAnim = $.datepicker._get( inst, "showAnim" );
    +			duration = $.datepicker._get( inst, "duration" );
    +			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
    +			$.datepicker._datepickerShowing = true;
    +
    +			if ( $.effects && $.effects.effect[ showAnim ] ) {
    +				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
    +			} else {
    +				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
    +			}
    +
    +			if ( $.datepicker._shouldFocusInput( inst ) ) {
    +				inst.input.trigger( "focus" );
    +			}
    +
    +			$.datepicker._curInst = inst;
    +		}
    +	},
    +
    +	/* Generate the date picker content. */
    +	_updateDatepicker: function( inst ) {
    +		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
    +		datepicker_instActive = inst; // for delegate hover events
    +		inst.dpDiv.empty().append( this._generateHTML( inst ) );
    +		this._attachHandlers( inst );
    +
    +		var origyearshtml,
    +			numMonths = this._getNumberOfMonths( inst ),
    +			cols = numMonths[ 1 ],
    +			width = 17,
    +			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
    +
    +		if ( activeCell.length > 0 ) {
    +			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
    +		}
    +
    +		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
    +		if ( cols > 1 ) {
    +			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
    +		}
    +		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
    +			"Class" ]( "ui-datepicker-multi" );
    +		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
    +			"Class" ]( "ui-datepicker-rtl" );
    +
    +		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
    +			inst.input.trigger( "focus" );
    +		}
    +
    +		// Deffered render of the years select (to avoid flashes on Firefox)
    +		if ( inst.yearshtml ) {
    +			origyearshtml = inst.yearshtml;
    +			setTimeout( function() {
    +
    +				//assure that inst.yearshtml didn't change.
    +				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
    +					inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
    +				}
    +				origyearshtml = inst.yearshtml = null;
    +			}, 0 );
    +		}
    +	},
    +
    +	// #6694 - don't focus the input if it's already focused
    +	// this breaks the change event in IE
    +	// Support: IE and jQuery <1.9
    +	_shouldFocusInput: function( inst ) {
    +		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
    +	},
    +
    +	/* Check positioning to remain on screen. */
    +	_checkOffset: function( inst, offset, isFixed ) {
    +		var dpWidth = inst.dpDiv.outerWidth(),
    +			dpHeight = inst.dpDiv.outerHeight(),
    +			inputWidth = inst.input ? inst.input.outerWidth() : 0,
    +			inputHeight = inst.input ? inst.input.outerHeight() : 0,
    +			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
    +			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
    +
    +		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
    +		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
    +		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
    +
    +		// Now check if datepicker is showing outside window viewport - move to a better place if so.
    +		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
    +			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
    +		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
    +			Math.abs( dpHeight + inputHeight ) : 0 );
    +
    +		return offset;
    +	},
    +
    +	/* Find an object's position on the screen. */
    +	_findPos: function( obj ) {
    +		var position,
    +			inst = this._getInst( obj ),
    +			isRTL = this._get( inst, "isRTL" );
    +
    +		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
    +			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
    +		}
    +
    +		position = $( obj ).offset();
    +		return [ position.left, position.top ];
    +	},
    +
    +	/* Hide the date picker from view.
    +	 * @param  input  element - the input field attached to the date picker
    +	 */
    +	_hideDatepicker: function( input ) {
    +		var showAnim, duration, postProcess, onClose,
    +			inst = this._curInst;
    +
    +		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
    +			return;
    +		}
    +
    +		if ( this._datepickerShowing ) {
    +			showAnim = this._get( inst, "showAnim" );
    +			duration = this._get( inst, "duration" );
    +			postProcess = function() {
    +				$.datepicker._tidyDialog( inst );
    +			};
    +
    +			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
    +			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
    +				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
    +			} else {
    +				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
    +					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
    +			}
    +
    +			if ( !showAnim ) {
    +				postProcess();
    +			}
    +			this._datepickerShowing = false;
    +
    +			onClose = this._get( inst, "onClose" );
    +			if ( onClose ) {
    +				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
    +			}
    +
    +			this._lastInput = null;
    +			if ( this._inDialog ) {
    +				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
    +				if ( $.blockUI ) {
    +					$.unblockUI();
    +					$( "body" ).append( this.dpDiv );
    +				}
    +			}
    +			this._inDialog = false;
    +		}
    +	},
    +
    +	/* Tidy up after a dialog display. */
    +	_tidyDialog: function( inst ) {
    +		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
    +	},
    +
    +	/* Close date picker if clicked elsewhere. */
    +	_checkExternalClick: function( event ) {
    +		if ( !$.datepicker._curInst ) {
    +			return;
    +		}
    +
    +		var $target = $( event.target ),
    +			inst = $.datepicker._getInst( $target[ 0 ] );
    +
    +		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
    +				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
    +				!$target.hasClass( $.datepicker.markerClassName ) &&
    +				!$target.closest( "." + $.datepicker._triggerClass ).length &&
    +				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
    +			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
    +				$.datepicker._hideDatepicker();
    +		}
    +	},
    +
    +	/* Adjust one of the date sub-fields. */
    +	_adjustDate: function( id, offset, period ) {
    +		var target = $( id ),
    +			inst = this._getInst( target[ 0 ] );
    +
    +		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
    +			return;
    +		}
    +		this._adjustInstDate( inst, offset +
    +			( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
    +			period );
    +		this._updateDatepicker( inst );
    +	},
    +
    +	/* Action for current link. */
    +	_gotoToday: function( id ) {
    +		var date,
    +			target = $( id ),
    +			inst = this._getInst( target[ 0 ] );
    +
    +		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
    +			inst.selectedDay = inst.currentDay;
    +			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
    +			inst.drawYear = inst.selectedYear = inst.currentYear;
    +		} else {
    +			date = new Date();
    +			inst.selectedDay = date.getDate();
    +			inst.drawMonth = inst.selectedMonth = date.getMonth();
    +			inst.drawYear = inst.selectedYear = date.getFullYear();
    +		}
    +		this._notifyChange( inst );
    +		this._adjustDate( target );
    +	},
    +
    +	/* Action for selecting a new month/year. */
    +	_selectMonthYear: function( id, select, period ) {
    +		var target = $( id ),
    +			inst = this._getInst( target[ 0 ] );
    +
    +		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
    +		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
    +			parseInt( select.options[ select.selectedIndex ].value, 10 );
    +
    +		this._notifyChange( inst );
    +		this._adjustDate( target );
    +	},
    +
    +	/* Action for selecting a day. */
    +	_selectDay: function( id, month, year, td ) {
    +		var inst,
    +			target = $( id );
    +
    +		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
    +			return;
    +		}
    +
    +		inst = this._getInst( target[ 0 ] );
    +		inst.selectedDay = inst.currentDay = $( "a", td ).html();
    +		inst.selectedMonth = inst.currentMonth = month;
    +		inst.selectedYear = inst.currentYear = year;
    +		this._selectDate( id, this._formatDate( inst,
    +			inst.currentDay, inst.currentMonth, inst.currentYear ) );
    +	},
    +
    +	/* Erase the input field and hide the date picker. */
    +	_clearDate: function( id ) {
    +		var target = $( id );
    +		this._selectDate( target, "" );
    +	},
    +
    +	/* Update the input field with the selected date. */
    +	_selectDate: function( id, dateStr ) {
    +		var onSelect,
    +			target = $( id ),
    +			inst = this._getInst( target[ 0 ] );
    +
    +		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
    +		if ( inst.input ) {
    +			inst.input.val( dateStr );
    +		}
    +		this._updateAlternate( inst );
    +
    +		onSelect = this._get( inst, "onSelect" );
    +		if ( onSelect ) {
    +			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
    +		} else if ( inst.input ) {
    +			inst.input.trigger( "change" ); // fire the change event
    +		}
    +
    +		if ( inst.inline ) {
    +			this._updateDatepicker( inst );
    +		} else {
    +			this._hideDatepicker();
    +			this._lastInput = inst.input[ 0 ];
    +			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
    +				inst.input.trigger( "focus" ); // restore focus
    +			}
    +			this._lastInput = null;
    +		}
    +	},
    +
    +	/* Update any alternate field to synchronise with the main field. */
    +	_updateAlternate: function( inst ) {
    +		var altFormat, date, dateStr,
    +			altField = this._get( inst, "altField" );
    +
    +		if ( altField ) { // update alternate field too
    +			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
    +			date = this._getDate( inst );
    +			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
    +			$( altField ).val( dateStr );
    +		}
    +	},
    +
    +	/* Set as beforeShowDay function to prevent selection of weekends.
    +	 * @param  date  Date - the date to customise
    +	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
    +	 */
    +	noWeekends: function( date ) {
    +		var day = date.getDay();
    +		return [ ( day > 0 && day < 6 ), "" ];
    +	},
    +
    +	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
    +	 * @param  date  Date - the date to get the week for
    +	 * @return  number - the number of the week within the year that contains this date
    +	 */
    +	iso8601Week: function( date ) {
    +		var time,
    +			checkDate = new Date( date.getTime() );
    +
    +		// Find Thursday of this week starting on Monday
    +		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
    +
    +		time = checkDate.getTime();
    +		checkDate.setMonth( 0 ); // Compare with Jan 1
    +		checkDate.setDate( 1 );
    +		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
    +	},
    +
    +	/* Parse a string value into a date object.
    +	 * See formatDate below for the possible formats.
    +	 *
    +	 * @param  format string - the expected format of the date
    +	 * @param  value string - the date in the above format
    +	 * @param  settings Object - attributes include:
    +	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
    +	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
    +	 *					dayNames		string[7] - names of the days from Sunday (optional)
    +	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
    +	 *					monthNames		string[12] - names of the months (optional)
    +	 * @return  Date - the extracted date value or null if value is blank
    +	 */
    +	parseDate: function( format, value, settings ) {
    +		if ( format == null || value == null ) {
    +			throw "Invalid arguments";
    +		}
    +
    +		value = ( typeof value === "object" ? value.toString() : value + "" );
    +		if ( value === "" ) {
    +			return null;
    +		}
    +
    +		var iFormat, dim, extra,
    +			iValue = 0,
    +			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
    +			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
    +				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
    +			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
    +			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
    +			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
    +			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
    +			year = -1,
    +			month = -1,
    +			day = -1,
    +			doy = -1,
    +			literal = false,
    +			date,
    +
    +			// Check whether a format character is doubled
    +			lookAhead = function( match ) {
    +				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
    +				if ( matches ) {
    +					iFormat++;
    +				}
    +				return matches;
    +			},
    +
    +			// Extract a number from the string value
    +			getNumber = function( match ) {
    +				var isDoubled = lookAhead( match ),
    +					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
    +					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
    +					minSize = ( match === "y" ? size : 1 ),
    +					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
    +					num = value.substring( iValue ).match( digits );
    +				if ( !num ) {
    +					throw "Missing number at position " + iValue;
    +				}
    +				iValue += num[ 0 ].length;
    +				return parseInt( num[ 0 ], 10 );
    +			},
    +
    +			// Extract a name from the string value and convert to an index
    +			getName = function( match, shortNames, longNames ) {
    +				var index = -1,
    +					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
    +						return [ [ k, v ] ];
    +					} ).sort( function( a, b ) {
    +						return -( a[ 1 ].length - b[ 1 ].length );
    +					} );
    +
    +				$.each( names, function( i, pair ) {
    +					var name = pair[ 1 ];
    +					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
    +						index = pair[ 0 ];
    +						iValue += name.length;
    +						return false;
    +					}
    +				} );
    +				if ( index !== -1 ) {
    +					return index + 1;
    +				} else {
    +					throw "Unknown name at position " + iValue;
    +				}
    +			},
    +
    +			// Confirm that a literal character matches the string value
    +			checkLiteral = function() {
    +				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
    +					throw "Unexpected literal at position " + iValue;
    +				}
    +				iValue++;
    +			};
    +
    +		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
    +			if ( literal ) {
    +				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
    +					literal = false;
    +				} else {
    +					checkLiteral();
    +				}
    +			} else {
    +				switch ( format.charAt( iFormat ) ) {
    +					case "d":
    +						day = getNumber( "d" );
    +						break;
    +					case "D":
    +						getName( "D", dayNamesShort, dayNames );
    +						break;
    +					case "o":
    +						doy = getNumber( "o" );
    +						break;
    +					case "m":
    +						month = getNumber( "m" );
    +						break;
    +					case "M":
    +						month = getName( "M", monthNamesShort, monthNames );
    +						break;
    +					case "y":
    +						year = getNumber( "y" );
    +						break;
    +					case "@":
    +						date = new Date( getNumber( "@" ) );
    +						year = date.getFullYear();
    +						month = date.getMonth() + 1;
    +						day = date.getDate();
    +						break;
    +					case "!":
    +						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
    +						year = date.getFullYear();
    +						month = date.getMonth() + 1;
    +						day = date.getDate();
    +						break;
    +					case "'":
    +						if ( lookAhead( "'" ) ) {
    +							checkLiteral();
    +						} else {
    +							literal = true;
    +						}
    +						break;
    +					default:
    +						checkLiteral();
    +				}
    +			}
    +		}
    +
    +		if ( iValue < value.length ) {
    +			extra = value.substr( iValue );
    +			if ( !/^\s+/.test( extra ) ) {
    +				throw "Extra/unparsed characters found in date: " + extra;
    +			}
    +		}
    +
    +		if ( year === -1 ) {
    +			year = new Date().getFullYear();
    +		} else if ( year < 100 ) {
    +			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
    +				( year <= shortYearCutoff ? 0 : -100 );
    +		}
    +
    +		if ( doy > -1 ) {
    +			month = 1;
    +			day = doy;
    +			do {
    +				dim = this._getDaysInMonth( year, month - 1 );
    +				if ( day <= dim ) {
    +					break;
    +				}
    +				month++;
    +				day -= dim;
    +			} while ( true );
    +		}
    +
    +		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
    +		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
    +			throw "Invalid date"; // E.g. 31/02/00
    +		}
    +		return date;
    +	},
    +
    +	/* Standard date formats. */
    +	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
    +	COOKIE: "D, dd M yy",
    +	ISO_8601: "yy-mm-dd",
    +	RFC_822: "D, d M y",
    +	RFC_850: "DD, dd-M-y",
    +	RFC_1036: "D, d M y",
    +	RFC_1123: "D, d M yy",
    +	RFC_2822: "D, d M yy",
    +	RSS: "D, d M y", // RFC 822
    +	TICKS: "!",
    +	TIMESTAMP: "@",
    +	W3C: "yy-mm-dd", // ISO 8601
    +
    +	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
    +		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
    +
    +	/* Format a date object into a string value.
    +	 * The format can be combinations of the following:
    +	 * d  - day of month (no leading zero)
    +	 * dd - day of month (two digit)
    +	 * o  - day of year (no leading zeros)
    +	 * oo - day of year (three digit)
    +	 * D  - day name short
    +	 * DD - day name long
    +	 * m  - month of year (no leading zero)
    +	 * mm - month of year (two digit)
    +	 * M  - month name short
    +	 * MM - month name long
    +	 * y  - year (two digit)
    +	 * yy - year (four digit)
    +	 * @ - Unix timestamp (ms since 01/01/1970)
    +	 * ! - Windows ticks (100ns since 01/01/0001)
    +	 * "..." - literal text
    +	 * '' - single quote
    +	 *
    +	 * @param  format string - the desired format of the date
    +	 * @param  date Date - the date value to format
    +	 * @param  settings Object - attributes include:
    +	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
    +	 *					dayNames		string[7] - names of the days from Sunday (optional)
    +	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
    +	 *					monthNames		string[12] - names of the months (optional)
    +	 * @return  string - the date in the above format
    +	 */
    +	formatDate: function( format, date, settings ) {
    +		if ( !date ) {
    +			return "";
    +		}
    +
    +		var iFormat,
    +			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
    +			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
    +			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
    +			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
    +
    +			// Check whether a format character is doubled
    +			lookAhead = function( match ) {
    +				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
    +				if ( matches ) {
    +					iFormat++;
    +				}
    +				return matches;
    +			},
    +
    +			// Format a number, with leading zero if necessary
    +			formatNumber = function( match, value, len ) {
    +				var num = "" + value;
    +				if ( lookAhead( match ) ) {
    +					while ( num.length < len ) {
    +						num = "0" + num;
    +					}
    +				}
    +				return num;
    +			},
    +
    +			// Format a name, short or long as requested
    +			formatName = function( match, value, shortNames, longNames ) {
    +				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
    +			},
    +			output = "",
    +			literal = false;
    +
    +		if ( date ) {
    +			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
    +				if ( literal ) {
    +					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
    +						literal = false;
    +					} else {
    +						output += format.charAt( iFormat );
    +					}
    +				} else {
    +					switch ( format.charAt( iFormat ) ) {
    +						case "d":
    +							output += formatNumber( "d", date.getDate(), 2 );
    +							break;
    +						case "D":
    +							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
    +							break;
    +						case "o":
    +							output += formatNumber( "o",
    +								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
    +							break;
    +						case "m":
    +							output += formatNumber( "m", date.getMonth() + 1, 2 );
    +							break;
    +						case "M":
    +							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
    +							break;
    +						case "y":
    +							output += ( lookAhead( "y" ) ? date.getFullYear() :
    +								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
    +							break;
    +						case "@":
    +							output += date.getTime();
    +							break;
    +						case "!":
    +							output += date.getTime() * 10000 + this._ticksTo1970;
    +							break;
    +						case "'":
    +							if ( lookAhead( "'" ) ) {
    +								output += "'";
    +							} else {
    +								literal = true;
    +							}
    +							break;
    +						default:
    +							output += format.charAt( iFormat );
    +					}
    +				}
    +			}
    +		}
    +		return output;
    +	},
    +
    +	/* Extract all possible characters from the date format. */
    +	_possibleChars: function( format ) {
    +		var iFormat,
    +			chars = "",
    +			literal = false,
    +
    +			// Check whether a format character is doubled
    +			lookAhead = function( match ) {
    +				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
    +				if ( matches ) {
    +					iFormat++;
    +				}
    +				return matches;
    +			};
    +
    +		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
    +			if ( literal ) {
    +				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
    +					literal = false;
    +				} else {
    +					chars += format.charAt( iFormat );
    +				}
    +			} else {
    +				switch ( format.charAt( iFormat ) ) {
    +					case "d": case "m": case "y": case "@":
    +						chars += "0123456789";
    +						break;
    +					case "D": case "M":
    +						return null; // Accept anything
    +					case "'":
    +						if ( lookAhead( "'" ) ) {
    +							chars += "'";
    +						} else {
    +							literal = true;
    +						}
    +						break;
    +					default:
    +						chars += format.charAt( iFormat );
    +				}
    +			}
    +		}
    +		return chars;
    +	},
    +
    +	/* Get a setting value, defaulting if necessary. */
    +	_get: function( inst, name ) {
    +		return inst.settings[ name ] !== undefined ?
    +			inst.settings[ name ] : this._defaults[ name ];
    +	},
    +
    +	/* Parse existing date and initialise date picker. */
    +	_setDateFromField: function( inst, noDefault ) {
    +		if ( inst.input.val() === inst.lastVal ) {
    +			return;
    +		}
    +
    +		var dateFormat = this._get( inst, "dateFormat" ),
    +			dates = inst.lastVal = inst.input ? inst.input.val() : null,
    +			defaultDate = this._getDefaultDate( inst ),
    +			date = defaultDate,
    +			settings = this._getFormatConfig( inst );
    +
    +		try {
    +			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
    +		} catch ( event ) {
    +			dates = ( noDefault ? "" : dates );
    +		}
    +		inst.selectedDay = date.getDate();
    +		inst.drawMonth = inst.selectedMonth = date.getMonth();
    +		inst.drawYear = inst.selectedYear = date.getFullYear();
    +		inst.currentDay = ( dates ? date.getDate() : 0 );
    +		inst.currentMonth = ( dates ? date.getMonth() : 0 );
    +		inst.currentYear = ( dates ? date.getFullYear() : 0 );
    +		this._adjustInstDate( inst );
    +	},
    +
    +	/* Retrieve the default date shown on opening. */
    +	_getDefaultDate: function( inst ) {
    +		return this._restrictMinMax( inst,
    +			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
    +	},
    +
    +	/* A date may be specified as an exact value or a relative one. */
    +	_determineDate: function( inst, date, defaultDate ) {
    +		var offsetNumeric = function( offset ) {
    +				var date = new Date();
    +				date.setDate( date.getDate() + offset );
    +				return date;
    +			},
    +			offsetString = function( offset ) {
    +				try {
    +					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
    +						offset, $.datepicker._getFormatConfig( inst ) );
    +				}
    +				catch ( e ) {
    +
    +					// Ignore
    +				}
    +
    +				var date = ( offset.toLowerCase().match( /^c/ ) ?
    +					$.datepicker._getDate( inst ) : null ) || new Date(),
    +					year = date.getFullYear(),
    +					month = date.getMonth(),
    +					day = date.getDate(),
    +					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
    +					matches = pattern.exec( offset );
    +
    +				while ( matches ) {
    +					switch ( matches[ 2 ] || "d" ) {
    +						case "d" : case "D" :
    +							day += parseInt( matches[ 1 ], 10 ); break;
    +						case "w" : case "W" :
    +							day += parseInt( matches[ 1 ], 10 ) * 7; break;
    +						case "m" : case "M" :
    +							month += parseInt( matches[ 1 ], 10 );
    +							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
    +							break;
    +						case "y": case "Y" :
    +							year += parseInt( matches[ 1 ], 10 );
    +							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
    +							break;
    +					}
    +					matches = pattern.exec( offset );
    +				}
    +				return new Date( year, month, day );
    +			},
    +			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
    +				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
    +
    +		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
    +		if ( newDate ) {
    +			newDate.setHours( 0 );
    +			newDate.setMinutes( 0 );
    +			newDate.setSeconds( 0 );
    +			newDate.setMilliseconds( 0 );
    +		}
    +		return this._daylightSavingAdjust( newDate );
    +	},
    +
    +	/* Handle switch to/from daylight saving.
    +	 * Hours may be non-zero on daylight saving cut-over:
    +	 * > 12 when midnight changeover, but then cannot generate
    +	 * midnight datetime, so jump to 1AM, otherwise reset.
    +	 * @param  date  (Date) the date to check
    +	 * @return  (Date) the corrected date
    +	 */
    +	_daylightSavingAdjust: function( date ) {
    +		if ( !date ) {
    +			return null;
    +		}
    +		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
    +		return date;
    +	},
    +
    +	/* Set the date(s) directly. */
    +	_setDate: function( inst, date, noChange ) {
    +		var clear = !date,
    +			origMonth = inst.selectedMonth,
    +			origYear = inst.selectedYear,
    +			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
    +
    +		inst.selectedDay = inst.currentDay = newDate.getDate();
    +		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
    +		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
    +		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
    +			this._notifyChange( inst );
    +		}
    +		this._adjustInstDate( inst );
    +		if ( inst.input ) {
    +			inst.input.val( clear ? "" : this._formatDate( inst ) );
    +		}
    +	},
    +
    +	/* Retrieve the date(s) directly. */
    +	_getDate: function( inst ) {
    +		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
    +			this._daylightSavingAdjust( new Date(
    +			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
    +			return startDate;
    +	},
    +
    +	/* Attach the onxxx handlers.  These are declared statically so
    +	 * they work with static code transformers like Caja.
    +	 */
    +	_attachHandlers: function( inst ) {
    +		var stepMonths = this._get( inst, "stepMonths" ),
    +			id = "#" + inst.id.replace( /\\\\/g, "\\" );
    +		inst.dpDiv.find( "[data-handler]" ).map( function() {
    +			var handler = {
    +				prev: function() {
    +					$.datepicker._adjustDate( id, -stepMonths, "M" );
    +				},
    +				next: function() {
    +					$.datepicker._adjustDate( id, +stepMonths, "M" );
    +				},
    +				hide: function() {
    +					$.datepicker._hideDatepicker();
    +				},
    +				today: function() {
    +					$.datepicker._gotoToday( id );
    +				},
    +				selectDay: function() {
    +					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
    +					return false;
    +				},
    +				selectMonth: function() {
    +					$.datepicker._selectMonthYear( id, this, "M" );
    +					return false;
    +				},
    +				selectYear: function() {
    +					$.datepicker._selectMonthYear( id, this, "Y" );
    +					return false;
    +				}
    +			};
    +			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
    +		} );
    +	},
    +
    +	/* Generate the HTML for the current state of the date picker. */
    +	_generateHTML: function( inst ) {
    +		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
    +			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
    +			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
    +			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
    +			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
    +			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
    +			tempDate = new Date(),
    +			today = this._daylightSavingAdjust(
    +				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
    +			isRTL = this._get( inst, "isRTL" ),
    +			showButtonPanel = this._get( inst, "showButtonPanel" ),
    +			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
    +			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
    +			numMonths = this._getNumberOfMonths( inst ),
    +			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
    +			stepMonths = this._get( inst, "stepMonths" ),
    +			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
    +			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
    +				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
    +			minDate = this._getMinMaxDate( inst, "min" ),
    +			maxDate = this._getMinMaxDate( inst, "max" ),
    +			drawMonth = inst.drawMonth - showCurrentAtPos,
    +			drawYear = inst.drawYear;
    +
    +		if ( drawMonth < 0 ) {
    +			drawMonth += 12;
    +			drawYear--;
    +		}
    +		if ( maxDate ) {
    +			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
    +				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
    +			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
    +			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
    +				drawMonth--;
    +				if ( drawMonth < 0 ) {
    +					drawMonth = 11;
    +					drawYear--;
    +				}
    +			}
    +		}
    +		inst.drawMonth = drawMonth;
    +		inst.drawYear = drawYear;
    +
    +		prevText = this._get( inst, "prevText" );
    +		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
    +			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
    +			this._getFormatConfig( inst ) ) );
    +
    +		prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
    +			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
    +			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
    +			( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" ) );
    +
    +		nextText = this._get( inst, "nextText" );
    +		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
    +			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
    +			this._getFormatConfig( inst ) ) );
    +
    +		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
    +			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
    +			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
    +			( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" ) );
    +
    +		currentText = this._get( inst, "currentText" );
    +		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
    +		currentText = ( !navigationAsDateFormat ? currentText :
    +			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
    +
    +		controls = ( !inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
    +			this._get( inst, "closeText" ) + "</button>" : "" );
    +
    +		buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
    +			( this._isInRange( inst, gotoDate ) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
    +			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
    +
    +		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
    +		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
    +
    +		showWeek = this._get( inst, "showWeek" );
    +		dayNames = this._get( inst, "dayNames" );
    +		dayNamesMin = this._get( inst, "dayNamesMin" );
    +		monthNames = this._get( inst, "monthNames" );
    +		monthNamesShort = this._get( inst, "monthNamesShort" );
    +		beforeShowDay = this._get( inst, "beforeShowDay" );
    +		showOtherMonths = this._get( inst, "showOtherMonths" );
    +		selectOtherMonths = this._get( inst, "selectOtherMonths" );
    +		defaultDate = this._getDefaultDate( inst );
    +		html = "";
    +
    +		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
    +			group = "";
    +			this.maxRows = 4;
    +			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
    +				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
    +				cornerClass = " ui-corner-all";
    +				calender = "";
    +				if ( isMultiMonth ) {
    +					calender += "<div class='ui-datepicker-group";
    +					if ( numMonths[ 1 ] > 1 ) {
    +						switch ( col ) {
    +							case 0: calender += " ui-datepicker-group-first";
    +								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
    +							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
    +								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
    +							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
    +						}
    +					}
    +					calender += "'>";
    +				}
    +				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
    +					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
    +					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
    +					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
    +					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
    +					"</div><table class='ui-datepicker-calendar'><thead>" +
    +					"<tr>";
    +				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
    +				for ( dow = 0; dow < 7; dow++ ) { // days of the week
    +					day = ( dow + firstDay ) % 7;
    +					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
    +						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
    +				}
    +				calender += thead + "</tr></thead><tbody>";
    +				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
    +				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
    +					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
    +				}
    +				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
    +				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
    +				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
    +				this.maxRows = numRows;
    +				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
    +				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
    +					calender += "<tr>";
    +					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
    +						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
    +					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
    +						daySettings = ( beforeShowDay ?
    +							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
    +						otherMonth = ( printDate.getMonth() !== drawMonth );
    +						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
    +							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
    +						tbody += "<td class='" +
    +							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
    +							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
    +							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
    +							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
    +
    +							// or defaultDate is current printedDate and defaultDate is selectedDate
    +							" " + this._dayOverClass : "" ) + // highlight selected day
    +							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
    +							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
    +							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
    +							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
    +							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
    +							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
    +							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
    +							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
    +							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
    +							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
    +							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
    +							"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
    +						printDate.setDate( printDate.getDate() + 1 );
    +						printDate = this._daylightSavingAdjust( printDate );
    +					}
    +					calender += tbody + "</tr>";
    +				}
    +				drawMonth++;
    +				if ( drawMonth > 11 ) {
    +					drawMonth = 0;
    +					drawYear++;
    +				}
    +				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
    +							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
    +				group += calender;
    +			}
    +			html += group;
    +		}
    +		html += buttonPanel;
    +		inst._keyEvent = false;
    +		return html;
    +	},
    +
    +	/* Generate the month and year header. */
    +	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
    +			secondary, monthNames, monthNamesShort ) {
    +
    +		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
    +			changeMonth = this._get( inst, "changeMonth" ),
    +			changeYear = this._get( inst, "changeYear" ),
    +			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
    +			html = "<div class='ui-datepicker-title'>",
    +			monthHtml = "";
    +
    +		// Month selection
    +		if ( secondary || !changeMonth ) {
    +			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
    +		} else {
    +			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
    +			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
    +			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
    +			for ( month = 0; month < 12; month++ ) {
    +				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
    +					monthHtml += "<option value='" + month + "'" +
    +						( month === drawMonth ? " selected='selected'" : "" ) +
    +						">" + monthNamesShort[ month ] + "</option>";
    +				}
    +			}
    +			monthHtml += "</select>";
    +		}
    +
    +		if ( !showMonthAfterYear ) {
    +			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
    +		}
    +
    +		// Year selection
    +		if ( !inst.yearshtml ) {
    +			inst.yearshtml = "";
    +			if ( secondary || !changeYear ) {
    +				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
    +			} else {
    +
    +				// determine range of years to display
    +				years = this._get( inst, "yearRange" ).split( ":" );
    +				thisYear = new Date().getFullYear();
    +				determineYear = function( value ) {
    +					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
    +						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
    +						parseInt( value, 10 ) ) );
    +					return ( isNaN( year ) ? thisYear : year );
    +				};
    +				year = determineYear( years[ 0 ] );
    +				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
    +				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
    +				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
    +				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
    +				for ( ; year <= endYear; year++ ) {
    +					inst.yearshtml += "<option value='" + year + "'" +
    +						( year === drawYear ? " selected='selected'" : "" ) +
    +						">" + year + "</option>";
    +				}
    +				inst.yearshtml += "</select>";
    +
    +				html += inst.yearshtml;
    +				inst.yearshtml = null;
    +			}
    +		}
    +
    +		html += this._get( inst, "yearSuffix" );
    +		if ( showMonthAfterYear ) {
    +			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
    +		}
    +		html += "</div>"; // Close datepicker_header
    +		return html;
    +	},
    +
    +	/* Adjust one of the date sub-fields. */
    +	_adjustInstDate: function( inst, offset, period ) {
    +		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
    +			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
    +			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
    +			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
    +
    +		inst.selectedDay = date.getDate();
    +		inst.drawMonth = inst.selectedMonth = date.getMonth();
    +		inst.drawYear = inst.selectedYear = date.getFullYear();
    +		if ( period === "M" || period === "Y" ) {
    +			this._notifyChange( inst );
    +		}
    +	},
    +
    +	/* Ensure a date is within any min/max bounds. */
    +	_restrictMinMax: function( inst, date ) {
    +		var minDate = this._getMinMaxDate( inst, "min" ),
    +			maxDate = this._getMinMaxDate( inst, "max" ),
    +			newDate = ( minDate && date < minDate ? minDate : date );
    +		return ( maxDate && newDate > maxDate ? maxDate : newDate );
    +	},
    +
    +	/* Notify change of month/year. */
    +	_notifyChange: function( inst ) {
    +		var onChange = this._get( inst, "onChangeMonthYear" );
    +		if ( onChange ) {
    +			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
    +				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
    +		}
    +	},
    +
    +	/* Determine the number of months to show. */
    +	_getNumberOfMonths: function( inst ) {
    +		var numMonths = this._get( inst, "numberOfMonths" );
    +		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
    +	},
    +
    +	/* Determine the current maximum date - ensure no time components are set. */
    +	_getMinMaxDate: function( inst, minMax ) {
    +		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
    +	},
    +
    +	/* Find the number of days in a given month. */
    +	_getDaysInMonth: function( year, month ) {
    +		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
    +	},
    +
    +	/* Find the day of the week of the first of a month. */
    +	_getFirstDayOfMonth: function( year, month ) {
    +		return new Date( year, month, 1 ).getDay();
    +	},
    +
    +	/* Determines if we should allow a "next/prev" month display change. */
    +	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
    +		var numMonths = this._getNumberOfMonths( inst ),
    +			date = this._daylightSavingAdjust( new Date( curYear,
    +			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
    +
    +		if ( offset < 0 ) {
    +			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
    +		}
    +		return this._isInRange( inst, date );
    +	},
    +
    +	/* Is the given date in the accepted range? */
    +	_isInRange: function( inst, date ) {
    +		var yearSplit, currentYear,
    +			minDate = this._getMinMaxDate( inst, "min" ),
    +			maxDate = this._getMinMaxDate( inst, "max" ),
    +			minYear = null,
    +			maxYear = null,
    +			years = this._get( inst, "yearRange" );
    +			if ( years ) {
    +				yearSplit = years.split( ":" );
    +				currentYear = new Date().getFullYear();
    +				minYear = parseInt( yearSplit[ 0 ], 10 );
    +				maxYear = parseInt( yearSplit[ 1 ], 10 );
    +				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
    +					minYear += currentYear;
    +				}
    +				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
    +					maxYear += currentYear;
    +				}
    +			}
    +
    +		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
    +			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
    +			( !minYear || date.getFullYear() >= minYear ) &&
    +			( !maxYear || date.getFullYear() <= maxYear ) );
    +	},
    +
    +	/* Provide the configuration settings for formatting/parsing. */
    +	_getFormatConfig: function( inst ) {
    +		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
    +		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
    +			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
    +		return { shortYearCutoff: shortYearCutoff,
    +			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
    +			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
    +	},
    +
    +	/* Format the given date for display. */
    +	_formatDate: function( inst, day, month, year ) {
    +		if ( !day ) {
    +			inst.currentDay = inst.selectedDay;
    +			inst.currentMonth = inst.selectedMonth;
    +			inst.currentYear = inst.selectedYear;
    +		}
    +		var date = ( day ? ( typeof day === "object" ? day :
    +			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
    +			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
    +		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
    +	}
    +} );
    +
    +/*
    + * Bind hover events for datepicker elements.
    + * Done via delegate so the binding only occurs once in the lifetime of the parent div.
    + * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
    + */
    +function datepicker_bindHover( dpDiv ) {
    +	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
    +	return dpDiv.on( "mouseout", selector, function() {
    +			$( this ).removeClass( "ui-state-hover" );
    +			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
    +				$( this ).removeClass( "ui-datepicker-prev-hover" );
    +			}
    +			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
    +				$( this ).removeClass( "ui-datepicker-next-hover" );
    +			}
    +		} )
    +		.on( "mouseover", selector, datepicker_handleMouseover );
    +}
    +
    +function datepicker_handleMouseover() {
    +	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
    +		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
    +		$( this ).addClass( "ui-state-hover" );
    +		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
    +			$( this ).addClass( "ui-datepicker-prev-hover" );
    +		}
    +		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
    +			$( this ).addClass( "ui-datepicker-next-hover" );
    +		}
    +	}
    +}
    +
    +/* jQuery extend now ignores nulls! */
    +function datepicker_extendRemove( target, props ) {
    +	$.extend( target, props );
    +	for ( var name in props ) {
    +		if ( props[ name ] == null ) {
    +			target[ name ] = props[ name ];
    +		}
    +	}
    +	return target;
    +}
    +
    +/* Invoke the datepicker functionality.
    +   @param  options  string - a command, optionally followed by additional parameters or
    +					Object - settings for attaching new datepicker functionality
    +   @return  jQuery object */
    +$.fn.datepicker = function( options ) {
    +
    +	/* Verify an empty collection wasn't passed - Fixes #6976 */
    +	if ( !this.length ) {
    +		return this;
    +	}
    +
    +	/* Initialise the date picker. */
    +	if ( !$.datepicker.initialized ) {
    +		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
    +		$.datepicker.initialized = true;
    +	}
    +
    +	/* Append datepicker main container to body if not exist. */
    +	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
    +		$( "body" ).append( $.datepicker.dpDiv );
    +	}
    +
    +	var otherArgs = Array.prototype.slice.call( arguments, 1 );
    +	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
    +		return $.datepicker[ "_" + options + "Datepicker" ].
    +			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
    +	}
    +	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
    +		return $.datepicker[ "_" + options + "Datepicker" ].
    +			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
    +	}
    +	return this.each( function() {
    +		typeof options === "string" ?
    +			$.datepicker[ "_" + options + "Datepicker" ].
    +				apply( $.datepicker, [ this ].concat( otherArgs ) ) :
    +			$.datepicker._attachDatepicker( this, options );
    +	} );
    +};
    +
    +$.datepicker = new Datepicker(); // singleton instance
    +$.datepicker.initialized = false;
    +$.datepicker.uuid = new Date().getTime();
    +$.datepicker.version = "1.12.1";
    +
    +var widgetsDatepicker = $.datepicker;
    +
    +
    +
    +
    +// This file is deprecated
    +var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
    +
    +/*!
    + * jQuery UI Mouse 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Mouse
    +//>>group: Widgets
    +//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
    +//>>docs: http://api.jqueryui.com/mouse/
    +
    +
    +
    +var mouseHandled = false;
    +$( document ).on( "mouseup", function() {
    +	mouseHandled = false;
    +} );
    +
    +var widgetsMouse = $.widget( "ui.mouse", {
    +	version: "1.12.1",
    +	options: {
    +		cancel: "input, textarea, button, select, option",
    +		distance: 1,
    +		delay: 0
    +	},
    +	_mouseInit: function() {
    +		var that = this;
    +
    +		this.element
    +			.on( "mousedown." + this.widgetName, function( event ) {
    +				return that._mouseDown( event );
    +			} )
    +			.on( "click." + this.widgetName, function( event ) {
    +				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
    +					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
    +					event.stopImmediatePropagation();
    +					return false;
    +				}
    +			} );
    +
    +		this.started = false;
    +	},
    +
    +	// TODO: make sure destroying one instance of mouse doesn't mess with
    +	// other instances of mouse
    +	_mouseDestroy: function() {
    +		this.element.off( "." + this.widgetName );
    +		if ( this._mouseMoveDelegate ) {
    +			this.document
    +				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
    +				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
    +		}
    +	},
    +
    +	_mouseDown: function( event ) {
    +
    +		// don't let more than one widget handle mouseStart
    +		if ( mouseHandled ) {
    +			return;
    +		}
    +
    +		this._mouseMoved = false;
    +
    +		// We may have missed mouseup (out of window)
    +		( this._mouseStarted && this._mouseUp( event ) );
    +
    +		this._mouseDownEvent = event;
    +
    +		var that = this,
    +			btnIsLeft = ( event.which === 1 ),
    +
    +			// event.target.nodeName works around a bug in IE 8 with
    +			// disabled inputs (#7620)
    +			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
    +				$( event.target ).closest( this.options.cancel ).length : false );
    +		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
    +			return true;
    +		}
    +
    +		this.mouseDelayMet = !this.options.delay;
    +		if ( !this.mouseDelayMet ) {
    +			this._mouseDelayTimer = setTimeout( function() {
    +				that.mouseDelayMet = true;
    +			}, this.options.delay );
    +		}
    +
    +		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
    +			this._mouseStarted = ( this._mouseStart( event ) !== false );
    +			if ( !this._mouseStarted ) {
    +				event.preventDefault();
    +				return true;
    +			}
    +		}
    +
    +		// Click event may never have fired (Gecko & Opera)
    +		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
    +			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
    +		}
    +
    +		// These delegates are required to keep context
    +		this._mouseMoveDelegate = function( event ) {
    +			return that._mouseMove( event );
    +		};
    +		this._mouseUpDelegate = function( event ) {
    +			return that._mouseUp( event );
    +		};
    +
    +		this.document
    +			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
    +			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
    +
    +		event.preventDefault();
    +
    +		mouseHandled = true;
    +		return true;
    +	},
    +
    +	_mouseMove: function( event ) {
    +
    +		// Only check for mouseups outside the document if you've moved inside the document
    +		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
    +		// fire a mousemove event if content is placed under the cursor. See #7778
    +		// Support: IE <9
    +		if ( this._mouseMoved ) {
    +
    +			// IE mouseup check - mouseup happened when mouse was out of window
    +			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
    +					!event.button ) {
    +				return this._mouseUp( event );
    +
    +			// Iframe mouseup check - mouseup occurred in another document
    +			} else if ( !event.which ) {
    +
    +				// Support: Safari <=8 - 9
    +				// Safari sets which to 0 if you press any of the following keys
    +				// during a drag (#14461)
    +				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
    +						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
    +					this.ignoreMissingWhich = true;
    +				} else if ( !this.ignoreMissingWhich ) {
    +					return this._mouseUp( event );
    +				}
    +			}
    +		}
    +
    +		if ( event.which || event.button ) {
    +			this._mouseMoved = true;
    +		}
    +
    +		if ( this._mouseStarted ) {
    +			this._mouseDrag( event );
    +			return event.preventDefault();
    +		}
    +
    +		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
    +			this._mouseStarted =
    +				( this._mouseStart( this._mouseDownEvent, event ) !== false );
    +			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
    +		}
    +
    +		return !this._mouseStarted;
    +	},
    +
    +	_mouseUp: function( event ) {
    +		this.document
    +			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
    +			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
    +
    +		if ( this._mouseStarted ) {
    +			this._mouseStarted = false;
    +
    +			if ( event.target === this._mouseDownEvent.target ) {
    +				$.data( event.target, this.widgetName + ".preventClickEvent", true );
    +			}
    +
    +			this._mouseStop( event );
    +		}
    +
    +		if ( this._mouseDelayTimer ) {
    +			clearTimeout( this._mouseDelayTimer );
    +			delete this._mouseDelayTimer;
    +		}
    +
    +		this.ignoreMissingWhich = false;
    +		mouseHandled = false;
    +		event.preventDefault();
    +	},
    +
    +	_mouseDistanceMet: function( event ) {
    +		return ( Math.max(
    +				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
    +				Math.abs( this._mouseDownEvent.pageY - event.pageY )
    +			) >= this.options.distance
    +		);
    +	},
    +
    +	_mouseDelayMet: function( /* event */ ) {
    +		return this.mouseDelayMet;
    +	},
    +
    +	// These are placeholder methods, to be overriden by extending plugin
    +	_mouseStart: function( /* event */ ) {},
    +	_mouseDrag: function( /* event */ ) {},
    +	_mouseStop: function( /* event */ ) {},
    +	_mouseCapture: function( /* event */ ) { return true; }
    +} );
    +
    +
    +
    +
    +// $.ui.plugin is deprecated. Use $.widget() extensions instead.
    +var plugin = $.ui.plugin = {
    +	add: function( module, option, set ) {
    +		var i,
    +			proto = $.ui[ module ].prototype;
    +		for ( i in set ) {
    +			proto.plugins[ i ] = proto.plugins[ i ] || [];
    +			proto.plugins[ i ].push( [ option, set[ i ] ] );
    +		}
    +	},
    +	call: function( instance, name, args, allowDisconnected ) {
    +		var i,
    +			set = instance.plugins[ name ];
    +
    +		if ( !set ) {
    +			return;
    +		}
    +
    +		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
    +				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
    +			return;
    +		}
    +
    +		for ( i = 0; i < set.length; i++ ) {
    +			if ( instance.options[ set[ i ][ 0 ] ] ) {
    +				set[ i ][ 1 ].apply( instance.element, args );
    +			}
    +		}
    +	}
    +};
    +
    +
    +
    +var safeBlur = $.ui.safeBlur = function( element ) {
    +
    +	// Support: IE9 - 10 only
    +	// If the <body> is blurred, IE will switch windows, see #9420
    +	if ( element && element.nodeName.toLowerCase() !== "body" ) {
    +		$( element ).trigger( "blur" );
    +	}
    +};
    +
    +
    +/*!
    + * jQuery UI Draggable 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Draggable
    +//>>group: Interactions
    +//>>description: Enables dragging functionality for any element.
    +//>>docs: http://api.jqueryui.com/draggable/
    +//>>demos: http://jqueryui.com/draggable/
    +//>>css.structure: ../../themes/base/draggable.css
    +
    +
    +
    +$.widget( "ui.draggable", $.ui.mouse, {
    +	version: "1.12.1",
    +	widgetEventPrefix: "drag",
    +	options: {
    +		addClasses: true,
    +		appendTo: "parent",
    +		axis: false,
    +		connectToSortable: false,
    +		containment: false,
    +		cursor: "auto",
    +		cursorAt: false,
    +		grid: false,
    +		handle: false,
    +		helper: "original",
    +		iframeFix: false,
    +		opacity: false,
    +		refreshPositions: false,
    +		revert: false,
    +		revertDuration: 500,
    +		scope: "default",
    +		scroll: true,
    +		scrollSensitivity: 20,
    +		scrollSpeed: 20,
    +		snap: false,
    +		snapMode: "both",
    +		snapTolerance: 20,
    +		stack: false,
    +		zIndex: false,
    +
    +		// Callbacks
    +		drag: null,
    +		start: null,
    +		stop: null
    +	},
    +	_create: function() {
    +
    +		if ( this.options.helper === "original" ) {
    +			this._setPositionRelative();
    +		}
    +		if ( this.options.addClasses ) {
    +			this._addClass( "ui-draggable" );
    +		}
    +		this._setHandleClassName();
    +
    +		this._mouseInit();
    +	},
    +
    +	_setOption: function( key, value ) {
    +		this._super( key, value );
    +		if ( key === "handle" ) {
    +			this._removeHandleClassName();
    +			this._setHandleClassName();
    +		}
    +	},
    +
    +	_destroy: function() {
    +		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
    +			this.destroyOnClear = true;
    +			return;
    +		}
    +		this._removeHandleClassName();
    +		this._mouseDestroy();
    +	},
    +
    +	_mouseCapture: function( event ) {
    +		var o = this.options;
    +
    +		// Among others, prevent a drag on a resizable-handle
    +		if ( this.helper || o.disabled ||
    +				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
    +			return false;
    +		}
    +
    +		//Quit if we're not on a valid handle
    +		this.handle = this._getHandle( event );
    +		if ( !this.handle ) {
    +			return false;
    +		}
    +
    +		this._blurActiveElement( event );
    +
    +		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
    +
    +		return true;
    +
    +	},
    +
    +	_blockFrames: function( selector ) {
    +		this.iframeBlocks = this.document.find( selector ).map( function() {
    +			var iframe = $( this );
    +
    +			return $( "<div>" )
    +				.css( "position", "absolute" )
    +				.appendTo( iframe.parent() )
    +				.outerWidth( iframe.outerWidth() )
    +				.outerHeight( iframe.outerHeight() )
    +				.offset( iframe.offset() )[ 0 ];
    +		} );
    +	},
    +
    +	_unblockFrames: function() {
    +		if ( this.iframeBlocks ) {
    +			this.iframeBlocks.remove();
    +			delete this.iframeBlocks;
    +		}
    +	},
    +
    +	_blurActiveElement: function( event ) {
    +		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
    +			target = $( event.target );
    +
    +		// Don't blur if the event occurred on an element that is within
    +		// the currently focused element
    +		// See #10527, #12472
    +		if ( target.closest( activeElement ).length ) {
    +			return;
    +		}
    +
    +		// Blur any element that currently has focus, see #4261
    +		$.ui.safeBlur( activeElement );
    +	},
    +
    +	_mouseStart: function( event ) {
    +
    +		var o = this.options;
    +
    +		//Create and append the visible helper
    +		this.helper = this._createHelper( event );
    +
    +		this._addClass( this.helper, "ui-draggable-dragging" );
    +
    +		//Cache the helper size
    +		this._cacheHelperProportions();
    +
    +		//If ddmanager is used for droppables, set the global draggable
    +		if ( $.ui.ddmanager ) {
    +			$.ui.ddmanager.current = this;
    +		}
    +
    +		/*
    +		 * - Position generation -
    +		 * This block generates everything position related - it's the core of draggables.
    +		 */
    +
    +		//Cache the margins of the original element
    +		this._cacheMargins();
    +
    +		//Store the helper's css position
    +		this.cssPosition = this.helper.css( "position" );
    +		this.scrollParent = this.helper.scrollParent( true );
    +		this.offsetParent = this.helper.offsetParent();
    +		this.hasFixedAncestor = this.helper.parents().filter( function() {
    +				return $( this ).css( "position" ) === "fixed";
    +			} ).length > 0;
    +
    +		//The element's absolute position on the page minus margins
    +		this.positionAbs = this.element.offset();
    +		this._refreshOffsets( event );
    +
    +		//Generate the original position
    +		this.originalPosition = this.position = this._generatePosition( event, false );
    +		this.originalPageX = event.pageX;
    +		this.originalPageY = event.pageY;
    +
    +		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
    +		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
    +
    +		//Set a containment if given in the options
    +		this._setContainment();
    +
    +		//Trigger event + callbacks
    +		if ( this._trigger( "start", event ) === false ) {
    +			this._clear();
    +			return false;
    +		}
    +
    +		//Recache the helper size
    +		this._cacheHelperProportions();
    +
    +		//Prepare the droppable offsets
    +		if ( $.ui.ddmanager && !o.dropBehaviour ) {
    +			$.ui.ddmanager.prepareOffsets( this, event );
    +		}
    +
    +		// Execute the drag once - this causes the helper not to be visible before getting its
    +		// correct position
    +		this._mouseDrag( event, true );
    +
    +		// If the ddmanager is used for droppables, inform the manager that dragging has started
    +		// (see #5003)
    +		if ( $.ui.ddmanager ) {
    +			$.ui.ddmanager.dragStart( this, event );
    +		}
    +
    +		return true;
    +	},
    +
    +	_refreshOffsets: function( event ) {
    +		this.offset = {
    +			top: this.positionAbs.top - this.margins.top,
    +			left: this.positionAbs.left - this.margins.left,
    +			scroll: false,
    +			parent: this._getParentOffset(),
    +			relative: this._getRelativeOffset()
    +		};
    +
    +		this.offset.click = {
    +			left: event.pageX - this.offset.left,
    +			top: event.pageY - this.offset.top
    +		};
    +	},
    +
    +	_mouseDrag: function( event, noPropagation ) {
    +
    +		// reset any necessary cached properties (see #5009)
    +		if ( this.hasFixedAncestor ) {
    +			this.offset.parent = this._getParentOffset();
    +		}
    +
    +		//Compute the helpers position
    +		this.position = this._generatePosition( event, true );
    +		this.positionAbs = this._convertPositionTo( "absolute" );
    +
    +		//Call plugins and callbacks and use the resulting position if something is returned
    +		if ( !noPropagation ) {
    +			var ui = this._uiHash();
    +			if ( this._trigger( "drag", event, ui ) === false ) {
    +				this._mouseUp( new $.Event( "mouseup", event ) );
    +				return false;
    +			}
    +			this.position = ui.position;
    +		}
    +
    +		this.helper[ 0 ].style.left = this.position.left + "px";
    +		this.helper[ 0 ].style.top = this.position.top + "px";
    +
    +		if ( $.ui.ddmanager ) {
    +			$.ui.ddmanager.drag( this, event );
    +		}
    +
    +		return false;
    +	},
    +
    +	_mouseStop: function( event ) {
    +
    +		//If we are using droppables, inform the manager about the drop
    +		var that = this,
    +			dropped = false;
    +		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
    +			dropped = $.ui.ddmanager.drop( this, event );
    +		}
    +
    +		//if a drop comes from outside (a sortable)
    +		if ( this.dropped ) {
    +			dropped = this.dropped;
    +			this.dropped = false;
    +		}
    +
    +		if ( ( this.options.revert === "invalid" && !dropped ) ||
    +				( this.options.revert === "valid" && dropped ) ||
    +				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
    +				this.options.revert.call( this.element, dropped ) )
    +		) {
    +			$( this.helper ).animate(
    +				this.originalPosition,
    +				parseInt( this.options.revertDuration, 10 ),
    +				function() {
    +					if ( that._trigger( "stop", event ) !== false ) {
    +						that._clear();
    +					}
    +				}
    +			);
    +		} else {
    +			if ( this._trigger( "stop", event ) !== false ) {
    +				this._clear();
    +			}
    +		}
    +
    +		return false;
    +	},
    +
    +	_mouseUp: function( event ) {
    +		this._unblockFrames();
    +
    +		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
    +		// (see #5003)
    +		if ( $.ui.ddmanager ) {
    +			$.ui.ddmanager.dragStop( this, event );
    +		}
    +
    +		// Only need to focus if the event occurred on the draggable itself, see #10527
    +		if ( this.handleElement.is( event.target ) ) {
    +
    +			// The interaction is over; whether or not the click resulted in a drag,
    +			// focus the element
    +			this.element.trigger( "focus" );
    +		}
    +
    +		return $.ui.mouse.prototype._mouseUp.call( this, event );
    +	},
    +
    +	cancel: function() {
    +
    +		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
    +			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
    +		} else {
    +			this._clear();
    +		}
    +
    +		return this;
    +
    +	},
    +
    +	_getHandle: function( event ) {
    +		return this.options.handle ?
    +			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
    +			true;
    +	},
    +
    +	_setHandleClassName: function() {
    +		this.handleElement = this.options.handle ?
    +			this.element.find( this.options.handle ) : this.element;
    +		this._addClass( this.handleElement, "ui-draggable-handle" );
    +	},
    +
    +	_removeHandleClassName: function() {
    +		this._removeClass( this.handleElement, "ui-draggable-handle" );
    +	},
    +
    +	_createHelper: function( event ) {
    +
    +		var o = this.options,
    +			helperIsFunction = $.isFunction( o.helper ),
    +			helper = helperIsFunction ?
    +				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
    +				( o.helper === "clone" ?
    +					this.element.clone().removeAttr( "id" ) :
    +					this.element );
    +
    +		if ( !helper.parents( "body" ).length ) {
    +			helper.appendTo( ( o.appendTo === "parent" ?
    +				this.element[ 0 ].parentNode :
    +				o.appendTo ) );
    +		}
    +
    +		// Http://bugs.jqueryui.com/ticket/9446
    +		// a helper function can return the original element
    +		// which wouldn't have been set to relative in _create
    +		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
    +			this._setPositionRelative();
    +		}
    +
    +		if ( helper[ 0 ] !== this.element[ 0 ] &&
    +				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
    +			helper.css( "position", "absolute" );
    +		}
    +
    +		return helper;
    +
    +	},
    +
    +	_setPositionRelative: function() {
    +		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
    +			this.element[ 0 ].style.position = "relative";
    +		}
    +	},
    +
    +	_adjustOffsetFromHelper: function( obj ) {
    +		if ( typeof obj === "string" ) {
    +			obj = obj.split( " " );
    +		}
    +		if ( $.isArray( obj ) ) {
    +			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
    +		}
    +		if ( "left" in obj ) {
    +			this.offset.click.left = obj.left + this.margins.left;
    +		}
    +		if ( "right" in obj ) {
    +			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
    +		}
    +		if ( "top" in obj ) {
    +			this.offset.click.top = obj.top + this.margins.top;
    +		}
    +		if ( "bottom" in obj ) {
    +			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
    +		}
    +	},
    +
    +	_isRootNode: function( element ) {
    +		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
    +	},
    +
    +	_getParentOffset: function() {
    +
    +		//Get the offsetParent and cache its position
    +		var po = this.offsetParent.offset(),
    +			document = this.document[ 0 ];
    +
    +		// This is a special case where we need to modify a offset calculated on start, since the
    +		// following happened:
    +		// 1. The position of the helper is absolute, so it's position is calculated based on the
    +		// next positioned parent
    +		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
    +		// the document, which means that the scroll is included in the initial calculation of the
    +		// offset of the parent, and never recalculated upon drag
    +		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
    +				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
    +			po.left += this.scrollParent.scrollLeft();
    +			po.top += this.scrollParent.scrollTop();
    +		}
    +
    +		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
    +			po = { top: 0, left: 0 };
    +		}
    +
    +		return {
    +			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
    +			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
    +		};
    +
    +	},
    +
    +	_getRelativeOffset: function() {
    +		if ( this.cssPosition !== "relative" ) {
    +			return { top: 0, left: 0 };
    +		}
    +
    +		var p = this.element.position(),
    +			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
    +
    +		return {
    +			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
    +				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
    +			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
    +				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
    +		};
    +
    +	},
    +
    +	_cacheMargins: function() {
    +		this.margins = {
    +			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
    +			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
    +			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
    +			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
    +		};
    +	},
    +
    +	_cacheHelperProportions: function() {
    +		this.helperProportions = {
    +			width: this.helper.outerWidth(),
    +			height: this.helper.outerHeight()
    +		};
    +	},
    +
    +	_setContainment: function() {
    +
    +		var isUserScrollable, c, ce,
    +			o = this.options,
    +			document = this.document[ 0 ];
    +
    +		this.relativeContainer = null;
    +
    +		if ( !o.containment ) {
    +			this.containment = null;
    +			return;
    +		}
    +
    +		if ( o.containment === "window" ) {
    +			this.containment = [
    +				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
    +				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
    +				$( window ).scrollLeft() + $( window ).width() -
    +					this.helperProportions.width - this.margins.left,
    +				$( window ).scrollTop() +
    +					( $( window ).height() || document.body.parentNode.scrollHeight ) -
    +					this.helperProportions.height - this.margins.top
    +			];
    +			return;
    +		}
    +
    +		if ( o.containment === "document" ) {
    +			this.containment = [
    +				0,
    +				0,
    +				$( document ).width() - this.helperProportions.width - this.margins.left,
    +				( $( document ).height() || document.body.parentNode.scrollHeight ) -
    +					this.helperProportions.height - this.margins.top
    +			];
    +			return;
    +		}
    +
    +		if ( o.containment.constructor === Array ) {
    +			this.containment = o.containment;
    +			return;
    +		}
    +
    +		if ( o.containment === "parent" ) {
    +			o.containment = this.helper[ 0 ].parentNode;
    +		}
    +
    +		c = $( o.containment );
    +		ce = c[ 0 ];
    +
    +		if ( !ce ) {
    +			return;
    +		}
    +
    +		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
    +
    +		this.containment = [
    +			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
    +				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
    +			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
    +				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
    +			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
    +				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
    +				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
    +				this.helperProportions.width -
    +				this.margins.left -
    +				this.margins.right,
    +			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
    +				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
    +				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
    +				this.helperProportions.height -
    +				this.margins.top -
    +				this.margins.bottom
    +		];
    +		this.relativeContainer = c;
    +	},
    +
    +	_convertPositionTo: function( d, pos ) {
    +
    +		if ( !pos ) {
    +			pos = this.position;
    +		}
    +
    +		var mod = d === "absolute" ? 1 : -1,
    +			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
    +
    +		return {
    +			top: (
    +
    +				// The absolute mouse position
    +				pos.top	+
    +
    +				// Only for relative positioned nodes: Relative offset from element to offset parent
    +				this.offset.relative.top * mod +
    +
    +				// The offsetParent's offset without borders (offset + border)
    +				this.offset.parent.top * mod -
    +				( ( this.cssPosition === "fixed" ?
    +					-this.offset.scroll.top :
    +					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
    +			),
    +			left: (
    +
    +				// The absolute mouse position
    +				pos.left +
    +
    +				// Only for relative positioned nodes: Relative offset from element to offset parent
    +				this.offset.relative.left * mod +
    +
    +				// The offsetParent's offset without borders (offset + border)
    +				this.offset.parent.left * mod	-
    +				( ( this.cssPosition === "fixed" ?
    +					-this.offset.scroll.left :
    +					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
    +			)
    +		};
    +
    +	},
    +
    +	_generatePosition: function( event, constrainPosition ) {
    +
    +		var containment, co, top, left,
    +			o = this.options,
    +			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
    +			pageX = event.pageX,
    +			pageY = event.pageY;
    +
    +		// Cache the scroll
    +		if ( !scrollIsRootNode || !this.offset.scroll ) {
    +			this.offset.scroll = {
    +				top: this.scrollParent.scrollTop(),
    +				left: this.scrollParent.scrollLeft()
    +			};
    +		}
    +
    +		/*
    +		 * - Position constraining -
    +		 * Constrain the position to a mix of grid, containment.
    +		 */
    +
    +		// If we are not dragging yet, we won't check for options
    +		if ( constrainPosition ) {
    +			if ( this.containment ) {
    +				if ( this.relativeContainer ) {
    +					co = this.relativeContainer.offset();
    +					containment = [
    +						this.containment[ 0 ] + co.left,
    +						this.containment[ 1 ] + co.top,
    +						this.containment[ 2 ] + co.left,
    +						this.containment[ 3 ] + co.top
    +					];
    +				} else {
    +					containment = this.containment;
    +				}
    +
    +				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
    +					pageX = containment[ 0 ] + this.offset.click.left;
    +				}
    +				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
    +					pageY = containment[ 1 ] + this.offset.click.top;
    +				}
    +				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
    +					pageX = containment[ 2 ] + this.offset.click.left;
    +				}
    +				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
    +					pageY = containment[ 3 ] + this.offset.click.top;
    +				}
    +			}
    +
    +			if ( o.grid ) {
    +
    +				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
    +				// argument errors in IE (see ticket #6950)
    +				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
    +					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
    +				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
    +					top - this.offset.click.top > containment[ 3 ] ) ?
    +						top :
    +						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
    +							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
    +
    +				left = o.grid[ 0 ] ? this.originalPageX +
    +					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
    +					this.originalPageX;
    +				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
    +					left - this.offset.click.left > containment[ 2 ] ) ?
    +						left :
    +						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
    +							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
    +			}
    +
    +			if ( o.axis === "y" ) {
    +				pageX = this.originalPageX;
    +			}
    +
    +			if ( o.axis === "x" ) {
    +				pageY = this.originalPageY;
    +			}
    +		}
    +
    +		return {
    +			top: (
    +
    +				// The absolute mouse position
    +				pageY -
    +
    +				// Click offset (relative to the element)
    +				this.offset.click.top -
    +
    +				// Only for relative positioned nodes: Relative offset from element to offset parent
    +				this.offset.relative.top -
    +
    +				// The offsetParent's offset without borders (offset + border)
    +				this.offset.parent.top +
    +				( this.cssPosition === "fixed" ?
    +					-this.offset.scroll.top :
    +					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
    +			),
    +			left: (
    +
    +				// The absolute mouse position
    +				pageX -
    +
    +				// Click offset (relative to the element)
    +				this.offset.click.left -
    +
    +				// Only for relative positioned nodes: Relative offset from element to offset parent
    +				this.offset.relative.left -
    +
    +				// The offsetParent's offset without borders (offset + border)
    +				this.offset.parent.left +
    +				( this.cssPosition === "fixed" ?
    +					-this.offset.scroll.left :
    +					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
    +			)
    +		};
    +
    +	},
    +
    +	_clear: function() {
    +		this._removeClass( this.helper, "ui-draggable-dragging" );
    +		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
    +			this.helper.remove();
    +		}
    +		this.helper = null;
    +		this.cancelHelperRemoval = false;
    +		if ( this.destroyOnClear ) {
    +			this.destroy();
    +		}
    +	},
    +
    +	// From now on bulk stuff - mainly helpers
    +
    +	_trigger: function( type, event, ui ) {
    +		ui = ui || this._uiHash();
    +		$.ui.plugin.call( this, type, [ event, ui, this ], true );
    +
    +		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
    +		if ( /^(drag|start|stop)/.test( type ) ) {
    +			this.positionAbs = this._convertPositionTo( "absolute" );
    +			ui.offset = this.positionAbs;
    +		}
    +		return $.Widget.prototype._trigger.call( this, type, event, ui );
    +	},
    +
    +	plugins: {},
    +
    +	_uiHash: function() {
    +		return {
    +			helper: this.helper,
    +			position: this.position,
    +			originalPosition: this.originalPosition,
    +			offset: this.positionAbs
    +		};
    +	}
    +
    +} );
    +
    +$.ui.plugin.add( "draggable", "connectToSortable", {
    +	start: function( event, ui, draggable ) {
    +		var uiSortable = $.extend( {}, ui, {
    +			item: draggable.element
    +		} );
    +
    +		draggable.sortables = [];
    +		$( draggable.options.connectToSortable ).each( function() {
    +			var sortable = $( this ).sortable( "instance" );
    +
    +			if ( sortable && !sortable.options.disabled ) {
    +				draggable.sortables.push( sortable );
    +
    +				// RefreshPositions is called at drag start to refresh the containerCache
    +				// which is used in drag. This ensures it's initialized and synchronized
    +				// with any changes that might have happened on the page since initialization.
    +				sortable.refreshPositions();
    +				sortable._trigger( "activate", event, uiSortable );
    +			}
    +		} );
    +	},
    +	stop: function( event, ui, draggable ) {
    +		var uiSortable = $.extend( {}, ui, {
    +			item: draggable.element
    +		} );
    +
    +		draggable.cancelHelperRemoval = false;
    +
    +		$.each( draggable.sortables, function() {
    +			var sortable = this;
    +
    +			if ( sortable.isOver ) {
    +				sortable.isOver = 0;
    +
    +				// Allow this sortable to handle removing the helper
    +				draggable.cancelHelperRemoval = true;
    +				sortable.cancelHelperRemoval = false;
    +
    +				// Use _storedCSS To restore properties in the sortable,
    +				// as this also handles revert (#9675) since the draggable
    +				// may have modified them in unexpected ways (#8809)
    +				sortable._storedCSS = {
    +					position: sortable.placeholder.css( "position" ),
    +					top: sortable.placeholder.css( "top" ),
    +					left: sortable.placeholder.css( "left" )
    +				};
    +
    +				sortable._mouseStop( event );
    +
    +				// Once drag has ended, the sortable should return to using
    +				// its original helper, not the shared helper from draggable
    +				sortable.options.helper = sortable.options._helper;
    +			} else {
    +
    +				// Prevent this Sortable from removing the helper.
    +				// However, don't set the draggable to remove the helper
    +				// either as another connected Sortable may yet handle the removal.
    +				sortable.cancelHelperRemoval = true;
    +
    +				sortable._trigger( "deactivate", event, uiSortable );
    +			}
    +		} );
    +	},
    +	drag: function( event, ui, draggable ) {
    +		$.each( draggable.sortables, function() {
    +			var innermostIntersecting = false,
    +				sortable = this;
    +
    +			// Copy over variables that sortable's _intersectsWith uses
    +			sortable.positionAbs = draggable.positionAbs;
    +			sortable.helperProportions = draggable.helperProportions;
    +			sortable.offset.click = draggable.offset.click;
    +
    +			if ( sortable._intersectsWith( sortable.containerCache ) ) {
    +				innermostIntersecting = true;
    +
    +				$.each( draggable.sortables, function() {
    +
    +					// Copy over variables that sortable's _intersectsWith uses
    +					this.positionAbs = draggable.positionAbs;
    +					this.helperProportions = draggable.helperProportions;
    +					this.offset.click = draggable.offset.click;
    +
    +					if ( this !== sortable &&
    +							this._intersectsWith( this.containerCache ) &&
    +							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
    +						innermostIntersecting = false;
    +					}
    +
    +					return innermostIntersecting;
    +				} );
    +			}
    +
    +			if ( innermostIntersecting ) {
    +
    +				// If it intersects, we use a little isOver variable and set it once,
    +				// so that the move-in stuff gets fired only once.
    +				if ( !sortable.isOver ) {
    +					sortable.isOver = 1;
    +
    +					// Store draggable's parent in case we need to reappend to it later.
    +					draggable._parent = ui.helper.parent();
    +
    +					sortable.currentItem = ui.helper
    +						.appendTo( sortable.element )
    +						.data( "ui-sortable-item", true );
    +
    +					// Store helper option to later restore it
    +					sortable.options._helper = sortable.options.helper;
    +
    +					sortable.options.helper = function() {
    +						return ui.helper[ 0 ];
    +					};
    +
    +					// Fire the start events of the sortable with our passed browser event,
    +					// and our own helper (so it doesn't create a new one)
    +					event.target = sortable.currentItem[ 0 ];
    +					sortable._mouseCapture( event, true );
    +					sortable._mouseStart( event, true, true );
    +
    +					// Because the browser event is way off the new appended portlet,
    +					// modify necessary variables to reflect the changes
    +					sortable.offset.click.top = draggable.offset.click.top;
    +					sortable.offset.click.left = draggable.offset.click.left;
    +					sortable.offset.parent.left -= draggable.offset.parent.left -
    +						sortable.offset.parent.left;
    +					sortable.offset.parent.top -= draggable.offset.parent.top -
    +						sortable.offset.parent.top;
    +
    +					draggable._trigger( "toSortable", event );
    +
    +					// Inform draggable that the helper is in a valid drop zone,
    +					// used solely in the revert option to handle "valid/invalid".
    +					draggable.dropped = sortable.element;
    +
    +					// Need to refreshPositions of all sortables in the case that
    +					// adding to one sortable changes the location of the other sortables (#9675)
    +					$.each( draggable.sortables, function() {
    +						this.refreshPositions();
    +					} );
    +
    +					// Hack so receive/update callbacks work (mostly)
    +					draggable.currentItem = draggable.element;
    +					sortable.fromOutside = draggable;
    +				}
    +
    +				if ( sortable.currentItem ) {
    +					sortable._mouseDrag( event );
    +
    +					// Copy the sortable's position because the draggable's can potentially reflect
    +					// a relative position, while sortable is always absolute, which the dragged
    +					// element has now become. (#8809)
    +					ui.position = sortable.position;
    +				}
    +			} else {
    +
    +				// If it doesn't intersect with the sortable, and it intersected before,
    +				// we fake the drag stop of the sortable, but make sure it doesn't remove
    +				// the helper by using cancelHelperRemoval.
    +				if ( sortable.isOver ) {
    +
    +					sortable.isOver = 0;
    +					sortable.cancelHelperRemoval = true;
    +
    +					// Calling sortable's mouseStop would trigger a revert,
    +					// so revert must be temporarily false until after mouseStop is called.
    +					sortable.options._revert = sortable.options.revert;
    +					sortable.options.revert = false;
    +
    +					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
    +					sortable._mouseStop( event, true );
    +
    +					// Restore sortable behaviors that were modfied
    +					// when the draggable entered the sortable area (#9481)
    +					sortable.options.revert = sortable.options._revert;
    +					sortable.options.helper = sortable.options._helper;
    +
    +					if ( sortable.placeholder ) {
    +						sortable.placeholder.remove();
    +					}
    +
    +					// Restore and recalculate the draggable's offset considering the sortable
    +					// may have modified them in unexpected ways. (#8809, #10669)
    +					ui.helper.appendTo( draggable._parent );
    +					draggable._refreshOffsets( event );
    +					ui.position = draggable._generatePosition( event, true );
    +
    +					draggable._trigger( "fromSortable", event );
    +
    +					// Inform draggable that the helper is no longer in a valid drop zone
    +					draggable.dropped = false;
    +
    +					// Need to refreshPositions of all sortables just in case removing
    +					// from one sortable changes the location of other sortables (#9675)
    +					$.each( draggable.sortables, function() {
    +						this.refreshPositions();
    +					} );
    +				}
    +			}
    +		} );
    +	}
    +} );
    +
    +$.ui.plugin.add( "draggable", "cursor", {
    +	start: function( event, ui, instance ) {
    +		var t = $( "body" ),
    +			o = instance.options;
    +
    +		if ( t.css( "cursor" ) ) {
    +			o._cursor = t.css( "cursor" );
    +		}
    +		t.css( "cursor", o.cursor );
    +	},
    +	stop: function( event, ui, instance ) {
    +		var o = instance.options;
    +		if ( o._cursor ) {
    +			$( "body" ).css( "cursor", o._cursor );
    +		}
    +	}
    +} );
    +
    +$.ui.plugin.add( "draggable", "opacity", {
    +	start: function( event, ui, instance ) {
    +		var t = $( ui.helper ),
    +			o = instance.options;
    +		if ( t.css( "opacity" ) ) {
    +			o._opacity = t.css( "opacity" );
    +		}
    +		t.css( "opacity", o.opacity );
    +	},
    +	stop: function( event, ui, instance ) {
    +		var o = instance.options;
    +		if ( o._opacity ) {
    +			$( ui.helper ).css( "opacity", o._opacity );
    +		}
    +	}
    +} );
    +
    +$.ui.plugin.add( "draggable", "scroll", {
    +	start: function( event, ui, i ) {
    +		if ( !i.scrollParentNotHidden ) {
    +			i.scrollParentNotHidden = i.helper.scrollParent( false );
    +		}
    +
    +		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
    +				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
    +			i.overflowOffset = i.scrollParentNotHidden.offset();
    +		}
    +	},
    +	drag: function( event, ui, i  ) {
    +
    +		var o = i.options,
    +			scrolled = false,
    +			scrollParent = i.scrollParentNotHidden[ 0 ],
    +			document = i.document[ 0 ];
    +
    +		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
    +			if ( !o.axis || o.axis !== "x" ) {
    +				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
    +						o.scrollSensitivity ) {
    +					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
    +				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
    +					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
    +				}
    +			}
    +
    +			if ( !o.axis || o.axis !== "y" ) {
    +				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
    +						o.scrollSensitivity ) {
    +					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
    +				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
    +					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
    +				}
    +			}
    +
    +		} else {
    +
    +			if ( !o.axis || o.axis !== "x" ) {
    +				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
    +					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
    +				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
    +						o.scrollSensitivity ) {
    +					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
    +				}
    +			}
    +
    +			if ( !o.axis || o.axis !== "y" ) {
    +				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
    +					scrolled = $( document ).scrollLeft(
    +						$( document ).scrollLeft() - o.scrollSpeed
    +					);
    +				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
    +						o.scrollSensitivity ) {
    +					scrolled = $( document ).scrollLeft(
    +						$( document ).scrollLeft() + o.scrollSpeed
    +					);
    +				}
    +			}
    +
    +		}
    +
    +		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
    +			$.ui.ddmanager.prepareOffsets( i, event );
    +		}
    +
    +	}
    +} );
    +
    +$.ui.plugin.add( "draggable", "snap", {
    +	start: function( event, ui, i ) {
    +
    +		var o = i.options;
    +
    +		i.snapElements = [];
    +
    +		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
    +			.each( function() {
    +				var $t = $( this ),
    +					$o = $t.offset();
    +				if ( this !== i.element[ 0 ] ) {
    +					i.snapElements.push( {
    +						item: this,
    +						width: $t.outerWidth(), height: $t.outerHeight(),
    +						top: $o.top, left: $o.left
    +					} );
    +				}
    +			} );
    +
    +	},
    +	drag: function( event, ui, inst ) {
    +
    +		var ts, bs, ls, rs, l, r, t, b, i, first,
    +			o = inst.options,
    +			d = o.snapTolerance,
    +			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
    +			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
    +
    +		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
    +
    +			l = inst.snapElements[ i ].left - inst.margins.left;
    +			r = l + inst.snapElements[ i ].width;
    +			t = inst.snapElements[ i ].top - inst.margins.top;
    +			b = t + inst.snapElements[ i ].height;
    +
    +			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
    +					!$.contains( inst.snapElements[ i ].item.ownerDocument,
    +					inst.snapElements[ i ].item ) ) {
    +				if ( inst.snapElements[ i ].snapping ) {
    +					( inst.options.snap.release &&
    +						inst.options.snap.release.call(
    +							inst.element,
    +							event,
    +							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
    +						) );
    +				}
    +				inst.snapElements[ i ].snapping = false;
    +				continue;
    +			}
    +
    +			if ( o.snapMode !== "inner" ) {
    +				ts = Math.abs( t - y2 ) <= d;
    +				bs = Math.abs( b - y1 ) <= d;
    +				ls = Math.abs( l - x2 ) <= d;
    +				rs = Math.abs( r - x1 ) <= d;
    +				if ( ts ) {
    +					ui.position.top = inst._convertPositionTo( "relative", {
    +						top: t - inst.helperProportions.height,
    +						left: 0
    +					} ).top;
    +				}
    +				if ( bs ) {
    +					ui.position.top = inst._convertPositionTo( "relative", {
    +						top: b,
    +						left: 0
    +					} ).top;
    +				}
    +				if ( ls ) {
    +					ui.position.left = inst._convertPositionTo( "relative", {
    +						top: 0,
    +						left: l - inst.helperProportions.width
    +					} ).left;
    +				}
    +				if ( rs ) {
    +					ui.position.left = inst._convertPositionTo( "relative", {
    +						top: 0,
    +						left: r
    +					} ).left;
    +				}
    +			}
    +
    +			first = ( ts || bs || ls || rs );
    +
    +			if ( o.snapMode !== "outer" ) {
    +				ts = Math.abs( t - y1 ) <= d;
    +				bs = Math.abs( b - y2 ) <= d;
    +				ls = Math.abs( l - x1 ) <= d;
    +				rs = Math.abs( r - x2 ) <= d;
    +				if ( ts ) {
    +					ui.position.top = inst._convertPositionTo( "relative", {
    +						top: t,
    +						left: 0
    +					} ).top;
    +				}
    +				if ( bs ) {
    +					ui.position.top = inst._convertPositionTo( "relative", {
    +						top: b - inst.helperProportions.height,
    +						left: 0
    +					} ).top;
    +				}
    +				if ( ls ) {
    +					ui.position.left = inst._convertPositionTo( "relative", {
    +						top: 0,
    +						left: l
    +					} ).left;
    +				}
    +				if ( rs ) {
    +					ui.position.left = inst._convertPositionTo( "relative", {
    +						top: 0,
    +						left: r - inst.helperProportions.width
    +					} ).left;
    +				}
    +			}
    +
    +			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
    +				( inst.options.snap.snap &&
    +					inst.options.snap.snap.call(
    +						inst.element,
    +						event,
    +						$.extend( inst._uiHash(), {
    +							snapItem: inst.snapElements[ i ].item
    +						} ) ) );
    +			}
    +			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
    +
    +		}
    +
    +	}
    +} );
    +
    +$.ui.plugin.add( "draggable", "stack", {
    +	start: function( event, ui, instance ) {
    +		var min,
    +			o = instance.options,
    +			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
    +				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
    +					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
    +			} );
    +
    +		if ( !group.length ) { return; }
    +
    +		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
    +		$( group ).each( function( i ) {
    +			$( this ).css( "zIndex", min + i );
    +		} );
    +		this.css( "zIndex", ( min + group.length ) );
    +	}
    +} );
    +
    +$.ui.plugin.add( "draggable", "zIndex", {
    +	start: function( event, ui, instance ) {
    +		var t = $( ui.helper ),
    +			o = instance.options;
    +
    +		if ( t.css( "zIndex" ) ) {
    +			o._zIndex = t.css( "zIndex" );
    +		}
    +		t.css( "zIndex", o.zIndex );
    +	},
    +	stop: function( event, ui, instance ) {
    +		var o = instance.options;
    +
    +		if ( o._zIndex ) {
    +			$( ui.helper ).css( "zIndex", o._zIndex );
    +		}
    +	}
    +} );
    +
    +var widgetsDraggable = $.ui.draggable;
    +
    +
    +/*!
    + * jQuery UI Resizable 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Resizable
    +//>>group: Interactions
    +//>>description: Enables resize functionality for any element.
    +//>>docs: http://api.jqueryui.com/resizable/
    +//>>demos: http://jqueryui.com/resizable/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/resizable.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +$.widget( "ui.resizable", $.ui.mouse, {
    +	version: "1.12.1",
    +	widgetEventPrefix: "resize",
    +	options: {
    +		alsoResize: false,
    +		animate: false,
    +		animateDuration: "slow",
    +		animateEasing: "swing",
    +		aspectRatio: false,
    +		autoHide: false,
    +		classes: {
    +			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
    +		},
    +		containment: false,
    +		ghost: false,
    +		grid: false,
    +		handles: "e,s,se",
    +		helper: false,
    +		maxHeight: null,
    +		maxWidth: null,
    +		minHeight: 10,
    +		minWidth: 10,
    +
    +		// See #7960
    +		zIndex: 90,
    +
    +		// Callbacks
    +		resize: null,
    +		start: null,
    +		stop: null
    +	},
    +
    +	_num: function( value ) {
    +		return parseFloat( value ) || 0;
    +	},
    +
    +	_isNumber: function( value ) {
    +		return !isNaN( parseFloat( value ) );
    +	},
    +
    +	_hasScroll: function( el, a ) {
    +
    +		if ( $( el ).css( "overflow" ) === "hidden" ) {
    +			return false;
    +		}
    +
    +		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
    +			has = false;
    +
    +		if ( el[ scroll ] > 0 ) {
    +			return true;
    +		}
    +
    +		// TODO: determine which cases actually cause this to happen
    +		// if the element doesn't have the scroll set, see if it's possible to
    +		// set the scroll
    +		el[ scroll ] = 1;
    +		has = ( el[ scroll ] > 0 );
    +		el[ scroll ] = 0;
    +		return has;
    +	},
    +
    +	_create: function() {
    +
    +		var margins,
    +			o = this.options,
    +			that = this;
    +		this._addClass( "ui-resizable" );
    +
    +		$.extend( this, {
    +			_aspectRatio: !!( o.aspectRatio ),
    +			aspectRatio: o.aspectRatio,
    +			originalElement: this.element,
    +			_proportionallyResizeElements: [],
    +			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
    +		} );
    +
    +		// Wrap the element if it cannot hold child nodes
    +		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
    +
    +			this.element.wrap(
    +				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
    +					position: this.element.css( "position" ),
    +					width: this.element.outerWidth(),
    +					height: this.element.outerHeight(),
    +					top: this.element.css( "top" ),
    +					left: this.element.css( "left" )
    +				} )
    +			);
    +
    +			this.element = this.element.parent().data(
    +				"ui-resizable", this.element.resizable( "instance" )
    +			);
    +
    +			this.elementIsWrapper = true;
    +
    +			margins = {
    +				marginTop: this.originalElement.css( "marginTop" ),
    +				marginRight: this.originalElement.css( "marginRight" ),
    +				marginBottom: this.originalElement.css( "marginBottom" ),
    +				marginLeft: this.originalElement.css( "marginLeft" )
    +			};
    +
    +			this.element.css( margins );
    +			this.originalElement.css( "margin", 0 );
    +
    +			// support: Safari
    +			// Prevent Safari textarea resize
    +			this.originalResizeStyle = this.originalElement.css( "resize" );
    +			this.originalElement.css( "resize", "none" );
    +
    +			this._proportionallyResizeElements.push( this.originalElement.css( {
    +				position: "static",
    +				zoom: 1,
    +				display: "block"
    +			} ) );
    +
    +			// Support: IE9
    +			// avoid IE jump (hard set the margin)
    +			this.originalElement.css( margins );
    +
    +			this._proportionallyResize();
    +		}
    +
    +		this._setupHandles();
    +
    +		if ( o.autoHide ) {
    +			$( this.element )
    +				.on( "mouseenter", function() {
    +					if ( o.disabled ) {
    +						return;
    +					}
    +					that._removeClass( "ui-resizable-autohide" );
    +					that._handles.show();
    +				} )
    +				.on( "mouseleave", function() {
    +					if ( o.disabled ) {
    +						return;
    +					}
    +					if ( !that.resizing ) {
    +						that._addClass( "ui-resizable-autohide" );
    +						that._handles.hide();
    +					}
    +				} );
    +		}
    +
    +		this._mouseInit();
    +	},
    +
    +	_destroy: function() {
    +
    +		this._mouseDestroy();
    +
    +		var wrapper,
    +			_destroy = function( exp ) {
    +				$( exp )
    +					.removeData( "resizable" )
    +					.removeData( "ui-resizable" )
    +					.off( ".resizable" )
    +					.find( ".ui-resizable-handle" )
    +						.remove();
    +			};
    +
    +		// TODO: Unwrap at same DOM position
    +		if ( this.elementIsWrapper ) {
    +			_destroy( this.element );
    +			wrapper = this.element;
    +			this.originalElement.css( {
    +				position: wrapper.css( "position" ),
    +				width: wrapper.outerWidth(),
    +				height: wrapper.outerHeight(),
    +				top: wrapper.css( "top" ),
    +				left: wrapper.css( "left" )
    +			} ).insertAfter( wrapper );
    +			wrapper.remove();
    +		}
    +
    +		this.originalElement.css( "resize", this.originalResizeStyle );
    +		_destroy( this.originalElement );
    +
    +		return this;
    +	},
    +
    +	_setOption: function( key, value ) {
    +		this._super( key, value );
    +
    +		switch ( key ) {
    +		case "handles":
    +			this._removeHandles();
    +			this._setupHandles();
    +			break;
    +		default:
    +			break;
    +		}
    +	},
    +
    +	_setupHandles: function() {
    +		var o = this.options, handle, i, n, hname, axis, that = this;
    +		this.handles = o.handles ||
    +			( !$( ".ui-resizable-handle", this.element ).length ?
    +				"e,s,se" : {
    +					n: ".ui-resizable-n",
    +					e: ".ui-resizable-e",
    +					s: ".ui-resizable-s",
    +					w: ".ui-resizable-w",
    +					se: ".ui-resizable-se",
    +					sw: ".ui-resizable-sw",
    +					ne: ".ui-resizable-ne",
    +					nw: ".ui-resizable-nw"
    +				} );
    +
    +		this._handles = $();
    +		if ( this.handles.constructor === String ) {
    +
    +			if ( this.handles === "all" ) {
    +				this.handles = "n,e,s,w,se,sw,ne,nw";
    +			}
    +
    +			n = this.handles.split( "," );
    +			this.handles = {};
    +
    +			for ( i = 0; i < n.length; i++ ) {
    +
    +				handle = $.trim( n[ i ] );
    +				hname = "ui-resizable-" + handle;
    +				axis = $( "<div>" );
    +				this._addClass( axis, "ui-resizable-handle " + hname );
    +
    +				axis.css( { zIndex: o.zIndex } );
    +
    +				this.handles[ handle ] = ".ui-resizable-" + handle;
    +				this.element.append( axis );
    +			}
    +
    +		}
    +
    +		this._renderAxis = function( target ) {
    +
    +			var i, axis, padPos, padWrapper;
    +
    +			target = target || this.element;
    +
    +			for ( i in this.handles ) {
    +
    +				if ( this.handles[ i ].constructor === String ) {
    +					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
    +				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
    +					this.handles[ i ] = $( this.handles[ i ] );
    +					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
    +				}
    +
    +				if ( this.elementIsWrapper &&
    +						this.originalElement[ 0 ]
    +							.nodeName
    +							.match( /^(textarea|input|select|button)$/i ) ) {
    +					axis = $( this.handles[ i ], this.element );
    +
    +					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
    +						axis.outerHeight() :
    +						axis.outerWidth();
    +
    +					padPos = [ "padding",
    +						/ne|nw|n/.test( i ) ? "Top" :
    +						/se|sw|s/.test( i ) ? "Bottom" :
    +						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
    +
    +					target.css( padPos, padWrapper );
    +
    +					this._proportionallyResize();
    +				}
    +
    +				this._handles = this._handles.add( this.handles[ i ] );
    +			}
    +		};
    +
    +		// TODO: make renderAxis a prototype function
    +		this._renderAxis( this.element );
    +
    +		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
    +		this._handles.disableSelection();
    +
    +		this._handles.on( "mouseover", function() {
    +			if ( !that.resizing ) {
    +				if ( this.className ) {
    +					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
    +				}
    +				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
    +			}
    +		} );
    +
    +		if ( o.autoHide ) {
    +			this._handles.hide();
    +			this._addClass( "ui-resizable-autohide" );
    +		}
    +	},
    +
    +	_removeHandles: function() {
    +		this._handles.remove();
    +	},
    +
    +	_mouseCapture: function( event ) {
    +		var i, handle,
    +			capture = false;
    +
    +		for ( i in this.handles ) {
    +			handle = $( this.handles[ i ] )[ 0 ];
    +			if ( handle === event.target || $.contains( handle, event.target ) ) {
    +				capture = true;
    +			}
    +		}
    +
    +		return !this.options.disabled && capture;
    +	},
    +
    +	_mouseStart: function( event ) {
    +
    +		var curleft, curtop, cursor,
    +			o = this.options,
    +			el = this.element;
    +
    +		this.resizing = true;
    +
    +		this._renderProxy();
    +
    +		curleft = this._num( this.helper.css( "left" ) );
    +		curtop = this._num( this.helper.css( "top" ) );
    +
    +		if ( o.containment ) {
    +			curleft += $( o.containment ).scrollLeft() || 0;
    +			curtop += $( o.containment ).scrollTop() || 0;
    +		}
    +
    +		this.offset = this.helper.offset();
    +		this.position = { left: curleft, top: curtop };
    +
    +		this.size = this._helper ? {
    +				width: this.helper.width(),
    +				height: this.helper.height()
    +			} : {
    +				width: el.width(),
    +				height: el.height()
    +			};
    +
    +		this.originalSize = this._helper ? {
    +				width: el.outerWidth(),
    +				height: el.outerHeight()
    +			} : {
    +				width: el.width(),
    +				height: el.height()
    +			};
    +
    +		this.sizeDiff = {
    +			width: el.outerWidth() - el.width(),
    +			height: el.outerHeight() - el.height()
    +		};
    +
    +		this.originalPosition = { left: curleft, top: curtop };
    +		this.originalMousePosition = { left: event.pageX, top: event.pageY };
    +
    +		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
    +			o.aspectRatio :
    +			( ( this.originalSize.width / this.originalSize.height ) || 1 );
    +
    +		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
    +		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
    +
    +		this._addClass( "ui-resizable-resizing" );
    +		this._propagate( "start", event );
    +		return true;
    +	},
    +
    +	_mouseDrag: function( event ) {
    +
    +		var data, props,
    +			smp = this.originalMousePosition,
    +			a = this.axis,
    +			dx = ( event.pageX - smp.left ) || 0,
    +			dy = ( event.pageY - smp.top ) || 0,
    +			trigger = this._change[ a ];
    +
    +		this._updatePrevProperties();
    +
    +		if ( !trigger ) {
    +			return false;
    +		}
    +
    +		data = trigger.apply( this, [ event, dx, dy ] );
    +
    +		this._updateVirtualBoundaries( event.shiftKey );
    +		if ( this._aspectRatio || event.shiftKey ) {
    +			data = this._updateRatio( data, event );
    +		}
    +
    +		data = this._respectSize( data, event );
    +
    +		this._updateCache( data );
    +
    +		this._propagate( "resize", event );
    +
    +		props = this._applyChanges();
    +
    +		if ( !this._helper && this._proportionallyResizeElements.length ) {
    +			this._proportionallyResize();
    +		}
    +
    +		if ( !$.isEmptyObject( props ) ) {
    +			this._updatePrevProperties();
    +			this._trigger( "resize", event, this.ui() );
    +			this._applyChanges();
    +		}
    +
    +		return false;
    +	},
    +
    +	_mouseStop: function( event ) {
    +
    +		this.resizing = false;
    +		var pr, ista, soffseth, soffsetw, s, left, top,
    +			o = this.options, that = this;
    +
    +		if ( this._helper ) {
    +
    +			pr = this._proportionallyResizeElements;
    +			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
    +			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
    +			soffsetw = ista ? 0 : that.sizeDiff.width;
    +
    +			s = {
    +				width: ( that.helper.width()  - soffsetw ),
    +				height: ( that.helper.height() - soffseth )
    +			};
    +			left = ( parseFloat( that.element.css( "left" ) ) +
    +				( that.position.left - that.originalPosition.left ) ) || null;
    +			top = ( parseFloat( that.element.css( "top" ) ) +
    +				( that.position.top - that.originalPosition.top ) ) || null;
    +
    +			if ( !o.animate ) {
    +				this.element.css( $.extend( s, { top: top, left: left } ) );
    +			}
    +
    +			that.helper.height( that.size.height );
    +			that.helper.width( that.size.width );
    +
    +			if ( this._helper && !o.animate ) {
    +				this._proportionallyResize();
    +			}
    +		}
    +
    +		$( "body" ).css( "cursor", "auto" );
    +
    +		this._removeClass( "ui-resizable-resizing" );
    +
    +		this._propagate( "stop", event );
    +
    +		if ( this._helper ) {
    +			this.helper.remove();
    +		}
    +
    +		return false;
    +
    +	},
    +
    +	_updatePrevProperties: function() {
    +		this.prevPosition = {
    +			top: this.position.top,
    +			left: this.position.left
    +		};
    +		this.prevSize = {
    +			width: this.size.width,
    +			height: this.size.height
    +		};
    +	},
    +
    +	_applyChanges: function() {
    +		var props = {};
    +
    +		if ( this.position.top !== this.prevPosition.top ) {
    +			props.top = this.position.top + "px";
    +		}
    +		if ( this.position.left !== this.prevPosition.left ) {
    +			props.left = this.position.left + "px";
    +		}
    +		if ( this.size.width !== this.prevSize.width ) {
    +			props.width = this.size.width + "px";
    +		}
    +		if ( this.size.height !== this.prevSize.height ) {
    +			props.height = this.size.height + "px";
    +		}
    +
    +		this.helper.css( props );
    +
    +		return props;
    +	},
    +
    +	_updateVirtualBoundaries: function( forceAspectRatio ) {
    +		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
    +			o = this.options;
    +
    +		b = {
    +			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
    +			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
    +			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
    +			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
    +		};
    +
    +		if ( this._aspectRatio || forceAspectRatio ) {
    +			pMinWidth = b.minHeight * this.aspectRatio;
    +			pMinHeight = b.minWidth / this.aspectRatio;
    +			pMaxWidth = b.maxHeight * this.aspectRatio;
    +			pMaxHeight = b.maxWidth / this.aspectRatio;
    +
    +			if ( pMinWidth > b.minWidth ) {
    +				b.minWidth = pMinWidth;
    +			}
    +			if ( pMinHeight > b.minHeight ) {
    +				b.minHeight = pMinHeight;
    +			}
    +			if ( pMaxWidth < b.maxWidth ) {
    +				b.maxWidth = pMaxWidth;
    +			}
    +			if ( pMaxHeight < b.maxHeight ) {
    +				b.maxHeight = pMaxHeight;
    +			}
    +		}
    +		this._vBoundaries = b;
    +	},
    +
    +	_updateCache: function( data ) {
    +		this.offset = this.helper.offset();
    +		if ( this._isNumber( data.left ) ) {
    +			this.position.left = data.left;
    +		}
    +		if ( this._isNumber( data.top ) ) {
    +			this.position.top = data.top;
    +		}
    +		if ( this._isNumber( data.height ) ) {
    +			this.size.height = data.height;
    +		}
    +		if ( this._isNumber( data.width ) ) {
    +			this.size.width = data.width;
    +		}
    +	},
    +
    +	_updateRatio: function( data ) {
    +
    +		var cpos = this.position,
    +			csize = this.size,
    +			a = this.axis;
    +
    +		if ( this._isNumber( data.height ) ) {
    +			data.width = ( data.height * this.aspectRatio );
    +		} else if ( this._isNumber( data.width ) ) {
    +			data.height = ( data.width / this.aspectRatio );
    +		}
    +
    +		if ( a === "sw" ) {
    +			data.left = cpos.left + ( csize.width - data.width );
    +			data.top = null;
    +		}
    +		if ( a === "nw" ) {
    +			data.top = cpos.top + ( csize.height - data.height );
    +			data.left = cpos.left + ( csize.width - data.width );
    +		}
    +
    +		return data;
    +	},
    +
    +	_respectSize: function( data ) {
    +
    +		var o = this._vBoundaries,
    +			a = this.axis,
    +			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
    +			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
    +			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
    +			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
    +			dw = this.originalPosition.left + this.originalSize.width,
    +			dh = this.originalPosition.top + this.originalSize.height,
    +			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
    +		if ( isminw ) {
    +			data.width = o.minWidth;
    +		}
    +		if ( isminh ) {
    +			data.height = o.minHeight;
    +		}
    +		if ( ismaxw ) {
    +			data.width = o.maxWidth;
    +		}
    +		if ( ismaxh ) {
    +			data.height = o.maxHeight;
    +		}
    +
    +		if ( isminw && cw ) {
    +			data.left = dw - o.minWidth;
    +		}
    +		if ( ismaxw && cw ) {
    +			data.left = dw - o.maxWidth;
    +		}
    +		if ( isminh && ch ) {
    +			data.top = dh - o.minHeight;
    +		}
    +		if ( ismaxh && ch ) {
    +			data.top = dh - o.maxHeight;
    +		}
    +
    +		// Fixing jump error on top/left - bug #2330
    +		if ( !data.width && !data.height && !data.left && data.top ) {
    +			data.top = null;
    +		} else if ( !data.width && !data.height && !data.top && data.left ) {
    +			data.left = null;
    +		}
    +
    +		return data;
    +	},
    +
    +	_getPaddingPlusBorderDimensions: function( element ) {
    +		var i = 0,
    +			widths = [],
    +			borders = [
    +				element.css( "borderTopWidth" ),
    +				element.css( "borderRightWidth" ),
    +				element.css( "borderBottomWidth" ),
    +				element.css( "borderLeftWidth" )
    +			],
    +			paddings = [
    +				element.css( "paddingTop" ),
    +				element.css( "paddingRight" ),
    +				element.css( "paddingBottom" ),
    +				element.css( "paddingLeft" )
    +			];
    +
    +		for ( ; i < 4; i++ ) {
    +			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
    +			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
    +		}
    +
    +		return {
    +			height: widths[ 0 ] + widths[ 2 ],
    +			width: widths[ 1 ] + widths[ 3 ]
    +		};
    +	},
    +
    +	_proportionallyResize: function() {
    +
    +		if ( !this._proportionallyResizeElements.length ) {
    +			return;
    +		}
    +
    +		var prel,
    +			i = 0,
    +			element = this.helper || this.element;
    +
    +		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
    +
    +			prel = this._proportionallyResizeElements[ i ];
    +
    +			// TODO: Seems like a bug to cache this.outerDimensions
    +			// considering that we are in a loop.
    +			if ( !this.outerDimensions ) {
    +				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
    +			}
    +
    +			prel.css( {
    +				height: ( element.height() - this.outerDimensions.height ) || 0,
    +				width: ( element.width() - this.outerDimensions.width ) || 0
    +			} );
    +
    +		}
    +
    +	},
    +
    +	_renderProxy: function() {
    +
    +		var el = this.element, o = this.options;
    +		this.elementOffset = el.offset();
    +
    +		if ( this._helper ) {
    +
    +			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
    +
    +			this._addClass( this.helper, this._helper );
    +			this.helper.css( {
    +				width: this.element.outerWidth(),
    +				height: this.element.outerHeight(),
    +				position: "absolute",
    +				left: this.elementOffset.left + "px",
    +				top: this.elementOffset.top + "px",
    +				zIndex: ++o.zIndex //TODO: Don't modify option
    +			} );
    +
    +			this.helper
    +				.appendTo( "body" )
    +				.disableSelection();
    +
    +		} else {
    +			this.helper = this.element;
    +		}
    +
    +	},
    +
    +	_change: {
    +		e: function( event, dx ) {
    +			return { width: this.originalSize.width + dx };
    +		},
    +		w: function( event, dx ) {
    +			var cs = this.originalSize, sp = this.originalPosition;
    +			return { left: sp.left + dx, width: cs.width - dx };
    +		},
    +		n: function( event, dx, dy ) {
    +			var cs = this.originalSize, sp = this.originalPosition;
    +			return { top: sp.top + dy, height: cs.height - dy };
    +		},
    +		s: function( event, dx, dy ) {
    +			return { height: this.originalSize.height + dy };
    +		},
    +		se: function( event, dx, dy ) {
    +			return $.extend( this._change.s.apply( this, arguments ),
    +				this._change.e.apply( this, [ event, dx, dy ] ) );
    +		},
    +		sw: function( event, dx, dy ) {
    +			return $.extend( this._change.s.apply( this, arguments ),
    +				this._change.w.apply( this, [ event, dx, dy ] ) );
    +		},
    +		ne: function( event, dx, dy ) {
    +			return $.extend( this._change.n.apply( this, arguments ),
    +				this._change.e.apply( this, [ event, dx, dy ] ) );
    +		},
    +		nw: function( event, dx, dy ) {
    +			return $.extend( this._change.n.apply( this, arguments ),
    +				this._change.w.apply( this, [ event, dx, dy ] ) );
    +		}
    +	},
    +
    +	_propagate: function( n, event ) {
    +		$.ui.plugin.call( this, n, [ event, this.ui() ] );
    +		( n !== "resize" && this._trigger( n, event, this.ui() ) );
    +	},
    +
    +	plugins: {},
    +
    +	ui: function() {
    +		return {
    +			originalElement: this.originalElement,
    +			element: this.element,
    +			helper: this.helper,
    +			position: this.position,
    +			size: this.size,
    +			originalSize: this.originalSize,
    +			originalPosition: this.originalPosition
    +		};
    +	}
    +
    +} );
    +
    +/*
    + * Resizable Extensions
    + */
    +
    +$.ui.plugin.add( "resizable", "animate", {
    +
    +	stop: function( event ) {
    +		var that = $( this ).resizable( "instance" ),
    +			o = that.options,
    +			pr = that._proportionallyResizeElements,
    +			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
    +			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
    +			soffsetw = ista ? 0 : that.sizeDiff.width,
    +			style = {
    +				width: ( that.size.width - soffsetw ),
    +				height: ( that.size.height - soffseth )
    +			},
    +			left = ( parseFloat( that.element.css( "left" ) ) +
    +				( that.position.left - that.originalPosition.left ) ) || null,
    +			top = ( parseFloat( that.element.css( "top" ) ) +
    +				( that.position.top - that.originalPosition.top ) ) || null;
    +
    +		that.element.animate(
    +			$.extend( style, top && left ? { top: top, left: left } : {} ), {
    +				duration: o.animateDuration,
    +				easing: o.animateEasing,
    +				step: function() {
    +
    +					var data = {
    +						width: parseFloat( that.element.css( "width" ) ),
    +						height: parseFloat( that.element.css( "height" ) ),
    +						top: parseFloat( that.element.css( "top" ) ),
    +						left: parseFloat( that.element.css( "left" ) )
    +					};
    +
    +					if ( pr && pr.length ) {
    +						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
    +					}
    +
    +					// Propagating resize, and updating values for each animation step
    +					that._updateCache( data );
    +					that._propagate( "resize", event );
    +
    +				}
    +			}
    +		);
    +	}
    +
    +} );
    +
    +$.ui.plugin.add( "resizable", "containment", {
    +
    +	start: function() {
    +		var element, p, co, ch, cw, width, height,
    +			that = $( this ).resizable( "instance" ),
    +			o = that.options,
    +			el = that.element,
    +			oc = o.containment,
    +			ce = ( oc instanceof $ ) ?
    +				oc.get( 0 ) :
    +				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
    +
    +		if ( !ce ) {
    +			return;
    +		}
    +
    +		that.containerElement = $( ce );
    +
    +		if ( /document/.test( oc ) || oc === document ) {
    +			that.containerOffset = {
    +				left: 0,
    +				top: 0
    +			};
    +			that.containerPosition = {
    +				left: 0,
    +				top: 0
    +			};
    +
    +			that.parentData = {
    +				element: $( document ),
    +				left: 0,
    +				top: 0,
    +				width: $( document ).width(),
    +				height: $( document ).height() || document.body.parentNode.scrollHeight
    +			};
    +		} else {
    +			element = $( ce );
    +			p = [];
    +			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
    +				p[ i ] = that._num( element.css( "padding" + name ) );
    +			} );
    +
    +			that.containerOffset = element.offset();
    +			that.containerPosition = element.position();
    +			that.containerSize = {
    +				height: ( element.innerHeight() - p[ 3 ] ),
    +				width: ( element.innerWidth() - p[ 1 ] )
    +			};
    +
    +			co = that.containerOffset;
    +			ch = that.containerSize.height;
    +			cw = that.containerSize.width;
    +			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
    +			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
    +
    +			that.parentData = {
    +				element: ce,
    +				left: co.left,
    +				top: co.top,
    +				width: width,
    +				height: height
    +			};
    +		}
    +	},
    +
    +	resize: function( event ) {
    +		var woset, hoset, isParent, isOffsetRelative,
    +			that = $( this ).resizable( "instance" ),
    +			o = that.options,
    +			co = that.containerOffset,
    +			cp = that.position,
    +			pRatio = that._aspectRatio || event.shiftKey,
    +			cop = {
    +				top: 0,
    +				left: 0
    +			},
    +			ce = that.containerElement,
    +			continueResize = true;
    +
    +		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
    +			cop = co;
    +		}
    +
    +		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
    +			that.size.width = that.size.width +
    +				( that._helper ?
    +					( that.position.left - co.left ) :
    +					( that.position.left - cop.left ) );
    +
    +			if ( pRatio ) {
    +				that.size.height = that.size.width / that.aspectRatio;
    +				continueResize = false;
    +			}
    +			that.position.left = o.helper ? co.left : 0;
    +		}
    +
    +		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
    +			that.size.height = that.size.height +
    +				( that._helper ?
    +					( that.position.top - co.top ) :
    +					that.position.top );
    +
    +			if ( pRatio ) {
    +				that.size.width = that.size.height * that.aspectRatio;
    +				continueResize = false;
    +			}
    +			that.position.top = that._helper ? co.top : 0;
    +		}
    +
    +		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
    +		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
    +
    +		if ( isParent && isOffsetRelative ) {
    +			that.offset.left = that.parentData.left + that.position.left;
    +			that.offset.top = that.parentData.top + that.position.top;
    +		} else {
    +			that.offset.left = that.element.offset().left;
    +			that.offset.top = that.element.offset().top;
    +		}
    +
    +		woset = Math.abs( that.sizeDiff.width +
    +			( that._helper ?
    +				that.offset.left - cop.left :
    +				( that.offset.left - co.left ) ) );
    +
    +		hoset = Math.abs( that.sizeDiff.height +
    +			( that._helper ?
    +				that.offset.top - cop.top :
    +				( that.offset.top - co.top ) ) );
    +
    +		if ( woset + that.size.width >= that.parentData.width ) {
    +			that.size.width = that.parentData.width - woset;
    +			if ( pRatio ) {
    +				that.size.height = that.size.width / that.aspectRatio;
    +				continueResize = false;
    +			}
    +		}
    +
    +		if ( hoset + that.size.height >= that.parentData.height ) {
    +			that.size.height = that.parentData.height - hoset;
    +			if ( pRatio ) {
    +				that.size.width = that.size.height * that.aspectRatio;
    +				continueResize = false;
    +			}
    +		}
    +
    +		if ( !continueResize ) {
    +			that.position.left = that.prevPosition.left;
    +			that.position.top = that.prevPosition.top;
    +			that.size.width = that.prevSize.width;
    +			that.size.height = that.prevSize.height;
    +		}
    +	},
    +
    +	stop: function() {
    +		var that = $( this ).resizable( "instance" ),
    +			o = that.options,
    +			co = that.containerOffset,
    +			cop = that.containerPosition,
    +			ce = that.containerElement,
    +			helper = $( that.helper ),
    +			ho = helper.offset(),
    +			w = helper.outerWidth() - that.sizeDiff.width,
    +			h = helper.outerHeight() - that.sizeDiff.height;
    +
    +		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
    +			$( this ).css( {
    +				left: ho.left - cop.left - co.left,
    +				width: w,
    +				height: h
    +			} );
    +		}
    +
    +		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
    +			$( this ).css( {
    +				left: ho.left - cop.left - co.left,
    +				width: w,
    +				height: h
    +			} );
    +		}
    +	}
    +} );
    +
    +$.ui.plugin.add( "resizable", "alsoResize", {
    +
    +	start: function() {
    +		var that = $( this ).resizable( "instance" ),
    +			o = that.options;
    +
    +		$( o.alsoResize ).each( function() {
    +			var el = $( this );
    +			el.data( "ui-resizable-alsoresize", {
    +				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
    +				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
    +			} );
    +		} );
    +	},
    +
    +	resize: function( event, ui ) {
    +		var that = $( this ).resizable( "instance" ),
    +			o = that.options,
    +			os = that.originalSize,
    +			op = that.originalPosition,
    +			delta = {
    +				height: ( that.size.height - os.height ) || 0,
    +				width: ( that.size.width - os.width ) || 0,
    +				top: ( that.position.top - op.top ) || 0,
    +				left: ( that.position.left - op.left ) || 0
    +			};
    +
    +			$( o.alsoResize ).each( function() {
    +				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
    +					css = el.parents( ui.originalElement[ 0 ] ).length ?
    +							[ "width", "height" ] :
    +							[ "width", "height", "top", "left" ];
    +
    +				$.each( css, function( i, prop ) {
    +					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
    +					if ( sum && sum >= 0 ) {
    +						style[ prop ] = sum || null;
    +					}
    +				} );
    +
    +				el.css( style );
    +			} );
    +	},
    +
    +	stop: function() {
    +		$( this ).removeData( "ui-resizable-alsoresize" );
    +	}
    +} );
    +
    +$.ui.plugin.add( "resizable", "ghost", {
    +
    +	start: function() {
    +
    +		var that = $( this ).resizable( "instance" ), cs = that.size;
    +
    +		that.ghost = that.originalElement.clone();
    +		that.ghost.css( {
    +			opacity: 0.25,
    +			display: "block",
    +			position: "relative",
    +			height: cs.height,
    +			width: cs.width,
    +			margin: 0,
    +			left: 0,
    +			top: 0
    +		} );
    +
    +		that._addClass( that.ghost, "ui-resizable-ghost" );
    +
    +		// DEPRECATED
    +		// TODO: remove after 1.12
    +		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
    +
    +			// Ghost option
    +			that.ghost.addClass( this.options.ghost );
    +		}
    +
    +		that.ghost.appendTo( that.helper );
    +
    +	},
    +
    +	resize: function() {
    +		var that = $( this ).resizable( "instance" );
    +		if ( that.ghost ) {
    +			that.ghost.css( {
    +				position: "relative",
    +				height: that.size.height,
    +				width: that.size.width
    +			} );
    +		}
    +	},
    +
    +	stop: function() {
    +		var that = $( this ).resizable( "instance" );
    +		if ( that.ghost && that.helper ) {
    +			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
    +		}
    +	}
    +
    +} );
    +
    +$.ui.plugin.add( "resizable", "grid", {
    +
    +	resize: function() {
    +		var outerDimensions,
    +			that = $( this ).resizable( "instance" ),
    +			o = that.options,
    +			cs = that.size,
    +			os = that.originalSize,
    +			op = that.originalPosition,
    +			a = that.axis,
    +			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
    +			gridX = ( grid[ 0 ] || 1 ),
    +			gridY = ( grid[ 1 ] || 1 ),
    +			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
    +			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
    +			newWidth = os.width + ox,
    +			newHeight = os.height + oy,
    +			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
    +			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
    +			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
    +			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
    +
    +		o.grid = grid;
    +
    +		if ( isMinWidth ) {
    +			newWidth += gridX;
    +		}
    +		if ( isMinHeight ) {
    +			newHeight += gridY;
    +		}
    +		if ( isMaxWidth ) {
    +			newWidth -= gridX;
    +		}
    +		if ( isMaxHeight ) {
    +			newHeight -= gridY;
    +		}
    +
    +		if ( /^(se|s|e)$/.test( a ) ) {
    +			that.size.width = newWidth;
    +			that.size.height = newHeight;
    +		} else if ( /^(ne)$/.test( a ) ) {
    +			that.size.width = newWidth;
    +			that.size.height = newHeight;
    +			that.position.top = op.top - oy;
    +		} else if ( /^(sw)$/.test( a ) ) {
    +			that.size.width = newWidth;
    +			that.size.height = newHeight;
    +			that.position.left = op.left - ox;
    +		} else {
    +			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
    +				outerDimensions = that._getPaddingPlusBorderDimensions( this );
    +			}
    +
    +			if ( newHeight - gridY > 0 ) {
    +				that.size.height = newHeight;
    +				that.position.top = op.top - oy;
    +			} else {
    +				newHeight = gridY - outerDimensions.height;
    +				that.size.height = newHeight;
    +				that.position.top = op.top + os.height - newHeight;
    +			}
    +			if ( newWidth - gridX > 0 ) {
    +				that.size.width = newWidth;
    +				that.position.left = op.left - ox;
    +			} else {
    +				newWidth = gridX - outerDimensions.width;
    +				that.size.width = newWidth;
    +				that.position.left = op.left + os.width - newWidth;
    +			}
    +		}
    +	}
    +
    +} );
    +
    +var widgetsResizable = $.ui.resizable;
    +
    +
    +/*!
    + * jQuery UI Dialog 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Dialog
    +//>>group: Widgets
    +//>>description: Displays customizable dialog windows.
    +//>>docs: http://api.jqueryui.com/dialog/
    +//>>demos: http://jqueryui.com/dialog/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/dialog.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +$.widget( "ui.dialog", {
    +	version: "1.12.1",
    +	options: {
    +		appendTo: "body",
    +		autoOpen: true,
    +		buttons: [],
    +		classes: {
    +			"ui-dialog": "ui-corner-all",
    +			"ui-dialog-titlebar": "ui-corner-all"
    +		},
    +		closeOnEscape: true,
    +		closeText: "Close",
    +		draggable: true,
    +		hide: null,
    +		height: "auto",
    +		maxHeight: null,
    +		maxWidth: null,
    +		minHeight: 150,
    +		minWidth: 150,
    +		modal: false,
    +		position: {
    +			my: "center",
    +			at: "center",
    +			of: window,
    +			collision: "fit",
    +
    +			// Ensure the titlebar is always visible
    +			using: function( pos ) {
    +				var topOffset = $( this ).css( pos ).offset().top;
    +				if ( topOffset < 0 ) {
    +					$( this ).css( "top", pos.top - topOffset );
    +				}
    +			}
    +		},
    +		resizable: true,
    +		show: null,
    +		title: null,
    +		width: 300,
    +
    +		// Callbacks
    +		beforeClose: null,
    +		close: null,
    +		drag: null,
    +		dragStart: null,
    +		dragStop: null,
    +		focus: null,
    +		open: null,
    +		resize: null,
    +		resizeStart: null,
    +		resizeStop: null
    +	},
    +
    +	sizeRelatedOptions: {
    +		buttons: true,
    +		height: true,
    +		maxHeight: true,
    +		maxWidth: true,
    +		minHeight: true,
    +		minWidth: true,
    +		width: true
    +	},
    +
    +	resizableRelatedOptions: {
    +		maxHeight: true,
    +		maxWidth: true,
    +		minHeight: true,
    +		minWidth: true
    +	},
    +
    +	_create: function() {
    +		this.originalCss = {
    +			display: this.element[ 0 ].style.display,
    +			width: this.element[ 0 ].style.width,
    +			minHeight: this.element[ 0 ].style.minHeight,
    +			maxHeight: this.element[ 0 ].style.maxHeight,
    +			height: this.element[ 0 ].style.height
    +		};
    +		this.originalPosition = {
    +			parent: this.element.parent(),
    +			index: this.element.parent().children().index( this.element )
    +		};
    +		this.originalTitle = this.element.attr( "title" );
    +		if ( this.options.title == null && this.originalTitle != null ) {
    +			this.options.title = this.originalTitle;
    +		}
    +
    +		// Dialogs can't be disabled
    +		if ( this.options.disabled ) {
    +			this.options.disabled = false;
    +		}
    +
    +		this._createWrapper();
    +
    +		this.element
    +			.show()
    +			.removeAttr( "title" )
    +			.appendTo( this.uiDialog );
    +
    +		this._addClass( "ui-dialog-content", "ui-widget-content" );
    +
    +		this._createTitlebar();
    +		this._createButtonPane();
    +
    +		if ( this.options.draggable && $.fn.draggable ) {
    +			this._makeDraggable();
    +		}
    +		if ( this.options.resizable && $.fn.resizable ) {
    +			this._makeResizable();
    +		}
    +
    +		this._isOpen = false;
    +
    +		this._trackFocus();
    +	},
    +
    +	_init: function() {
    +		if ( this.options.autoOpen ) {
    +			this.open();
    +		}
    +	},
    +
    +	_appendTo: function() {
    +		var element = this.options.appendTo;
    +		if ( element && ( element.jquery || element.nodeType ) ) {
    +			return $( element );
    +		}
    +		return this.document.find( element || "body" ).eq( 0 );
    +	},
    +
    +	_destroy: function() {
    +		var next,
    +			originalPosition = this.originalPosition;
    +
    +		this._untrackInstance();
    +		this._destroyOverlay();
    +
    +		this.element
    +			.removeUniqueId()
    +			.css( this.originalCss )
    +
    +			// Without detaching first, the following becomes really slow
    +			.detach();
    +
    +		this.uiDialog.remove();
    +
    +		if ( this.originalTitle ) {
    +			this.element.attr( "title", this.originalTitle );
    +		}
    +
    +		next = originalPosition.parent.children().eq( originalPosition.index );
    +
    +		// Don't try to place the dialog next to itself (#8613)
    +		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
    +			next.before( this.element );
    +		} else {
    +			originalPosition.parent.append( this.element );
    +		}
    +	},
    +
    +	widget: function() {
    +		return this.uiDialog;
    +	},
    +
    +	disable: $.noop,
    +	enable: $.noop,
    +
    +	close: function( event ) {
    +		var that = this;
    +
    +		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
    +			return;
    +		}
    +
    +		this._isOpen = false;
    +		this._focusedElement = null;
    +		this._destroyOverlay();
    +		this._untrackInstance();
    +
    +		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
    +
    +			// Hiding a focused element doesn't trigger blur in WebKit
    +			// so in case we have nothing to focus on, explicitly blur the active element
    +			// https://bugs.webkit.org/show_bug.cgi?id=47182
    +			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
    +		}
    +
    +		this._hide( this.uiDialog, this.options.hide, function() {
    +			that._trigger( "close", event );
    +		} );
    +	},
    +
    +	isOpen: function() {
    +		return this._isOpen;
    +	},
    +
    +	moveToTop: function() {
    +		this._moveToTop();
    +	},
    +
    +	_moveToTop: function( event, silent ) {
    +		var moved = false,
    +			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
    +				return +$( this ).css( "z-index" );
    +			} ).get(),
    +			zIndexMax = Math.max.apply( null, zIndices );
    +
    +		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
    +			this.uiDialog.css( "z-index", zIndexMax + 1 );
    +			moved = true;
    +		}
    +
    +		if ( moved && !silent ) {
    +			this._trigger( "focus", event );
    +		}
    +		return moved;
    +	},
    +
    +	open: function() {
    +		var that = this;
    +		if ( this._isOpen ) {
    +			if ( this._moveToTop() ) {
    +				this._focusTabbable();
    +			}
    +			return;
    +		}
    +
    +		this._isOpen = true;
    +		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
    +
    +		this._size();
    +		this._position();
    +		this._createOverlay();
    +		this._moveToTop( null, true );
    +
    +		// Ensure the overlay is moved to the top with the dialog, but only when
    +		// opening. The overlay shouldn't move after the dialog is open so that
    +		// modeless dialogs opened after the modal dialog stack properly.
    +		if ( this.overlay ) {
    +			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
    +		}
    +
    +		this._show( this.uiDialog, this.options.show, function() {
    +			that._focusTabbable();
    +			that._trigger( "focus" );
    +		} );
    +
    +		// Track the dialog immediately upon openening in case a focus event
    +		// somehow occurs outside of the dialog before an element inside the
    +		// dialog is focused (#10152)
    +		this._makeFocusTarget();
    +
    +		this._trigger( "open" );
    +	},
    +
    +	_focusTabbable: function() {
    +
    +		// Set focus to the first match:
    +		// 1. An element that was focused previously
    +		// 2. First element inside the dialog matching [autofocus]
    +		// 3. Tabbable element inside the content element
    +		// 4. Tabbable element inside the buttonpane
    +		// 5. The close button
    +		// 6. The dialog itself
    +		var hasFocus = this._focusedElement;
    +		if ( !hasFocus ) {
    +			hasFocus = this.element.find( "[autofocus]" );
    +		}
    +		if ( !hasFocus.length ) {
    +			hasFocus = this.element.find( ":tabbable" );
    +		}
    +		if ( !hasFocus.length ) {
    +			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
    +		}
    +		if ( !hasFocus.length ) {
    +			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
    +		}
    +		if ( !hasFocus.length ) {
    +			hasFocus = this.uiDialog;
    +		}
    +		hasFocus.eq( 0 ).trigger( "focus" );
    +	},
    +
    +	_keepFocus: function( event ) {
    +		function checkFocus() {
    +			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
    +				isActive = this.uiDialog[ 0 ] === activeElement ||
    +					$.contains( this.uiDialog[ 0 ], activeElement );
    +			if ( !isActive ) {
    +				this._focusTabbable();
    +			}
    +		}
    +		event.preventDefault();
    +		checkFocus.call( this );
    +
    +		// support: IE
    +		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
    +		// so we check again later
    +		this._delay( checkFocus );
    +	},
    +
    +	_createWrapper: function() {
    +		this.uiDialog = $( "<div>" )
    +			.hide()
    +			.attr( {
    +
    +				// Setting tabIndex makes the div focusable
    +				tabIndex: -1,
    +				role: "dialog"
    +			} )
    +			.appendTo( this._appendTo() );
    +
    +		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
    +		this._on( this.uiDialog, {
    +			keydown: function( event ) {
    +				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
    +						event.keyCode === $.ui.keyCode.ESCAPE ) {
    +					event.preventDefault();
    +					this.close( event );
    +					return;
    +				}
    +
    +				// Prevent tabbing out of dialogs
    +				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
    +					return;
    +				}
    +				var tabbables = this.uiDialog.find( ":tabbable" ),
    +					first = tabbables.filter( ":first" ),
    +					last = tabbables.filter( ":last" );
    +
    +				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
    +						!event.shiftKey ) {
    +					this._delay( function() {
    +						first.trigger( "focus" );
    +					} );
    +					event.preventDefault();
    +				} else if ( ( event.target === first[ 0 ] ||
    +						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
    +					this._delay( function() {
    +						last.trigger( "focus" );
    +					} );
    +					event.preventDefault();
    +				}
    +			},
    +			mousedown: function( event ) {
    +				if ( this._moveToTop( event ) ) {
    +					this._focusTabbable();
    +				}
    +			}
    +		} );
    +
    +		// We assume that any existing aria-describedby attribute means
    +		// that the dialog content is marked up properly
    +		// otherwise we brute force the content as the description
    +		if ( !this.element.find( "[aria-describedby]" ).length ) {
    +			this.uiDialog.attr( {
    +				"aria-describedby": this.element.uniqueId().attr( "id" )
    +			} );
    +		}
    +	},
    +
    +	_createTitlebar: function() {
    +		var uiDialogTitle;
    +
    +		this.uiDialogTitlebar = $( "<div>" );
    +		this._addClass( this.uiDialogTitlebar,
    +			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
    +		this._on( this.uiDialogTitlebar, {
    +			mousedown: function( event ) {
    +
    +				// Don't prevent click on close button (#8838)
    +				// Focusing a dialog that is partially scrolled out of view
    +				// causes the browser to scroll it into view, preventing the click event
    +				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
    +
    +					// Dialog isn't getting focus when dragging (#8063)
    +					this.uiDialog.trigger( "focus" );
    +				}
    +			}
    +		} );
    +
    +		// Support: IE
    +		// Use type="button" to prevent enter keypresses in textboxes from closing the
    +		// dialog in IE (#9312)
    +		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
    +			.button( {
    +				label: $( "<a>" ).text( this.options.closeText ).html(),
    +				icon: "ui-icon-closethick",
    +				showLabel: false
    +			} )
    +			.appendTo( this.uiDialogTitlebar );
    +
    +		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
    +		this._on( this.uiDialogTitlebarClose, {
    +			click: function( event ) {
    +				event.preventDefault();
    +				this.close( event );
    +			}
    +		} );
    +
    +		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
    +		this._addClass( uiDialogTitle, "ui-dialog-title" );
    +		this._title( uiDialogTitle );
    +
    +		this.uiDialogTitlebar.prependTo( this.uiDialog );
    +
    +		this.uiDialog.attr( {
    +			"aria-labelledby": uiDialogTitle.attr( "id" )
    +		} );
    +	},
    +
    +	_title: function( title ) {
    +		if ( this.options.title ) {
    +			title.text( this.options.title );
    +		} else {
    +			title.html( "&#160;" );
    +		}
    +	},
    +
    +	_createButtonPane: function() {
    +		this.uiDialogButtonPane = $( "<div>" );
    +		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
    +			"ui-widget-content ui-helper-clearfix" );
    +
    +		this.uiButtonSet = $( "<div>" )
    +			.appendTo( this.uiDialogButtonPane );
    +		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
    +
    +		this._createButtons();
    +	},
    +
    +	_createButtons: function() {
    +		var that = this,
    +			buttons = this.options.buttons;
    +
    +		// If we already have a button pane, remove it
    +		this.uiDialogButtonPane.remove();
    +		this.uiButtonSet.empty();
    +
    +		if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
    +			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
    +			return;
    +		}
    +
    +		$.each( buttons, function( name, props ) {
    +			var click, buttonOptions;
    +			props = $.isFunction( props ) ?
    +				{ click: props, text: name } :
    +				props;
    +
    +			// Default to a non-submitting button
    +			props = $.extend( { type: "button" }, props );
    +
    +			// Change the context for the click callback to be the main element
    +			click = props.click;
    +			buttonOptions = {
    +				icon: props.icon,
    +				iconPosition: props.iconPosition,
    +				showLabel: props.showLabel,
    +
    +				// Deprecated options
    +				icons: props.icons,
    +				text: props.text
    +			};
    +
    +			delete props.click;
    +			delete props.icon;
    +			delete props.iconPosition;
    +			delete props.showLabel;
    +
    +			// Deprecated options
    +			delete props.icons;
    +			if ( typeof props.text === "boolean" ) {
    +				delete props.text;
    +			}
    +
    +			$( "<button></button>", props )
    +				.button( buttonOptions )
    +				.appendTo( that.uiButtonSet )
    +				.on( "click", function() {
    +					click.apply( that.element[ 0 ], arguments );
    +				} );
    +		} );
    +		this._addClass( this.uiDialog, "ui-dialog-buttons" );
    +		this.uiDialogButtonPane.appendTo( this.uiDialog );
    +	},
    +
    +	_makeDraggable: function() {
    +		var that = this,
    +			options = this.options;
    +
    +		function filteredUi( ui ) {
    +			return {
    +				position: ui.position,
    +				offset: ui.offset
    +			};
    +		}
    +
    +		this.uiDialog.draggable( {
    +			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
    +			handle: ".ui-dialog-titlebar",
    +			containment: "document",
    +			start: function( event, ui ) {
    +				that._addClass( $( this ), "ui-dialog-dragging" );
    +				that._blockFrames();
    +				that._trigger( "dragStart", event, filteredUi( ui ) );
    +			},
    +			drag: function( event, ui ) {
    +				that._trigger( "drag", event, filteredUi( ui ) );
    +			},
    +			stop: function( event, ui ) {
    +				var left = ui.offset.left - that.document.scrollLeft(),
    +					top = ui.offset.top - that.document.scrollTop();
    +
    +				options.position = {
    +					my: "left top",
    +					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
    +						"top" + ( top >= 0 ? "+" : "" ) + top,
    +					of: that.window
    +				};
    +				that._removeClass( $( this ), "ui-dialog-dragging" );
    +				that._unblockFrames();
    +				that._trigger( "dragStop", event, filteredUi( ui ) );
    +			}
    +		} );
    +	},
    +
    +	_makeResizable: function() {
    +		var that = this,
    +			options = this.options,
    +			handles = options.resizable,
    +
    +			// .ui-resizable has position: relative defined in the stylesheet
    +			// but dialogs have to use absolute or fixed positioning
    +			position = this.uiDialog.css( "position" ),
    +			resizeHandles = typeof handles === "string" ?
    +				handles :
    +				"n,e,s,w,se,sw,ne,nw";
    +
    +		function filteredUi( ui ) {
    +			return {
    +				originalPosition: ui.originalPosition,
    +				originalSize: ui.originalSize,
    +				position: ui.position,
    +				size: ui.size
    +			};
    +		}
    +
    +		this.uiDialog.resizable( {
    +			cancel: ".ui-dialog-content",
    +			containment: "document",
    +			alsoResize: this.element,
    +			maxWidth: options.maxWidth,
    +			maxHeight: options.maxHeight,
    +			minWidth: options.minWidth,
    +			minHeight: this._minHeight(),
    +			handles: resizeHandles,
    +			start: function( event, ui ) {
    +				that._addClass( $( this ), "ui-dialog-resizing" );
    +				that._blockFrames();
    +				that._trigger( "resizeStart", event, filteredUi( ui ) );
    +			},
    +			resize: function( event, ui ) {
    +				that._trigger( "resize", event, filteredUi( ui ) );
    +			},
    +			stop: function( event, ui ) {
    +				var offset = that.uiDialog.offset(),
    +					left = offset.left - that.document.scrollLeft(),
    +					top = offset.top - that.document.scrollTop();
    +
    +				options.height = that.uiDialog.height();
    +				options.width = that.uiDialog.width();
    +				options.position = {
    +					my: "left top",
    +					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
    +						"top" + ( top >= 0 ? "+" : "" ) + top,
    +					of: that.window
    +				};
    +				that._removeClass( $( this ), "ui-dialog-resizing" );
    +				that._unblockFrames();
    +				that._trigger( "resizeStop", event, filteredUi( ui ) );
    +			}
    +		} )
    +			.css( "position", position );
    +	},
    +
    +	_trackFocus: function() {
    +		this._on( this.widget(), {
    +			focusin: function( event ) {
    +				this._makeFocusTarget();
    +				this._focusedElement = $( event.target );
    +			}
    +		} );
    +	},
    +
    +	_makeFocusTarget: function() {
    +		this._untrackInstance();
    +		this._trackingInstances().unshift( this );
    +	},
    +
    +	_untrackInstance: function() {
    +		var instances = this._trackingInstances(),
    +			exists = $.inArray( this, instances );
    +		if ( exists !== -1 ) {
    +			instances.splice( exists, 1 );
    +		}
    +	},
    +
    +	_trackingInstances: function() {
    +		var instances = this.document.data( "ui-dialog-instances" );
    +		if ( !instances ) {
    +			instances = [];
    +			this.document.data( "ui-dialog-instances", instances );
    +		}
    +		return instances;
    +	},
    +
    +	_minHeight: function() {
    +		var options = this.options;
    +
    +		return options.height === "auto" ?
    +			options.minHeight :
    +			Math.min( options.minHeight, options.height );
    +	},
    +
    +	_position: function() {
    +
    +		// Need to show the dialog to get the actual offset in the position plugin
    +		var isVisible = this.uiDialog.is( ":visible" );
    +		if ( !isVisible ) {
    +			this.uiDialog.show();
    +		}
    +		this.uiDialog.position( this.options.position );
    +		if ( !isVisible ) {
    +			this.uiDialog.hide();
    +		}
    +	},
    +
    +	_setOptions: function( options ) {
    +		var that = this,
    +			resize = false,
    +			resizableOptions = {};
    +
    +		$.each( options, function( key, value ) {
    +			that._setOption( key, value );
    +
    +			if ( key in that.sizeRelatedOptions ) {
    +				resize = true;
    +			}
    +			if ( key in that.resizableRelatedOptions ) {
    +				resizableOptions[ key ] = value;
    +			}
    +		} );
    +
    +		if ( resize ) {
    +			this._size();
    +			this._position();
    +		}
    +		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
    +			this.uiDialog.resizable( "option", resizableOptions );
    +		}
    +	},
    +
    +	_setOption: function( key, value ) {
    +		var isDraggable, isResizable,
    +			uiDialog = this.uiDialog;
    +
    +		if ( key === "disabled" ) {
    +			return;
    +		}
    +
    +		this._super( key, value );
    +
    +		if ( key === "appendTo" ) {
    +			this.uiDialog.appendTo( this._appendTo() );
    +		}
    +
    +		if ( key === "buttons" ) {
    +			this._createButtons();
    +		}
    +
    +		if ( key === "closeText" ) {
    +			this.uiDialogTitlebarClose.button( {
    +
    +				// Ensure that we always pass a string
    +				label: $( "<a>" ).text( "" + this.options.closeText ).html()
    +			} );
    +		}
    +
    +		if ( key === "draggable" ) {
    +			isDraggable = uiDialog.is( ":data(ui-draggable)" );
    +			if ( isDraggable && !value ) {
    +				uiDialog.draggable( "destroy" );
    +			}
    +
    +			if ( !isDraggable && value ) {
    +				this._makeDraggable();
    +			}
    +		}
    +
    +		if ( key === "position" ) {
    +			this._position();
    +		}
    +
    +		if ( key === "resizable" ) {
    +
    +			// currently resizable, becoming non-resizable
    +			isResizable = uiDialog.is( ":data(ui-resizable)" );
    +			if ( isResizable && !value ) {
    +				uiDialog.resizable( "destroy" );
    +			}
    +
    +			// Currently resizable, changing handles
    +			if ( isResizable && typeof value === "string" ) {
    +				uiDialog.resizable( "option", "handles", value );
    +			}
    +
    +			// Currently non-resizable, becoming resizable
    +			if ( !isResizable && value !== false ) {
    +				this._makeResizable();
    +			}
    +		}
    +
    +		if ( key === "title" ) {
    +			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
    +		}
    +	},
    +
    +	_size: function() {
    +
    +		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
    +		// divs will both have width and height set, so we need to reset them
    +		var nonContentHeight, minContentHeight, maxContentHeight,
    +			options = this.options;
    +
    +		// Reset content sizing
    +		this.element.show().css( {
    +			width: "auto",
    +			minHeight: 0,
    +			maxHeight: "none",
    +			height: 0
    +		} );
    +
    +		if ( options.minWidth > options.width ) {
    +			options.width = options.minWidth;
    +		}
    +
    +		// Reset wrapper sizing
    +		// determine the height of all the non-content elements
    +		nonContentHeight = this.uiDialog.css( {
    +			height: "auto",
    +			width: options.width
    +		} )
    +			.outerHeight();
    +		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
    +		maxContentHeight = typeof options.maxHeight === "number" ?
    +			Math.max( 0, options.maxHeight - nonContentHeight ) :
    +			"none";
    +
    +		if ( options.height === "auto" ) {
    +			this.element.css( {
    +				minHeight: minContentHeight,
    +				maxHeight: maxContentHeight,
    +				height: "auto"
    +			} );
    +		} else {
    +			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
    +		}
    +
    +		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
    +			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
    +		}
    +	},
    +
    +	_blockFrames: function() {
    +		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
    +			var iframe = $( this );
    +
    +			return $( "<div>" )
    +				.css( {
    +					position: "absolute",
    +					width: iframe.outerWidth(),
    +					height: iframe.outerHeight()
    +				} )
    +				.appendTo( iframe.parent() )
    +				.offset( iframe.offset() )[ 0 ];
    +		} );
    +	},
    +
    +	_unblockFrames: function() {
    +		if ( this.iframeBlocks ) {
    +			this.iframeBlocks.remove();
    +			delete this.iframeBlocks;
    +		}
    +	},
    +
    +	_allowInteraction: function( event ) {
    +		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
    +			return true;
    +		}
    +
    +		// TODO: Remove hack when datepicker implements
    +		// the .ui-front logic (#8989)
    +		return !!$( event.target ).closest( ".ui-datepicker" ).length;
    +	},
    +
    +	_createOverlay: function() {
    +		if ( !this.options.modal ) {
    +			return;
    +		}
    +
    +		// We use a delay in case the overlay is created from an
    +		// event that we're going to be cancelling (#2804)
    +		var isOpening = true;
    +		this._delay( function() {
    +			isOpening = false;
    +		} );
    +
    +		if ( !this.document.data( "ui-dialog-overlays" ) ) {
    +
    +			// Prevent use of anchors and inputs
    +			// Using _on() for an event handler shared across many instances is
    +			// safe because the dialogs stack and must be closed in reverse order
    +			this._on( this.document, {
    +				focusin: function( event ) {
    +					if ( isOpening ) {
    +						return;
    +					}
    +
    +					if ( !this._allowInteraction( event ) ) {
    +						event.preventDefault();
    +						this._trackingInstances()[ 0 ]._focusTabbable();
    +					}
    +				}
    +			} );
    +		}
    +
    +		this.overlay = $( "<div>" )
    +			.appendTo( this._appendTo() );
    +
    +		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
    +		this._on( this.overlay, {
    +			mousedown: "_keepFocus"
    +		} );
    +		this.document.data( "ui-dialog-overlays",
    +			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
    +	},
    +
    +	_destroyOverlay: function() {
    +		if ( !this.options.modal ) {
    +			return;
    +		}
    +
    +		if ( this.overlay ) {
    +			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
    +
    +			if ( !overlays ) {
    +				this._off( this.document, "focusin" );
    +				this.document.removeData( "ui-dialog-overlays" );
    +			} else {
    +				this.document.data( "ui-dialog-overlays", overlays );
    +			}
    +
    +			this.overlay.remove();
    +			this.overlay = null;
    +		}
    +	}
    +} );
    +
    +// DEPRECATED
    +// TODO: switch return back to widget declaration at top of file when this is removed
    +if ( $.uiBackCompat !== false ) {
    +
    +	// Backcompat for dialogClass option
    +	$.widget( "ui.dialog", $.ui.dialog, {
    +		options: {
    +			dialogClass: ""
    +		},
    +		_createWrapper: function() {
    +			this._super();
    +			this.uiDialog.addClass( this.options.dialogClass );
    +		},
    +		_setOption: function( key, value ) {
    +			if ( key === "dialogClass" ) {
    +				this.uiDialog
    +					.removeClass( this.options.dialogClass )
    +					.addClass( value );
    +			}
    +			this._superApply( arguments );
    +		}
    +	} );
    +}
    +
    +var widgetsDialog = $.ui.dialog;
    +
    +
    +/*!
    + * jQuery UI Droppable 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Droppable
    +//>>group: Interactions
    +//>>description: Enables drop targets for draggable elements.
    +//>>docs: http://api.jqueryui.com/droppable/
    +//>>demos: http://jqueryui.com/droppable/
    +
    +
    +
    +$.widget( "ui.droppable", {
    +	version: "1.12.1",
    +	widgetEventPrefix: "drop",
    +	options: {
    +		accept: "*",
    +		addClasses: true,
    +		greedy: false,
    +		scope: "default",
    +		tolerance: "intersect",
    +
    +		// Callbacks
    +		activate: null,
    +		deactivate: null,
    +		drop: null,
    +		out: null,
    +		over: null
    +	},
    +	_create: function() {
    +
    +		var proportions,
    +			o = this.options,
    +			accept = o.accept;
    +
    +		this.isover = false;
    +		this.isout = true;
    +
    +		this.accept = $.isFunction( accept ) ? accept : function( d ) {
    +			return d.is( accept );
    +		};
    +
    +		this.proportions = function( /* valueToWrite */ ) {
    +			if ( arguments.length ) {
    +
    +				// Store the droppable's proportions
    +				proportions = arguments[ 0 ];
    +			} else {
    +
    +				// Retrieve or derive the droppable's proportions
    +				return proportions ?
    +					proportions :
    +					proportions = {
    +						width: this.element[ 0 ].offsetWidth,
    +						height: this.element[ 0 ].offsetHeight
    +					};
    +			}
    +		};
    +
    +		this._addToManager( o.scope );
    +
    +		o.addClasses && this._addClass( "ui-droppable" );
    +
    +	},
    +
    +	_addToManager: function( scope ) {
    +
    +		// Add the reference and positions to the manager
    +		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
    +		$.ui.ddmanager.droppables[ scope ].push( this );
    +	},
    +
    +	_splice: function( drop ) {
    +		var i = 0;
    +		for ( ; i < drop.length; i++ ) {
    +			if ( drop[ i ] === this ) {
    +				drop.splice( i, 1 );
    +			}
    +		}
    +	},
    +
    +	_destroy: function() {
    +		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
    +
    +		this._splice( drop );
    +	},
    +
    +	_setOption: function( key, value ) {
    +
    +		if ( key === "accept" ) {
    +			this.accept = $.isFunction( value ) ? value : function( d ) {
    +				return d.is( value );
    +			};
    +		} else if ( key === "scope" ) {
    +			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
    +
    +			this._splice( drop );
    +			this._addToManager( value );
    +		}
    +
    +		this._super( key, value );
    +	},
    +
    +	_activate: function( event ) {
    +		var draggable = $.ui.ddmanager.current;
    +
    +		this._addActiveClass();
    +		if ( draggable ) {
    +			this._trigger( "activate", event, this.ui( draggable ) );
    +		}
    +	},
    +
    +	_deactivate: function( event ) {
    +		var draggable = $.ui.ddmanager.current;
    +
    +		this._removeActiveClass();
    +		if ( draggable ) {
    +			this._trigger( "deactivate", event, this.ui( draggable ) );
    +		}
    +	},
    +
    +	_over: function( event ) {
    +
    +		var draggable = $.ui.ddmanager.current;
    +
    +		// Bail if draggable and droppable are same element
    +		if ( !draggable || ( draggable.currentItem ||
    +				draggable.element )[ 0 ] === this.element[ 0 ] ) {
    +			return;
    +		}
    +
    +		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
    +				draggable.element ) ) ) {
    +			this._addHoverClass();
    +			this._trigger( "over", event, this.ui( draggable ) );
    +		}
    +
    +	},
    +
    +	_out: function( event ) {
    +
    +		var draggable = $.ui.ddmanager.current;
    +
    +		// Bail if draggable and droppable are same element
    +		if ( !draggable || ( draggable.currentItem ||
    +				draggable.element )[ 0 ] === this.element[ 0 ] ) {
    +			return;
    +		}
    +
    +		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
    +				draggable.element ) ) ) {
    +			this._removeHoverClass();
    +			this._trigger( "out", event, this.ui( draggable ) );
    +		}
    +
    +	},
    +
    +	_drop: function( event, custom ) {
    +
    +		var draggable = custom || $.ui.ddmanager.current,
    +			childrenIntersection = false;
    +
    +		// Bail if draggable and droppable are same element
    +		if ( !draggable || ( draggable.currentItem ||
    +				draggable.element )[ 0 ] === this.element[ 0 ] ) {
    +			return false;
    +		}
    +
    +		this.element
    +			.find( ":data(ui-droppable)" )
    +			.not( ".ui-draggable-dragging" )
    +			.each( function() {
    +				var inst = $( this ).droppable( "instance" );
    +				if (
    +					inst.options.greedy &&
    +					!inst.options.disabled &&
    +					inst.options.scope === draggable.options.scope &&
    +					inst.accept.call(
    +						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
    +					) &&
    +					intersect(
    +						draggable,
    +						$.extend( inst, { offset: inst.element.offset() } ),
    +						inst.options.tolerance, event
    +					)
    +				) {
    +					childrenIntersection = true;
    +					return false; }
    +			} );
    +		if ( childrenIntersection ) {
    +			return false;
    +		}
    +
    +		if ( this.accept.call( this.element[ 0 ],
    +				( draggable.currentItem || draggable.element ) ) ) {
    +			this._removeActiveClass();
    +			this._removeHoverClass();
    +
    +			this._trigger( "drop", event, this.ui( draggable ) );
    +			return this.element;
    +		}
    +
    +		return false;
    +
    +	},
    +
    +	ui: function( c ) {
    +		return {
    +			draggable: ( c.currentItem || c.element ),
    +			helper: c.helper,
    +			position: c.position,
    +			offset: c.positionAbs
    +		};
    +	},
    +
    +	// Extension points just to make backcompat sane and avoid duplicating logic
    +	// TODO: Remove in 1.13 along with call to it below
    +	_addHoverClass: function() {
    +		this._addClass( "ui-droppable-hover" );
    +	},
    +
    +	_removeHoverClass: function() {
    +		this._removeClass( "ui-droppable-hover" );
    +	},
    +
    +	_addActiveClass: function() {
    +		this._addClass( "ui-droppable-active" );
    +	},
    +
    +	_removeActiveClass: function() {
    +		this._removeClass( "ui-droppable-active" );
    +	}
    +} );
    +
    +var intersect = $.ui.intersect = ( function() {
    +	function isOverAxis( x, reference, size ) {
    +		return ( x >= reference ) && ( x < ( reference + size ) );
    +	}
    +
    +	return function( draggable, droppable, toleranceMode, event ) {
    +
    +		if ( !droppable.offset ) {
    +			return false;
    +		}
    +
    +		var x1 = ( draggable.positionAbs ||
    +				draggable.position.absolute ).left + draggable.margins.left,
    +			y1 = ( draggable.positionAbs ||
    +				draggable.position.absolute ).top + draggable.margins.top,
    +			x2 = x1 + draggable.helperProportions.width,
    +			y2 = y1 + draggable.helperProportions.height,
    +			l = droppable.offset.left,
    +			t = droppable.offset.top,
    +			r = l + droppable.proportions().width,
    +			b = t + droppable.proportions().height;
    +
    +		switch ( toleranceMode ) {
    +		case "fit":
    +			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
    +		case "intersect":
    +			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
    +				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
    +				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
    +				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
    +		case "pointer":
    +			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
    +				isOverAxis( event.pageX, l, droppable.proportions().width );
    +		case "touch":
    +			return (
    +				( y1 >= t && y1 <= b ) || // Top edge touching
    +				( y2 >= t && y2 <= b ) || // Bottom edge touching
    +				( y1 < t && y2 > b ) // Surrounded vertically
    +			) && (
    +				( x1 >= l && x1 <= r ) || // Left edge touching
    +				( x2 >= l && x2 <= r ) || // Right edge touching
    +				( x1 < l && x2 > r ) // Surrounded horizontally
    +			);
    +		default:
    +			return false;
    +		}
    +	};
    +} )();
    +
    +/*
    +	This manager tracks offsets of draggables and droppables
    +*/
    +$.ui.ddmanager = {
    +	current: null,
    +	droppables: { "default": [] },
    +	prepareOffsets: function( t, event ) {
    +
    +		var i, j,
    +			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
    +			type = event ? event.type : null, // workaround for #2317
    +			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
    +
    +		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
    +
    +			// No disabled and non-accepted
    +			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
    +					( t.currentItem || t.element ) ) ) ) {
    +				continue;
    +			}
    +
    +			// Filter out elements in the current dragged item
    +			for ( j = 0; j < list.length; j++ ) {
    +				if ( list[ j ] === m[ i ].element[ 0 ] ) {
    +					m[ i ].proportions().height = 0;
    +					continue droppablesLoop;
    +				}
    +			}
    +
    +			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
    +			if ( !m[ i ].visible ) {
    +				continue;
    +			}
    +
    +			// Activate the droppable if used directly from draggables
    +			if ( type === "mousedown" ) {
    +				m[ i ]._activate.call( m[ i ], event );
    +			}
    +
    +			m[ i ].offset = m[ i ].element.offset();
    +			m[ i ].proportions( {
    +				width: m[ i ].element[ 0 ].offsetWidth,
    +				height: m[ i ].element[ 0 ].offsetHeight
    +			} );
    +
    +		}
    +
    +	},
    +	drop: function( draggable, event ) {
    +
    +		var dropped = false;
    +
    +		// Create a copy of the droppables in case the list changes during the drop (#9116)
    +		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
    +
    +			if ( !this.options ) {
    +				return;
    +			}
    +			if ( !this.options.disabled && this.visible &&
    +					intersect( draggable, this, this.options.tolerance, event ) ) {
    +				dropped = this._drop.call( this, event ) || dropped;
    +			}
    +
    +			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
    +					( draggable.currentItem || draggable.element ) ) ) {
    +				this.isout = true;
    +				this.isover = false;
    +				this._deactivate.call( this, event );
    +			}
    +
    +		} );
    +		return dropped;
    +
    +	},
    +	dragStart: function( draggable, event ) {
    +
    +		// Listen for scrolling so that if the dragging causes scrolling the position of the
    +		// droppables can be recalculated (see #5003)
    +		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
    +			if ( !draggable.options.refreshPositions ) {
    +				$.ui.ddmanager.prepareOffsets( draggable, event );
    +			}
    +		} );
    +	},
    +	drag: function( draggable, event ) {
    +
    +		// If you have a highly dynamic page, you might try this option. It renders positions
    +		// every time you move the mouse.
    +		if ( draggable.options.refreshPositions ) {
    +			$.ui.ddmanager.prepareOffsets( draggable, event );
    +		}
    +
    +		// Run through all droppables and check their positions based on specific tolerance options
    +		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
    +
    +			if ( this.options.disabled || this.greedyChild || !this.visible ) {
    +				return;
    +			}
    +
    +			var parentInstance, scope, parent,
    +				intersects = intersect( draggable, this, this.options.tolerance, event ),
    +				c = !intersects && this.isover ?
    +					"isout" :
    +					( intersects && !this.isover ? "isover" : null );
    +			if ( !c ) {
    +				return;
    +			}
    +
    +			if ( this.options.greedy ) {
    +
    +				// find droppable parents with same scope
    +				scope = this.options.scope;
    +				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
    +					return $( this ).droppable( "instance" ).options.scope === scope;
    +				} );
    +
    +				if ( parent.length ) {
    +					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
    +					parentInstance.greedyChild = ( c === "isover" );
    +				}
    +			}
    +
    +			// We just moved into a greedy child
    +			if ( parentInstance && c === "isover" ) {
    +				parentInstance.isover = false;
    +				parentInstance.isout = true;
    +				parentInstance._out.call( parentInstance, event );
    +			}
    +
    +			this[ c ] = true;
    +			this[ c === "isout" ? "isover" : "isout" ] = false;
    +			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
    +
    +			// We just moved out of a greedy child
    +			if ( parentInstance && c === "isout" ) {
    +				parentInstance.isout = false;
    +				parentInstance.isover = true;
    +				parentInstance._over.call( parentInstance, event );
    +			}
    +		} );
    +
    +	},
    +	dragStop: function( draggable, event ) {
    +		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
    +
    +		// Call prepareOffsets one final time since IE does not fire return scroll events when
    +		// overflow was caused by drag (see #5003)
    +		if ( !draggable.options.refreshPositions ) {
    +			$.ui.ddmanager.prepareOffsets( draggable, event );
    +		}
    +	}
    +};
    +
    +// DEPRECATED
    +// TODO: switch return back to widget declaration at top of file when this is removed
    +if ( $.uiBackCompat !== false ) {
    +
    +	// Backcompat for activeClass and hoverClass options
    +	$.widget( "ui.droppable", $.ui.droppable, {
    +		options: {
    +			hoverClass: false,
    +			activeClass: false
    +		},
    +		_addActiveClass: function() {
    +			this._super();
    +			if ( this.options.activeClass ) {
    +				this.element.addClass( this.options.activeClass );
    +			}
    +		},
    +		_removeActiveClass: function() {
    +			this._super();
    +			if ( this.options.activeClass ) {
    +				this.element.removeClass( this.options.activeClass );
    +			}
    +		},
    +		_addHoverClass: function() {
    +			this._super();
    +			if ( this.options.hoverClass ) {
    +				this.element.addClass( this.options.hoverClass );
    +			}
    +		},
    +		_removeHoverClass: function() {
    +			this._super();
    +			if ( this.options.hoverClass ) {
    +				this.element.removeClass( this.options.hoverClass );
    +			}
    +		}
    +	} );
    +}
    +
    +var widgetsDroppable = $.ui.droppable;
    +
    +
    +/*!
    + * jQuery UI Progressbar 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Progressbar
    +//>>group: Widgets
    +// jscs:disable maximumLineLength
    +//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
    +// jscs:enable maximumLineLength
    +//>>docs: http://api.jqueryui.com/progressbar/
    +//>>demos: http://jqueryui.com/progressbar/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/progressbar.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +var widgetsProgressbar = $.widget( "ui.progressbar", {
    +	version: "1.12.1",
    +	options: {
    +		classes: {
    +			"ui-progressbar": "ui-corner-all",
    +			"ui-progressbar-value": "ui-corner-left",
    +			"ui-progressbar-complete": "ui-corner-right"
    +		},
    +		max: 100,
    +		value: 0,
    +
    +		change: null,
    +		complete: null
    +	},
    +
    +	min: 0,
    +
    +	_create: function() {
    +
    +		// Constrain initial value
    +		this.oldValue = this.options.value = this._constrainedValue();
    +
    +		this.element.attr( {
    +
    +			// Only set static values; aria-valuenow and aria-valuemax are
    +			// set inside _refreshValue()
    +			role: "progressbar",
    +			"aria-valuemin": this.min
    +		} );
    +		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
    +
    +		this.valueDiv = $( "<div>" ).appendTo( this.element );
    +		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
    +		this._refreshValue();
    +	},
    +
    +	_destroy: function() {
    +		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
    +
    +		this.valueDiv.remove();
    +	},
    +
    +	value: function( newValue ) {
    +		if ( newValue === undefined ) {
    +			return this.options.value;
    +		}
    +
    +		this.options.value = this._constrainedValue( newValue );
    +		this._refreshValue();
    +	},
    +
    +	_constrainedValue: function( newValue ) {
    +		if ( newValue === undefined ) {
    +			newValue = this.options.value;
    +		}
    +
    +		this.indeterminate = newValue === false;
    +
    +		// Sanitize value
    +		if ( typeof newValue !== "number" ) {
    +			newValue = 0;
    +		}
    +
    +		return this.indeterminate ? false :
    +			Math.min( this.options.max, Math.max( this.min, newValue ) );
    +	},
    +
    +	_setOptions: function( options ) {
    +
    +		// Ensure "value" option is set after other values (like max)
    +		var value = options.value;
    +		delete options.value;
    +
    +		this._super( options );
    +
    +		this.options.value = this._constrainedValue( value );
    +		this._refreshValue();
    +	},
    +
    +	_setOption: function( key, value ) {
    +		if ( key === "max" ) {
    +
    +			// Don't allow a max less than min
    +			value = Math.max( this.min, value );
    +		}
    +		this._super( key, value );
    +	},
    +
    +	_setOptionDisabled: function( value ) {
    +		this._super( value );
    +
    +		this.element.attr( "aria-disabled", value );
    +		this._toggleClass( null, "ui-state-disabled", !!value );
    +	},
    +
    +	_percentage: function() {
    +		return this.indeterminate ?
    +			100 :
    +			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
    +	},
    +
    +	_refreshValue: function() {
    +		var value = this.options.value,
    +			percentage = this._percentage();
    +
    +		this.valueDiv
    +			.toggle( this.indeterminate || value > this.min )
    +			.width( percentage.toFixed( 0 ) + "%" );
    +
    +		this
    +			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
    +				value === this.options.max )
    +			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
    +
    +		if ( this.indeterminate ) {
    +			this.element.removeAttr( "aria-valuenow" );
    +			if ( !this.overlayDiv ) {
    +				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
    +				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
    +			}
    +		} else {
    +			this.element.attr( {
    +				"aria-valuemax": this.options.max,
    +				"aria-valuenow": value
    +			} );
    +			if ( this.overlayDiv ) {
    +				this.overlayDiv.remove();
    +				this.overlayDiv = null;
    +			}
    +		}
    +
    +		if ( this.oldValue !== value ) {
    +			this.oldValue = value;
    +			this._trigger( "change" );
    +		}
    +		if ( value === this.options.max ) {
    +			this._trigger( "complete" );
    +		}
    +	}
    +} );
    +
    +
    +/*!
    + * jQuery UI Selectable 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Selectable
    +//>>group: Interactions
    +//>>description: Allows groups of elements to be selected with the mouse.
    +//>>docs: http://api.jqueryui.com/selectable/
    +//>>demos: http://jqueryui.com/selectable/
    +//>>css.structure: ../../themes/base/selectable.css
    +
    +
    +
    +var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
    +	version: "1.12.1",
    +	options: {
    +		appendTo: "body",
    +		autoRefresh: true,
    +		distance: 0,
    +		filter: "*",
    +		tolerance: "touch",
    +
    +		// Callbacks
    +		selected: null,
    +		selecting: null,
    +		start: null,
    +		stop: null,
    +		unselected: null,
    +		unselecting: null
    +	},
    +	_create: function() {
    +		var that = this;
    +
    +		this._addClass( "ui-selectable" );
    +
    +		this.dragged = false;
    +
    +		// Cache selectee children based on filter
    +		this.refresh = function() {
    +			that.elementPos = $( that.element[ 0 ] ).offset();
    +			that.selectees = $( that.options.filter, that.element[ 0 ] );
    +			that._addClass( that.selectees, "ui-selectee" );
    +			that.selectees.each( function() {
    +				var $this = $( this ),
    +					selecteeOffset = $this.offset(),
    +					pos = {
    +						left: selecteeOffset.left - that.elementPos.left,
    +						top: selecteeOffset.top - that.elementPos.top
    +					};
    +				$.data( this, "selectable-item", {
    +					element: this,
    +					$element: $this,
    +					left: pos.left,
    +					top: pos.top,
    +					right: pos.left + $this.outerWidth(),
    +					bottom: pos.top + $this.outerHeight(),
    +					startselected: false,
    +					selected: $this.hasClass( "ui-selected" ),
    +					selecting: $this.hasClass( "ui-selecting" ),
    +					unselecting: $this.hasClass( "ui-unselecting" )
    +				} );
    +			} );
    +		};
    +		this.refresh();
    +
    +		this._mouseInit();
    +
    +		this.helper = $( "<div>" );
    +		this._addClass( this.helper, "ui-selectable-helper" );
    +	},
    +
    +	_destroy: function() {
    +		this.selectees.removeData( "selectable-item" );
    +		this._mouseDestroy();
    +	},
    +
    +	_mouseStart: function( event ) {
    +		var that = this,
    +			options = this.options;
    +
    +		this.opos = [ event.pageX, event.pageY ];
    +		this.elementPos = $( this.element[ 0 ] ).offset();
    +
    +		if ( this.options.disabled ) {
    +			return;
    +		}
    +
    +		this.selectees = $( options.filter, this.element[ 0 ] );
    +
    +		this._trigger( "start", event );
    +
    +		$( options.appendTo ).append( this.helper );
    +
    +		// position helper (lasso)
    +		this.helper.css( {
    +			"left": event.pageX,
    +			"top": event.pageY,
    +			"width": 0,
    +			"height": 0
    +		} );
    +
    +		if ( options.autoRefresh ) {
    +			this.refresh();
    +		}
    +
    +		this.selectees.filter( ".ui-selected" ).each( function() {
    +			var selectee = $.data( this, "selectable-item" );
    +			selectee.startselected = true;
    +			if ( !event.metaKey && !event.ctrlKey ) {
    +				that._removeClass( selectee.$element, "ui-selected" );
    +				selectee.selected = false;
    +				that._addClass( selectee.$element, "ui-unselecting" );
    +				selectee.unselecting = true;
    +
    +				// selectable UNSELECTING callback
    +				that._trigger( "unselecting", event, {
    +					unselecting: selectee.element
    +				} );
    +			}
    +		} );
    +
    +		$( event.target ).parents().addBack().each( function() {
    +			var doSelect,
    +				selectee = $.data( this, "selectable-item" );
    +			if ( selectee ) {
    +				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
    +					!selectee.$element.hasClass( "ui-selected" );
    +				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
    +					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
    +				selectee.unselecting = !doSelect;
    +				selectee.selecting = doSelect;
    +				selectee.selected = doSelect;
    +
    +				// selectable (UN)SELECTING callback
    +				if ( doSelect ) {
    +					that._trigger( "selecting", event, {
    +						selecting: selectee.element
    +					} );
    +				} else {
    +					that._trigger( "unselecting", event, {
    +						unselecting: selectee.element
    +					} );
    +				}
    +				return false;
    +			}
    +		} );
    +
    +	},
    +
    +	_mouseDrag: function( event ) {
    +
    +		this.dragged = true;
    +
    +		if ( this.options.disabled ) {
    +			return;
    +		}
    +
    +		var tmp,
    +			that = this,
    +			options = this.options,
    +			x1 = this.opos[ 0 ],
    +			y1 = this.opos[ 1 ],
    +			x2 = event.pageX,
    +			y2 = event.pageY;
    +
    +		if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
    +		if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
    +		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
    +
    +		this.selectees.each( function() {
    +			var selectee = $.data( this, "selectable-item" ),
    +				hit = false,
    +				offset = {};
    +
    +			//prevent helper from being selected if appendTo: selectable
    +			if ( !selectee || selectee.element === that.element[ 0 ] ) {
    +				return;
    +			}
    +
    +			offset.left   = selectee.left   + that.elementPos.left;
    +			offset.right  = selectee.right  + that.elementPos.left;
    +			offset.top    = selectee.top    + that.elementPos.top;
    +			offset.bottom = selectee.bottom + that.elementPos.top;
    +
    +			if ( options.tolerance === "touch" ) {
    +				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
    +                    offset.bottom < y1 ) );
    +			} else if ( options.tolerance === "fit" ) {
    +				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
    +                    offset.bottom < y2 );
    +			}
    +
    +			if ( hit ) {
    +
    +				// SELECT
    +				if ( selectee.selected ) {
    +					that._removeClass( selectee.$element, "ui-selected" );
    +					selectee.selected = false;
    +				}
    +				if ( selectee.unselecting ) {
    +					that._removeClass( selectee.$element, "ui-unselecting" );
    +					selectee.unselecting = false;
    +				}
    +				if ( !selectee.selecting ) {
    +					that._addClass( selectee.$element, "ui-selecting" );
    +					selectee.selecting = true;
    +
    +					// selectable SELECTING callback
    +					that._trigger( "selecting", event, {
    +						selecting: selectee.element
    +					} );
    +				}
    +			} else {
    +
    +				// UNSELECT
    +				if ( selectee.selecting ) {
    +					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
    +						that._removeClass( selectee.$element, "ui-selecting" );
    +						selectee.selecting = false;
    +						that._addClass( selectee.$element, "ui-selected" );
    +						selectee.selected = true;
    +					} else {
    +						that._removeClass( selectee.$element, "ui-selecting" );
    +						selectee.selecting = false;
    +						if ( selectee.startselected ) {
    +							that._addClass( selectee.$element, "ui-unselecting" );
    +							selectee.unselecting = true;
    +						}
    +
    +						// selectable UNSELECTING callback
    +						that._trigger( "unselecting", event, {
    +							unselecting: selectee.element
    +						} );
    +					}
    +				}
    +				if ( selectee.selected ) {
    +					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
    +						that._removeClass( selectee.$element, "ui-selected" );
    +						selectee.selected = false;
    +
    +						that._addClass( selectee.$element, "ui-unselecting" );
    +						selectee.unselecting = true;
    +
    +						// selectable UNSELECTING callback
    +						that._trigger( "unselecting", event, {
    +							unselecting: selectee.element
    +						} );
    +					}
    +				}
    +			}
    +		} );
    +
    +		return false;
    +	},
    +
    +	_mouseStop: function( event ) {
    +		var that = this;
    +
    +		this.dragged = false;
    +
    +		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
    +			var selectee = $.data( this, "selectable-item" );
    +			that._removeClass( selectee.$element, "ui-unselecting" );
    +			selectee.unselecting = false;
    +			selectee.startselected = false;
    +			that._trigger( "unselected", event, {
    +				unselected: selectee.element
    +			} );
    +		} );
    +		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
    +			var selectee = $.data( this, "selectable-item" );
    +			that._removeClass( selectee.$element, "ui-selecting" )
    +				._addClass( selectee.$element, "ui-selected" );
    +			selectee.selecting = false;
    +			selectee.selected = true;
    +			selectee.startselected = true;
    +			that._trigger( "selected", event, {
    +				selected: selectee.element
    +			} );
    +		} );
    +		this._trigger( "stop", event );
    +
    +		this.helper.remove();
    +
    +		return false;
    +	}
    +
    +} );
    +
    +
    +/*!
    + * jQuery UI Selectmenu 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Selectmenu
    +//>>group: Widgets
    +// jscs:disable maximumLineLength
    +//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
    +// jscs:enable maximumLineLength
    +//>>docs: http://api.jqueryui.com/selectmenu/
    +//>>demos: http://jqueryui.com/selectmenu/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
    +	version: "1.12.1",
    +	defaultElement: "<select>",
    +	options: {
    +		appendTo: null,
    +		classes: {
    +			"ui-selectmenu-button-open": "ui-corner-top",
    +			"ui-selectmenu-button-closed": "ui-corner-all"
    +		},
    +		disabled: null,
    +		icons: {
    +			button: "ui-icon-triangle-1-s"
    +		},
    +		position: {
    +			my: "left top",
    +			at: "left bottom",
    +			collision: "none"
    +		},
    +		width: false,
    +
    +		// Callbacks
    +		change: null,
    +		close: null,
    +		focus: null,
    +		open: null,
    +		select: null
    +	},
    +
    +	_create: function() {
    +		var selectmenuId = this.element.uniqueId().attr( "id" );
    +		this.ids = {
    +			element: selectmenuId,
    +			button: selectmenuId + "-button",
    +			menu: selectmenuId + "-menu"
    +		};
    +
    +		this._drawButton();
    +		this._drawMenu();
    +		this._bindFormResetHandler();
    +
    +		this._rendered = false;
    +		this.menuItems = $();
    +	},
    +
    +	_drawButton: function() {
    +		var icon,
    +			that = this,
    +			item = this._parseOption(
    +				this.element.find( "option:selected" ),
    +				this.element[ 0 ].selectedIndex
    +			);
    +
    +		// Associate existing label with the new button
    +		this.labels = this.element.labels().attr( "for", this.ids.button );
    +		this._on( this.labels, {
    +			click: function( event ) {
    +				this.button.focus();
    +				event.preventDefault();
    +			}
    +		} );
    +
    +		// Hide original select element
    +		this.element.hide();
    +
    +		// Create button
    +		this.button = $( "<span>", {
    +			tabindex: this.options.disabled ? -1 : 0,
    +			id: this.ids.button,
    +			role: "combobox",
    +			"aria-expanded": "false",
    +			"aria-autocomplete": "list",
    +			"aria-owns": this.ids.menu,
    +			"aria-haspopup": "true",
    +			title: this.element.attr( "title" )
    +		} )
    +			.insertAfter( this.element );
    +
    +		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
    +			"ui-button ui-widget" );
    +
    +		icon = $( "<span>" ).appendTo( this.button );
    +		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
    +		this.buttonItem = this._renderButtonItem( item )
    +			.appendTo( this.button );
    +
    +		if ( this.options.width !== false ) {
    +			this._resizeButton();
    +		}
    +
    +		this._on( this.button, this._buttonEvents );
    +		this.button.one( "focusin", function() {
    +
    +			// Delay rendering the menu items until the button receives focus.
    +			// The menu may have already been rendered via a programmatic open.
    +			if ( !that._rendered ) {
    +				that._refreshMenu();
    +			}
    +		} );
    +	},
    +
    +	_drawMenu: function() {
    +		var that = this;
    +
    +		// Create menu
    +		this.menu = $( "<ul>", {
    +			"aria-hidden": "true",
    +			"aria-labelledby": this.ids.button,
    +			id: this.ids.menu
    +		} );
    +
    +		// Wrap menu
    +		this.menuWrap = $( "<div>" ).append( this.menu );
    +		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
    +		this.menuWrap.appendTo( this._appendTo() );
    +
    +		// Initialize menu widget
    +		this.menuInstance = this.menu
    +			.menu( {
    +				classes: {
    +					"ui-menu": "ui-corner-bottom"
    +				},
    +				role: "listbox",
    +				select: function( event, ui ) {
    +					event.preventDefault();
    +
    +					// Support: IE8
    +					// If the item was selected via a click, the text selection
    +					// will be destroyed in IE
    +					that._setSelection();
    +
    +					that._select( ui.item.data( "ui-selectmenu-item" ), event );
    +				},
    +				focus: function( event, ui ) {
    +					var item = ui.item.data( "ui-selectmenu-item" );
    +
    +					// Prevent inital focus from firing and check if its a newly focused item
    +					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
    +						that._trigger( "focus", event, { item: item } );
    +						if ( !that.isOpen ) {
    +							that._select( item, event );
    +						}
    +					}
    +					that.focusIndex = item.index;
    +
    +					that.button.attr( "aria-activedescendant",
    +						that.menuItems.eq( item.index ).attr( "id" ) );
    +				}
    +			} )
    +			.menu( "instance" );
    +
    +		// Don't close the menu on mouseleave
    +		this.menuInstance._off( this.menu, "mouseleave" );
    +
    +		// Cancel the menu's collapseAll on document click
    +		this.menuInstance._closeOnDocumentClick = function() {
    +			return false;
    +		};
    +
    +		// Selects often contain empty items, but never contain dividers
    +		this.menuInstance._isDivider = function() {
    +			return false;
    +		};
    +	},
    +
    +	refresh: function() {
    +		this._refreshMenu();
    +		this.buttonItem.replaceWith(
    +			this.buttonItem = this._renderButtonItem(
    +
    +				// Fall back to an empty object in case there are no options
    +				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
    +			)
    +		);
    +		if ( this.options.width === null ) {
    +			this._resizeButton();
    +		}
    +	},
    +
    +	_refreshMenu: function() {
    +		var item,
    +			options = this.element.find( "option" );
    +
    +		this.menu.empty();
    +
    +		this._parseOptions( options );
    +		this._renderMenu( this.menu, this.items );
    +
    +		this.menuInstance.refresh();
    +		this.menuItems = this.menu.find( "li" )
    +			.not( ".ui-selectmenu-optgroup" )
    +				.find( ".ui-menu-item-wrapper" );
    +
    +		this._rendered = true;
    +
    +		if ( !options.length ) {
    +			return;
    +		}
    +
    +		item = this._getSelectedItem();
    +
    +		// Update the menu to have the correct item focused
    +		this.menuInstance.focus( null, item );
    +		this._setAria( item.data( "ui-selectmenu-item" ) );
    +
    +		// Set disabled state
    +		this._setOption( "disabled", this.element.prop( "disabled" ) );
    +	},
    +
    +	open: function( event ) {
    +		if ( this.options.disabled ) {
    +			return;
    +		}
    +
    +		// If this is the first time the menu is being opened, render the items
    +		if ( !this._rendered ) {
    +			this._refreshMenu();
    +		} else {
    +
    +			// Menu clears focus on close, reset focus to selected item
    +			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
    +			this.menuInstance.focus( null, this._getSelectedItem() );
    +		}
    +
    +		// If there are no options, don't open the menu
    +		if ( !this.menuItems.length ) {
    +			return;
    +		}
    +
    +		this.isOpen = true;
    +		this._toggleAttr();
    +		this._resizeMenu();
    +		this._position();
    +
    +		this._on( this.document, this._documentClick );
    +
    +		this._trigger( "open", event );
    +	},
    +
    +	_position: function() {
    +		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
    +	},
    +
    +	close: function( event ) {
    +		if ( !this.isOpen ) {
    +			return;
    +		}
    +
    +		this.isOpen = false;
    +		this._toggleAttr();
    +
    +		this.range = null;
    +		this._off( this.document );
    +
    +		this._trigger( "close", event );
    +	},
    +
    +	widget: function() {
    +		return this.button;
    +	},
    +
    +	menuWidget: function() {
    +		return this.menu;
    +	},
    +
    +	_renderButtonItem: function( item ) {
    +		var buttonItem = $( "<span>" );
    +
    +		this._setText( buttonItem, item.label );
    +		this._addClass( buttonItem, "ui-selectmenu-text" );
    +
    +		return buttonItem;
    +	},
    +
    +	_renderMenu: function( ul, items ) {
    +		var that = this,
    +			currentOptgroup = "";
    +
    +		$.each( items, function( index, item ) {
    +			var li;
    +
    +			if ( item.optgroup !== currentOptgroup ) {
    +				li = $( "<li>", {
    +					text: item.optgroup
    +				} );
    +				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
    +					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
    +						" ui-state-disabled" :
    +						"" ) );
    +
    +				li.appendTo( ul );
    +
    +				currentOptgroup = item.optgroup;
    +			}
    +
    +			that._renderItemData( ul, item );
    +		} );
    +	},
    +
    +	_renderItemData: function( ul, item ) {
    +		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
    +	},
    +
    +	_renderItem: function( ul, item ) {
    +		var li = $( "<li>" ),
    +			wrapper = $( "<div>", {
    +				title: item.element.attr( "title" )
    +			} );
    +
    +		if ( item.disabled ) {
    +			this._addClass( li, null, "ui-state-disabled" );
    +		}
    +		this._setText( wrapper, item.label );
    +
    +		return li.append( wrapper ).appendTo( ul );
    +	},
    +
    +	_setText: function( element, value ) {
    +		if ( value ) {
    +			element.text( value );
    +		} else {
    +			element.html( "&#160;" );
    +		}
    +	},
    +
    +	_move: function( direction, event ) {
    +		var item, next,
    +			filter = ".ui-menu-item";
    +
    +		if ( this.isOpen ) {
    +			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
    +		} else {
    +			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
    +			filter += ":not(.ui-state-disabled)";
    +		}
    +
    +		if ( direction === "first" || direction === "last" ) {
    +			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
    +		} else {
    +			next = item[ direction + "All" ]( filter ).eq( 0 );
    +		}
    +
    +		if ( next.length ) {
    +			this.menuInstance.focus( event, next );
    +		}
    +	},
    +
    +	_getSelectedItem: function() {
    +		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
    +	},
    +
    +	_toggle: function( event ) {
    +		this[ this.isOpen ? "close" : "open" ]( event );
    +	},
    +
    +	_setSelection: function() {
    +		var selection;
    +
    +		if ( !this.range ) {
    +			return;
    +		}
    +
    +		if ( window.getSelection ) {
    +			selection = window.getSelection();
    +			selection.removeAllRanges();
    +			selection.addRange( this.range );
    +
    +		// Support: IE8
    +		} else {
    +			this.range.select();
    +		}
    +
    +		// Support: IE
    +		// Setting the text selection kills the button focus in IE, but
    +		// restoring the focus doesn't kill the selection.
    +		this.button.focus();
    +	},
    +
    +	_documentClick: {
    +		mousedown: function( event ) {
    +			if ( !this.isOpen ) {
    +				return;
    +			}
    +
    +			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
    +					$.ui.escapeSelector( this.ids.button ) ).length ) {
    +				this.close( event );
    +			}
    +		}
    +	},
    +
    +	_buttonEvents: {
    +
    +		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
    +		mousedown: function() {
    +			var selection;
    +
    +			if ( window.getSelection ) {
    +				selection = window.getSelection();
    +				if ( selection.rangeCount ) {
    +					this.range = selection.getRangeAt( 0 );
    +				}
    +
    +			// Support: IE8
    +			} else {
    +				this.range = document.selection.createRange();
    +			}
    +		},
    +
    +		click: function( event ) {
    +			this._setSelection();
    +			this._toggle( event );
    +		},
    +
    +		keydown: function( event ) {
    +			var preventDefault = true;
    +			switch ( event.keyCode ) {
    +			case $.ui.keyCode.TAB:
    +			case $.ui.keyCode.ESCAPE:
    +				this.close( event );
    +				preventDefault = false;
    +				break;
    +			case $.ui.keyCode.ENTER:
    +				if ( this.isOpen ) {
    +					this._selectFocusedItem( event );
    +				}
    +				break;
    +			case $.ui.keyCode.UP:
    +				if ( event.altKey ) {
    +					this._toggle( event );
    +				} else {
    +					this._move( "prev", event );
    +				}
    +				break;
    +			case $.ui.keyCode.DOWN:
    +				if ( event.altKey ) {
    +					this._toggle( event );
    +				} else {
    +					this._move( "next", event );
    +				}
    +				break;
    +			case $.ui.keyCode.SPACE:
    +				if ( this.isOpen ) {
    +					this._selectFocusedItem( event );
    +				} else {
    +					this._toggle( event );
    +				}
    +				break;
    +			case $.ui.keyCode.LEFT:
    +				this._move( "prev", event );
    +				break;
    +			case $.ui.keyCode.RIGHT:
    +				this._move( "next", event );
    +				break;
    +			case $.ui.keyCode.HOME:
    +			case $.ui.keyCode.PAGE_UP:
    +				this._move( "first", event );
    +				break;
    +			case $.ui.keyCode.END:
    +			case $.ui.keyCode.PAGE_DOWN:
    +				this._move( "last", event );
    +				break;
    +			default:
    +				this.menu.trigger( event );
    +				preventDefault = false;
    +			}
    +
    +			if ( preventDefault ) {
    +				event.preventDefault();
    +			}
    +		}
    +	},
    +
    +	_selectFocusedItem: function( event ) {
    +		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
    +		if ( !item.hasClass( "ui-state-disabled" ) ) {
    +			this._select( item.data( "ui-selectmenu-item" ), event );
    +		}
    +	},
    +
    +	_select: function( item, event ) {
    +		var oldIndex = this.element[ 0 ].selectedIndex;
    +
    +		// Change native select element
    +		this.element[ 0 ].selectedIndex = item.index;
    +		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
    +		this._setAria( item );
    +		this._trigger( "select", event, { item: item } );
    +
    +		if ( item.index !== oldIndex ) {
    +			this._trigger( "change", event, { item: item } );
    +		}
    +
    +		this.close( event );
    +	},
    +
    +	_setAria: function( item ) {
    +		var id = this.menuItems.eq( item.index ).attr( "id" );
    +
    +		this.button.attr( {
    +			"aria-labelledby": id,
    +			"aria-activedescendant": id
    +		} );
    +		this.menu.attr( "aria-activedescendant", id );
    +	},
    +
    +	_setOption: function( key, value ) {
    +		if ( key === "icons" ) {
    +			var icon = this.button.find( "span.ui-icon" );
    +			this._removeClass( icon, null, this.options.icons.button )
    +				._addClass( icon, null, value.button );
    +		}
    +
    +		this._super( key, value );
    +
    +		if ( key === "appendTo" ) {
    +			this.menuWrap.appendTo( this._appendTo() );
    +		}
    +
    +		if ( key === "width" ) {
    +			this._resizeButton();
    +		}
    +	},
    +
    +	_setOptionDisabled: function( value ) {
    +		this._super( value );
    +
    +		this.menuInstance.option( "disabled", value );
    +		this.button.attr( "aria-disabled", value );
    +		this._toggleClass( this.button, null, "ui-state-disabled", value );
    +
    +		this.element.prop( "disabled", value );
    +		if ( value ) {
    +			this.button.attr( "tabindex", -1 );
    +			this.close();
    +		} else {
    +			this.button.attr( "tabindex", 0 );
    +		}
    +	},
    +
    +	_appendTo: function() {
    +		var element = this.options.appendTo;
    +
    +		if ( element ) {
    +			element = element.jquery || element.nodeType ?
    +				$( element ) :
    +				this.document.find( element ).eq( 0 );
    +		}
    +
    +		if ( !element || !element[ 0 ] ) {
    +			element = this.element.closest( ".ui-front, dialog" );
    +		}
    +
    +		if ( !element.length ) {
    +			element = this.document[ 0 ].body;
    +		}
    +
    +		return element;
    +	},
    +
    +	_toggleAttr: function() {
    +		this.button.attr( "aria-expanded", this.isOpen );
    +
    +		// We can't use two _toggleClass() calls here, because we need to make sure
    +		// we always remove classes first and add them second, otherwise if both classes have the
    +		// same theme class, it will be removed after we add it.
    +		this._removeClass( this.button, "ui-selectmenu-button-" +
    +			( this.isOpen ? "closed" : "open" ) )
    +			._addClass( this.button, "ui-selectmenu-button-" +
    +				( this.isOpen ? "open" : "closed" ) )
    +			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
    +
    +		this.menu.attr( "aria-hidden", !this.isOpen );
    +	},
    +
    +	_resizeButton: function() {
    +		var width = this.options.width;
    +
    +		// For `width: false`, just remove inline style and stop
    +		if ( width === false ) {
    +			this.button.css( "width", "" );
    +			return;
    +		}
    +
    +		// For `width: null`, match the width of the original element
    +		if ( width === null ) {
    +			width = this.element.show().outerWidth();
    +			this.element.hide();
    +		}
    +
    +		this.button.outerWidth( width );
    +	},
    +
    +	_resizeMenu: function() {
    +		this.menu.outerWidth( Math.max(
    +			this.button.outerWidth(),
    +
    +			// Support: IE10
    +			// IE10 wraps long text (possibly a rounding bug)
    +			// so we add 1px to avoid the wrapping
    +			this.menu.width( "" ).outerWidth() + 1
    +		) );
    +	},
    +
    +	_getCreateOptions: function() {
    +		var options = this._super();
    +
    +		options.disabled = this.element.prop( "disabled" );
    +
    +		return options;
    +	},
    +
    +	_parseOptions: function( options ) {
    +		var that = this,
    +			data = [];
    +		options.each( function( index, item ) {
    +			data.push( that._parseOption( $( item ), index ) );
    +		} );
    +		this.items = data;
    +	},
    +
    +	_parseOption: function( option, index ) {
    +		var optgroup = option.parent( "optgroup" );
    +
    +		return {
    +			element: option,
    +			index: index,
    +			value: option.val(),
    +			label: option.text(),
    +			optgroup: optgroup.attr( "label" ) || "",
    +			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
    +		};
    +	},
    +
    +	_destroy: function() {
    +		this._unbindFormResetHandler();
    +		this.menuWrap.remove();
    +		this.button.remove();
    +		this.element.show();
    +		this.element.removeUniqueId();
    +		this.labels.attr( "for", this.ids.element );
    +	}
    +} ] );
    +
    +
    +/*!
    + * jQuery UI Slider 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Slider
    +//>>group: Widgets
    +//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
    +//>>docs: http://api.jqueryui.com/slider/
    +//>>demos: http://jqueryui.com/slider/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/slider.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
    +	version: "1.12.1",
    +	widgetEventPrefix: "slide",
    +
    +	options: {
    +		animate: false,
    +		classes: {
    +			"ui-slider": "ui-corner-all",
    +			"ui-slider-handle": "ui-corner-all",
    +
    +			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
    +			// element, but worked best visually with a variety of themes
    +			"ui-slider-range": "ui-corner-all ui-widget-header"
    +		},
    +		distance: 0,
    +		max: 100,
    +		min: 0,
    +		orientation: "horizontal",
    +		range: false,
    +		step: 1,
    +		value: 0,
    +		values: null,
    +
    +		// Callbacks
    +		change: null,
    +		slide: null,
    +		start: null,
    +		stop: null
    +	},
    +
    +	// Number of pages in a slider
    +	// (how many times can you page up/down to go through the whole range)
    +	numPages: 5,
    +
    +	_create: function() {
    +		this._keySliding = false;
    +		this._mouseSliding = false;
    +		this._animateOff = true;
    +		this._handleIndex = null;
    +		this._detectOrientation();
    +		this._mouseInit();
    +		this._calculateNewMax();
    +
    +		this._addClass( "ui-slider ui-slider-" + this.orientation,
    +			"ui-widget ui-widget-content" );
    +
    +		this._refresh();
    +
    +		this._animateOff = false;
    +	},
    +
    +	_refresh: function() {
    +		this._createRange();
    +		this._createHandles();
    +		this._setupEvents();
    +		this._refreshValue();
    +	},
    +
    +	_createHandles: function() {
    +		var i, handleCount,
    +			options = this.options,
    +			existingHandles = this.element.find( ".ui-slider-handle" ),
    +			handle = "<span tabindex='0'></span>",
    +			handles = [];
    +
    +		handleCount = ( options.values && options.values.length ) || 1;
    +
    +		if ( existingHandles.length > handleCount ) {
    +			existingHandles.slice( handleCount ).remove();
    +			existingHandles = existingHandles.slice( 0, handleCount );
    +		}
    +
    +		for ( i = existingHandles.length; i < handleCount; i++ ) {
    +			handles.push( handle );
    +		}
    +
    +		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
    +
    +		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
    +
    +		this.handle = this.handles.eq( 0 );
    +
    +		this.handles.each( function( i ) {
    +			$( this )
    +				.data( "ui-slider-handle-index", i )
    +				.attr( "tabIndex", 0 );
    +		} );
    +	},
    +
    +	_createRange: function() {
    +		var options = this.options;
    +
    +		if ( options.range ) {
    +			if ( options.range === true ) {
    +				if ( !options.values ) {
    +					options.values = [ this._valueMin(), this._valueMin() ];
    +				} else if ( options.values.length && options.values.length !== 2 ) {
    +					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
    +				} else if ( $.isArray( options.values ) ) {
    +					options.values = options.values.slice( 0 );
    +				}
    +			}
    +
    +			if ( !this.range || !this.range.length ) {
    +				this.range = $( "<div>" )
    +					.appendTo( this.element );
    +
    +				this._addClass( this.range, "ui-slider-range" );
    +			} else {
    +				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
    +
    +				// Handle range switching from true to min/max
    +				this.range.css( {
    +					"left": "",
    +					"bottom": ""
    +				} );
    +			}
    +			if ( options.range === "min" || options.range === "max" ) {
    +				this._addClass( this.range, "ui-slider-range-" + options.range );
    +			}
    +		} else {
    +			if ( this.range ) {
    +				this.range.remove();
    +			}
    +			this.range = null;
    +		}
    +	},
    +
    +	_setupEvents: function() {
    +		this._off( this.handles );
    +		this._on( this.handles, this._handleEvents );
    +		this._hoverable( this.handles );
    +		this._focusable( this.handles );
    +	},
    +
    +	_destroy: function() {
    +		this.handles.remove();
    +		if ( this.range ) {
    +			this.range.remove();
    +		}
    +
    +		this._mouseDestroy();
    +	},
    +
    +	_mouseCapture: function( event ) {
    +		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
    +			that = this,
    +			o = this.options;
    +
    +		if ( o.disabled ) {
    +			return false;
    +		}
    +
    +		this.elementSize = {
    +			width: this.element.outerWidth(),
    +			height: this.element.outerHeight()
    +		};
    +		this.elementOffset = this.element.offset();
    +
    +		position = { x: event.pageX, y: event.pageY };
    +		normValue = this._normValueFromMouse( position );
    +		distance = this._valueMax() - this._valueMin() + 1;
    +		this.handles.each( function( i ) {
    +			var thisDistance = Math.abs( normValue - that.values( i ) );
    +			if ( ( distance > thisDistance ) ||
    +				( distance === thisDistance &&
    +					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
    +				distance = thisDistance;
    +				closestHandle = $( this );
    +				index = i;
    +			}
    +		} );
    +
    +		allowed = this._start( event, index );
    +		if ( allowed === false ) {
    +			return false;
    +		}
    +		this._mouseSliding = true;
    +
    +		this._handleIndex = index;
    +
    +		this._addClass( closestHandle, null, "ui-state-active" );
    +		closestHandle.trigger( "focus" );
    +
    +		offset = closestHandle.offset();
    +		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
    +		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
    +			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
    +			top: event.pageY - offset.top -
    +				( closestHandle.height() / 2 ) -
    +				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
    +				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
    +				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
    +		};
    +
    +		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
    +			this._slide( event, index, normValue );
    +		}
    +		this._animateOff = true;
    +		return true;
    +	},
    +
    +	_mouseStart: function() {
    +		return true;
    +	},
    +
    +	_mouseDrag: function( event ) {
    +		var position = { x: event.pageX, y: event.pageY },
    +			normValue = this._normValueFromMouse( position );
    +
    +		this._slide( event, this._handleIndex, normValue );
    +
    +		return false;
    +	},
    +
    +	_mouseStop: function( event ) {
    +		this._removeClass( this.handles, null, "ui-state-active" );
    +		this._mouseSliding = false;
    +
    +		this._stop( event, this._handleIndex );
    +		this._change( event, this._handleIndex );
    +
    +		this._handleIndex = null;
    +		this._clickOffset = null;
    +		this._animateOff = false;
    +
    +		return false;
    +	},
    +
    +	_detectOrientation: function() {
    +		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
    +	},
    +
    +	_normValueFromMouse: function( position ) {
    +		var pixelTotal,
    +			pixelMouse,
    +			percentMouse,
    +			valueTotal,
    +			valueMouse;
    +
    +		if ( this.orientation === "horizontal" ) {
    +			pixelTotal = this.elementSize.width;
    +			pixelMouse = position.x - this.elementOffset.left -
    +				( this._clickOffset ? this._clickOffset.left : 0 );
    +		} else {
    +			pixelTotal = this.elementSize.height;
    +			pixelMouse = position.y - this.elementOffset.top -
    +				( this._clickOffset ? this._clickOffset.top : 0 );
    +		}
    +
    +		percentMouse = ( pixelMouse / pixelTotal );
    +		if ( percentMouse > 1 ) {
    +			percentMouse = 1;
    +		}
    +		if ( percentMouse < 0 ) {
    +			percentMouse = 0;
    +		}
    +		if ( this.orientation === "vertical" ) {
    +			percentMouse = 1 - percentMouse;
    +		}
    +
    +		valueTotal = this._valueMax() - this._valueMin();
    +		valueMouse = this._valueMin() + percentMouse * valueTotal;
    +
    +		return this._trimAlignValue( valueMouse );
    +	},
    +
    +	_uiHash: function( index, value, values ) {
    +		var uiHash = {
    +			handle: this.handles[ index ],
    +			handleIndex: index,
    +			value: value !== undefined ? value : this.value()
    +		};
    +
    +		if ( this._hasMultipleValues() ) {
    +			uiHash.value = value !== undefined ? value : this.values( index );
    +			uiHash.values = values || this.values();
    +		}
    +
    +		return uiHash;
    +	},
    +
    +	_hasMultipleValues: function() {
    +		return this.options.values && this.options.values.length;
    +	},
    +
    +	_start: function( event, index ) {
    +		return this._trigger( "start", event, this._uiHash( index ) );
    +	},
    +
    +	_slide: function( event, index, newVal ) {
    +		var allowed, otherVal,
    +			currentValue = this.value(),
    +			newValues = this.values();
    +
    +		if ( this._hasMultipleValues() ) {
    +			otherVal = this.values( index ? 0 : 1 );
    +			currentValue = this.values( index );
    +
    +			if ( this.options.values.length === 2 && this.options.range === true ) {
    +				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
    +			}
    +
    +			newValues[ index ] = newVal;
    +		}
    +
    +		if ( newVal === currentValue ) {
    +			return;
    +		}
    +
    +		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
    +
    +		// A slide can be canceled by returning false from the slide callback
    +		if ( allowed === false ) {
    +			return;
    +		}
    +
    +		if ( this._hasMultipleValues() ) {
    +			this.values( index, newVal );
    +		} else {
    +			this.value( newVal );
    +		}
    +	},
    +
    +	_stop: function( event, index ) {
    +		this._trigger( "stop", event, this._uiHash( index ) );
    +	},
    +
    +	_change: function( event, index ) {
    +		if ( !this._keySliding && !this._mouseSliding ) {
    +
    +			//store the last changed value index for reference when handles overlap
    +			this._lastChangedValue = index;
    +			this._trigger( "change", event, this._uiHash( index ) );
    +		}
    +	},
    +
    +	value: function( newValue ) {
    +		if ( arguments.length ) {
    +			this.options.value = this._trimAlignValue( newValue );
    +			this._refreshValue();
    +			this._change( null, 0 );
    +			return;
    +		}
    +
    +		return this._value();
    +	},
    +
    +	values: function( index, newValue ) {
    +		var vals,
    +			newValues,
    +			i;
    +
    +		if ( arguments.length > 1 ) {
    +			this.options.values[ index ] = this._trimAlignValue( newValue );
    +			this._refreshValue();
    +			this._change( null, index );
    +			return;
    +		}
    +
    +		if ( arguments.length ) {
    +			if ( $.isArray( arguments[ 0 ] ) ) {
    +				vals = this.options.values;
    +				newValues = arguments[ 0 ];
    +				for ( i = 0; i < vals.length; i += 1 ) {
    +					vals[ i ] = this._trimAlignValue( newValues[ i ] );
    +					this._change( null, i );
    +				}
    +				this._refreshValue();
    +			} else {
    +				if ( this._hasMultipleValues() ) {
    +					return this._values( index );
    +				} else {
    +					return this.value();
    +				}
    +			}
    +		} else {
    +			return this._values();
    +		}
    +	},
    +
    +	_setOption: function( key, value ) {
    +		var i,
    +			valsLength = 0;
    +
    +		if ( key === "range" && this.options.range === true ) {
    +			if ( value === "min" ) {
    +				this.options.value = this._values( 0 );
    +				this.options.values = null;
    +			} else if ( value === "max" ) {
    +				this.options.value = this._values( this.options.values.length - 1 );
    +				this.options.values = null;
    +			}
    +		}
    +
    +		if ( $.isArray( this.options.values ) ) {
    +			valsLength = this.options.values.length;
    +		}
    +
    +		this._super( key, value );
    +
    +		switch ( key ) {
    +			case "orientation":
    +				this._detectOrientation();
    +				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
    +					._addClass( "ui-slider-" + this.orientation );
    +				this._refreshValue();
    +				if ( this.options.range ) {
    +					this._refreshRange( value );
    +				}
    +
    +				// Reset positioning from previous orientation
    +				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
    +				break;
    +			case "value":
    +				this._animateOff = true;
    +				this._refreshValue();
    +				this._change( null, 0 );
    +				this._animateOff = false;
    +				break;
    +			case "values":
    +				this._animateOff = true;
    +				this._refreshValue();
    +
    +				// Start from the last handle to prevent unreachable handles (#9046)
    +				for ( i = valsLength - 1; i >= 0; i-- ) {
    +					this._change( null, i );
    +				}
    +				this._animateOff = false;
    +				break;
    +			case "step":
    +			case "min":
    +			case "max":
    +				this._animateOff = true;
    +				this._calculateNewMax();
    +				this._refreshValue();
    +				this._animateOff = false;
    +				break;
    +			case "range":
    +				this._animateOff = true;
    +				this._refresh();
    +				this._animateOff = false;
    +				break;
    +		}
    +	},
    +
    +	_setOptionDisabled: function( value ) {
    +		this._super( value );
    +
    +		this._toggleClass( null, "ui-state-disabled", !!value );
    +	},
    +
    +	//internal value getter
    +	// _value() returns value trimmed by min and max, aligned by step
    +	_value: function() {
    +		var val = this.options.value;
    +		val = this._trimAlignValue( val );
    +
    +		return val;
    +	},
    +
    +	//internal values getter
    +	// _values() returns array of values trimmed by min and max, aligned by step
    +	// _values( index ) returns single value trimmed by min and max, aligned by step
    +	_values: function( index ) {
    +		var val,
    +			vals,
    +			i;
    +
    +		if ( arguments.length ) {
    +			val = this.options.values[ index ];
    +			val = this._trimAlignValue( val );
    +
    +			return val;
    +		} else if ( this._hasMultipleValues() ) {
    +
    +			// .slice() creates a copy of the array
    +			// this copy gets trimmed by min and max and then returned
    +			vals = this.options.values.slice();
    +			for ( i = 0; i < vals.length; i += 1 ) {
    +				vals[ i ] = this._trimAlignValue( vals[ i ] );
    +			}
    +
    +			return vals;
    +		} else {
    +			return [];
    +		}
    +	},
    +
    +	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
    +	_trimAlignValue: function( val ) {
    +		if ( val <= this._valueMin() ) {
    +			return this._valueMin();
    +		}
    +		if ( val >= this._valueMax() ) {
    +			return this._valueMax();
    +		}
    +		var step = ( this.options.step > 0 ) ? this.options.step : 1,
    +			valModStep = ( val - this._valueMin() ) % step,
    +			alignValue = val - valModStep;
    +
    +		if ( Math.abs( valModStep ) * 2 >= step ) {
    +			alignValue += ( valModStep > 0 ) ? step : ( -step );
    +		}
    +
    +		// Since JavaScript has problems with large floats, round
    +		// the final value to 5 digits after the decimal point (see #4124)
    +		return parseFloat( alignValue.toFixed( 5 ) );
    +	},
    +
    +	_calculateNewMax: function() {
    +		var max = this.options.max,
    +			min = this._valueMin(),
    +			step = this.options.step,
    +			aboveMin = Math.round( ( max - min ) / step ) * step;
    +		max = aboveMin + min;
    +		if ( max > this.options.max ) {
    +
    +			//If max is not divisible by step, rounding off may increase its value
    +			max -= step;
    +		}
    +		this.max = parseFloat( max.toFixed( this._precision() ) );
    +	},
    +
    +	_precision: function() {
    +		var precision = this._precisionOf( this.options.step );
    +		if ( this.options.min !== null ) {
    +			precision = Math.max( precision, this._precisionOf( this.options.min ) );
    +		}
    +		return precision;
    +	},
    +
    +	_precisionOf: function( num ) {
    +		var str = num.toString(),
    +			decimal = str.indexOf( "." );
    +		return decimal === -1 ? 0 : str.length - decimal - 1;
    +	},
    +
    +	_valueMin: function() {
    +		return this.options.min;
    +	},
    +
    +	_valueMax: function() {
    +		return this.max;
    +	},
    +
    +	_refreshRange: function( orientation ) {
    +		if ( orientation === "vertical" ) {
    +			this.range.css( { "width": "", "left": "" } );
    +		}
    +		if ( orientation === "horizontal" ) {
    +			this.range.css( { "height": "", "bottom": "" } );
    +		}
    +	},
    +
    +	_refreshValue: function() {
    +		var lastValPercent, valPercent, value, valueMin, valueMax,
    +			oRange = this.options.range,
    +			o = this.options,
    +			that = this,
    +			animate = ( !this._animateOff ) ? o.animate : false,
    +			_set = {};
    +
    +		if ( this._hasMultipleValues() ) {
    +			this.handles.each( function( i ) {
    +				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
    +					that._valueMin() ) * 100;
    +				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
    +				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
    +				if ( that.options.range === true ) {
    +					if ( that.orientation === "horizontal" ) {
    +						if ( i === 0 ) {
    +							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
    +								left: valPercent + "%"
    +							}, o.animate );
    +						}
    +						if ( i === 1 ) {
    +							that.range[ animate ? "animate" : "css" ]( {
    +								width: ( valPercent - lastValPercent ) + "%"
    +							}, {
    +								queue: false,
    +								duration: o.animate
    +							} );
    +						}
    +					} else {
    +						if ( i === 0 ) {
    +							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
    +								bottom: ( valPercent ) + "%"
    +							}, o.animate );
    +						}
    +						if ( i === 1 ) {
    +							that.range[ animate ? "animate" : "css" ]( {
    +								height: ( valPercent - lastValPercent ) + "%"
    +							}, {
    +								queue: false,
    +								duration: o.animate
    +							} );
    +						}
    +					}
    +				}
    +				lastValPercent = valPercent;
    +			} );
    +		} else {
    +			value = this.value();
    +			valueMin = this._valueMin();
    +			valueMax = this._valueMax();
    +			valPercent = ( valueMax !== valueMin ) ?
    +					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
    +					0;
    +			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
    +			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
    +
    +			if ( oRange === "min" && this.orientation === "horizontal" ) {
    +				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
    +					width: valPercent + "%"
    +				}, o.animate );
    +			}
    +			if ( oRange === "max" && this.orientation === "horizontal" ) {
    +				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
    +					width: ( 100 - valPercent ) + "%"
    +				}, o.animate );
    +			}
    +			if ( oRange === "min" && this.orientation === "vertical" ) {
    +				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
    +					height: valPercent + "%"
    +				}, o.animate );
    +			}
    +			if ( oRange === "max" && this.orientation === "vertical" ) {
    +				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
    +					height: ( 100 - valPercent ) + "%"
    +				}, o.animate );
    +			}
    +		}
    +	},
    +
    +	_handleEvents: {
    +		keydown: function( event ) {
    +			var allowed, curVal, newVal, step,
    +				index = $( event.target ).data( "ui-slider-handle-index" );
    +
    +			switch ( event.keyCode ) {
    +				case $.ui.keyCode.HOME:
    +				case $.ui.keyCode.END:
    +				case $.ui.keyCode.PAGE_UP:
    +				case $.ui.keyCode.PAGE_DOWN:
    +				case $.ui.keyCode.UP:
    +				case $.ui.keyCode.RIGHT:
    +				case $.ui.keyCode.DOWN:
    +				case $.ui.keyCode.LEFT:
    +					event.preventDefault();
    +					if ( !this._keySliding ) {
    +						this._keySliding = true;
    +						this._addClass( $( event.target ), null, "ui-state-active" );
    +						allowed = this._start( event, index );
    +						if ( allowed === false ) {
    +							return;
    +						}
    +					}
    +					break;
    +			}
    +
    +			step = this.options.step;
    +			if ( this._hasMultipleValues() ) {
    +				curVal = newVal = this.values( index );
    +			} else {
    +				curVal = newVal = this.value();
    +			}
    +
    +			switch ( event.keyCode ) {
    +				case $.ui.keyCode.HOME:
    +					newVal = this._valueMin();
    +					break;
    +				case $.ui.keyCode.END:
    +					newVal = this._valueMax();
    +					break;
    +				case $.ui.keyCode.PAGE_UP:
    +					newVal = this._trimAlignValue(
    +						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
    +					);
    +					break;
    +				case $.ui.keyCode.PAGE_DOWN:
    +					newVal = this._trimAlignValue(
    +						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
    +					break;
    +				case $.ui.keyCode.UP:
    +				case $.ui.keyCode.RIGHT:
    +					if ( curVal === this._valueMax() ) {
    +						return;
    +					}
    +					newVal = this._trimAlignValue( curVal + step );
    +					break;
    +				case $.ui.keyCode.DOWN:
    +				case $.ui.keyCode.LEFT:
    +					if ( curVal === this._valueMin() ) {
    +						return;
    +					}
    +					newVal = this._trimAlignValue( curVal - step );
    +					break;
    +			}
    +
    +			this._slide( event, index, newVal );
    +		},
    +		keyup: function( event ) {
    +			var index = $( event.target ).data( "ui-slider-handle-index" );
    +
    +			if ( this._keySliding ) {
    +				this._keySliding = false;
    +				this._stop( event, index );
    +				this._change( event, index );
    +				this._removeClass( $( event.target ), null, "ui-state-active" );
    +			}
    +		}
    +	}
    +} );
    +
    +
    +/*!
    + * jQuery UI Sortable 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Sortable
    +//>>group: Interactions
    +//>>description: Enables items in a list to be sorted using the mouse.
    +//>>docs: http://api.jqueryui.com/sortable/
    +//>>demos: http://jqueryui.com/sortable/
    +//>>css.structure: ../../themes/base/sortable.css
    +
    +
    +
    +var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
    +	version: "1.12.1",
    +	widgetEventPrefix: "sort",
    +	ready: false,
    +	options: {
    +		appendTo: "parent",
    +		axis: false,
    +		connectWith: false,
    +		containment: false,
    +		cursor: "auto",
    +		cursorAt: false,
    +		dropOnEmpty: true,
    +		forcePlaceholderSize: false,
    +		forceHelperSize: false,
    +		grid: false,
    +		handle: false,
    +		helper: "original",
    +		items: "> *",
    +		opacity: false,
    +		placeholder: false,
    +		revert: false,
    +		scroll: true,
    +		scrollSensitivity: 20,
    +		scrollSpeed: 20,
    +		scope: "default",
    +		tolerance: "intersect",
    +		zIndex: 1000,
    +
    +		// Callbacks
    +		activate: null,
    +		beforeStop: null,
    +		change: null,
    +		deactivate: null,
    +		out: null,
    +		over: null,
    +		receive: null,
    +		remove: null,
    +		sort: null,
    +		start: null,
    +		stop: null,
    +		update: null
    +	},
    +
    +	_isOverAxis: function( x, reference, size ) {
    +		return ( x >= reference ) && ( x < ( reference + size ) );
    +	},
    +
    +	_isFloating: function( item ) {
    +		return ( /left|right/ ).test( item.css( "float" ) ) ||
    +			( /inline|table-cell/ ).test( item.css( "display" ) );
    +	},
    +
    +	_create: function() {
    +		this.containerCache = {};
    +		this._addClass( "ui-sortable" );
    +
    +		//Get the items
    +		this.refresh();
    +
    +		//Let's determine the parent's offset
    +		this.offset = this.element.offset();
    +
    +		//Initialize mouse events for interaction
    +		this._mouseInit();
    +
    +		this._setHandleClassName();
    +
    +		//We're ready to go
    +		this.ready = true;
    +
    +	},
    +
    +	_setOption: function( key, value ) {
    +		this._super( key, value );
    +
    +		if ( key === "handle" ) {
    +			this._setHandleClassName();
    +		}
    +	},
    +
    +	_setHandleClassName: function() {
    +		var that = this;
    +		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
    +		$.each( this.items, function() {
    +			that._addClass(
    +				this.instance.options.handle ?
    +					this.item.find( this.instance.options.handle ) :
    +					this.item,
    +				"ui-sortable-handle"
    +			);
    +		} );
    +	},
    +
    +	_destroy: function() {
    +		this._mouseDestroy();
    +
    +		for ( var i = this.items.length - 1; i >= 0; i-- ) {
    +			this.items[ i ].item.removeData( this.widgetName + "-item" );
    +		}
    +
    +		return this;
    +	},
    +
    +	_mouseCapture: function( event, overrideHandle ) {
    +		var currentItem = null,
    +			validHandle = false,
    +			that = this;
    +
    +		if ( this.reverting ) {
    +			return false;
    +		}
    +
    +		if ( this.options.disabled || this.options.type === "static" ) {
    +			return false;
    +		}
    +
    +		//We have to refresh the items data once first
    +		this._refreshItems( event );
    +
    +		//Find out if the clicked node (or one of its parents) is a actual item in this.items
    +		$( event.target ).parents().each( function() {
    +			if ( $.data( this, that.widgetName + "-item" ) === that ) {
    +				currentItem = $( this );
    +				return false;
    +			}
    +		} );
    +		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
    +			currentItem = $( event.target );
    +		}
    +
    +		if ( !currentItem ) {
    +			return false;
    +		}
    +		if ( this.options.handle && !overrideHandle ) {
    +			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
    +				if ( this === event.target ) {
    +					validHandle = true;
    +				}
    +			} );
    +			if ( !validHandle ) {
    +				return false;
    +			}
    +		}
    +
    +		this.currentItem = currentItem;
    +		this._removeCurrentsFromItems();
    +		return true;
    +
    +	},
    +
    +	_mouseStart: function( event, overrideHandle, noActivation ) {
    +
    +		var i, body,
    +			o = this.options;
    +
    +		this.currentContainer = this;
    +
    +		//We only need to call refreshPositions, because the refreshItems call has been moved to
    +		// mouseCapture
    +		this.refreshPositions();
    +
    +		//Create and append the visible helper
    +		this.helper = this._createHelper( event );
    +
    +		//Cache the helper size
    +		this._cacheHelperProportions();
    +
    +		/*
    +		 * - Position generation -
    +		 * This block generates everything position related - it's the core of draggables.
    +		 */
    +
    +		//Cache the margins of the original element
    +		this._cacheMargins();
    +
    +		//Get the next scrolling parent
    +		this.scrollParent = this.helper.scrollParent();
    +
    +		//The element's absolute position on the page minus margins
    +		this.offset = this.currentItem.offset();
    +		this.offset = {
    +			top: this.offset.top - this.margins.top,
    +			left: this.offset.left - this.margins.left
    +		};
    +
    +		$.extend( this.offset, {
    +			click: { //Where the click happened, relative to the element
    +				left: event.pageX - this.offset.left,
    +				top: event.pageY - this.offset.top
    +			},
    +			parent: this._getParentOffset(),
    +
    +			// This is a relative to absolute position minus the actual position calculation -
    +			// only used for relative positioned helper
    +			relative: this._getRelativeOffset()
    +		} );
    +
    +		// Only after we got the offset, we can change the helper's position to absolute
    +		// TODO: Still need to figure out a way to make relative sorting possible
    +		this.helper.css( "position", "absolute" );
    +		this.cssPosition = this.helper.css( "position" );
    +
    +		//Generate the original position
    +		this.originalPosition = this._generatePosition( event );
    +		this.originalPageX = event.pageX;
    +		this.originalPageY = event.pageY;
    +
    +		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
    +		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
    +
    +		//Cache the former DOM position
    +		this.domPosition = {
    +			prev: this.currentItem.prev()[ 0 ],
    +			parent: this.currentItem.parent()[ 0 ]
    +		};
    +
    +		// If the helper is not the original, hide the original so it's not playing any role during
    +		// the drag, won't cause anything bad this way
    +		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
    +			this.currentItem.hide();
    +		}
    +
    +		//Create the placeholder
    +		this._createPlaceholder();
    +
    +		//Set a containment if given in the options
    +		if ( o.containment ) {
    +			this._setContainment();
    +		}
    +
    +		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
    +			body = this.document.find( "body" );
    +
    +			// Support: IE
    +			this.storedCursor = body.css( "cursor" );
    +			body.css( "cursor", o.cursor );
    +
    +			this.storedStylesheet =
    +				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
    +		}
    +
    +		if ( o.opacity ) { // opacity option
    +			if ( this.helper.css( "opacity" ) ) {
    +				this._storedOpacity = this.helper.css( "opacity" );
    +			}
    +			this.helper.css( "opacity", o.opacity );
    +		}
    +
    +		if ( o.zIndex ) { // zIndex option
    +			if ( this.helper.css( "zIndex" ) ) {
    +				this._storedZIndex = this.helper.css( "zIndex" );
    +			}
    +			this.helper.css( "zIndex", o.zIndex );
    +		}
    +
    +		//Prepare scrolling
    +		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
    +				this.scrollParent[ 0 ].tagName !== "HTML" ) {
    +			this.overflowOffset = this.scrollParent.offset();
    +		}
    +
    +		//Call callbacks
    +		this._trigger( "start", event, this._uiHash() );
    +
    +		//Recache the helper size
    +		if ( !this._preserveHelperProportions ) {
    +			this._cacheHelperProportions();
    +		}
    +
    +		//Post "activate" events to possible containers
    +		if ( !noActivation ) {
    +			for ( i = this.containers.length - 1; i >= 0; i-- ) {
    +				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
    +			}
    +		}
    +
    +		//Prepare possible droppables
    +		if ( $.ui.ddmanager ) {
    +			$.ui.ddmanager.current = this;
    +		}
    +
    +		if ( $.ui.ddmanager && !o.dropBehaviour ) {
    +			$.ui.ddmanager.prepareOffsets( this, event );
    +		}
    +
    +		this.dragging = true;
    +
    +		this._addClass( this.helper, "ui-sortable-helper" );
    +
    +		// Execute the drag once - this causes the helper not to be visiblebefore getting its
    +		// correct position
    +		this._mouseDrag( event );
    +		return true;
    +
    +	},
    +
    +	_mouseDrag: function( event ) {
    +		var i, item, itemElement, intersection,
    +			o = this.options,
    +			scrolled = false;
    +
    +		//Compute the helpers position
    +		this.position = this._generatePosition( event );
    +		this.positionAbs = this._convertPositionTo( "absolute" );
    +
    +		if ( !this.lastPositionAbs ) {
    +			this.lastPositionAbs = this.positionAbs;
    +		}
    +
    +		//Do scrolling
    +		if ( this.options.scroll ) {
    +			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
    +					this.scrollParent[ 0 ].tagName !== "HTML" ) {
    +
    +				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
    +						event.pageY < o.scrollSensitivity ) {
    +					this.scrollParent[ 0 ].scrollTop =
    +						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
    +				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
    +					this.scrollParent[ 0 ].scrollTop =
    +						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
    +				}
    +
    +				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
    +						event.pageX < o.scrollSensitivity ) {
    +					this.scrollParent[ 0 ].scrollLeft = scrolled =
    +						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
    +				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
    +					this.scrollParent[ 0 ].scrollLeft = scrolled =
    +						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
    +				}
    +
    +			} else {
    +
    +				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
    +					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
    +				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
    +						o.scrollSensitivity ) {
    +					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
    +				}
    +
    +				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
    +					scrolled = this.document.scrollLeft(
    +						this.document.scrollLeft() - o.scrollSpeed
    +					);
    +				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
    +						o.scrollSensitivity ) {
    +					scrolled = this.document.scrollLeft(
    +						this.document.scrollLeft() + o.scrollSpeed
    +					);
    +				}
    +
    +			}
    +
    +			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
    +				$.ui.ddmanager.prepareOffsets( this, event );
    +			}
    +		}
    +
    +		//Regenerate the absolute position used for position checks
    +		this.positionAbs = this._convertPositionTo( "absolute" );
    +
    +		//Set the helper position
    +		if ( !this.options.axis || this.options.axis !== "y" ) {
    +			this.helper[ 0 ].style.left = this.position.left + "px";
    +		}
    +		if ( !this.options.axis || this.options.axis !== "x" ) {
    +			this.helper[ 0 ].style.top = this.position.top + "px";
    +		}
    +
    +		//Rearrange
    +		for ( i = this.items.length - 1; i >= 0; i-- ) {
    +
    +			//Cache variables and intersection, continue if no intersection
    +			item = this.items[ i ];
    +			itemElement = item.item[ 0 ];
    +			intersection = this._intersectsWithPointer( item );
    +			if ( !intersection ) {
    +				continue;
    +			}
    +
    +			// Only put the placeholder inside the current Container, skip all
    +			// items from other containers. This works because when moving
    +			// an item from one container to another the
    +			// currentContainer is switched before the placeholder is moved.
    +			//
    +			// Without this, moving items in "sub-sortables" can cause
    +			// the placeholder to jitter between the outer and inner container.
    +			if ( item.instance !== this.currentContainer ) {
    +				continue;
    +			}
    +
    +			// Cannot intersect with itself
    +			// no useless actions that have been done before
    +			// no action if the item moved is the parent of the item checked
    +			if ( itemElement !== this.currentItem[ 0 ] &&
    +				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
    +				!$.contains( this.placeholder[ 0 ], itemElement ) &&
    +				( this.options.type === "semi-dynamic" ?
    +					!$.contains( this.element[ 0 ], itemElement ) :
    +					true
    +				)
    +			) {
    +
    +				this.direction = intersection === 1 ? "down" : "up";
    +
    +				if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
    +					this._rearrange( event, item );
    +				} else {
    +					break;
    +				}
    +
    +				this._trigger( "change", event, this._uiHash() );
    +				break;
    +			}
    +		}
    +
    +		//Post events to containers
    +		this._contactContainers( event );
    +
    +		//Interconnect with droppables
    +		if ( $.ui.ddmanager ) {
    +			$.ui.ddmanager.drag( this, event );
    +		}
    +
    +		//Call callbacks
    +		this._trigger( "sort", event, this._uiHash() );
    +
    +		this.lastPositionAbs = this.positionAbs;
    +		return false;
    +
    +	},
    +
    +	_mouseStop: function( event, noPropagation ) {
    +
    +		if ( !event ) {
    +			return;
    +		}
    +
    +		//If we are using droppables, inform the manager about the drop
    +		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
    +			$.ui.ddmanager.drop( this, event );
    +		}
    +
    +		if ( this.options.revert ) {
    +			var that = this,
    +				cur = this.placeholder.offset(),
    +				axis = this.options.axis,
    +				animation = {};
    +
    +			if ( !axis || axis === "x" ) {
    +				animation.left = cur.left - this.offset.parent.left - this.margins.left +
    +					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
    +						0 :
    +						this.offsetParent[ 0 ].scrollLeft
    +					);
    +			}
    +			if ( !axis || axis === "y" ) {
    +				animation.top = cur.top - this.offset.parent.top - this.margins.top +
    +					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
    +						0 :
    +						this.offsetParent[ 0 ].scrollTop
    +					);
    +			}
    +			this.reverting = true;
    +			$( this.helper ).animate(
    +				animation,
    +				parseInt( this.options.revert, 10 ) || 500,
    +				function() {
    +					that._clear( event );
    +				}
    +			);
    +		} else {
    +			this._clear( event, noPropagation );
    +		}
    +
    +		return false;
    +
    +	},
    +
    +	cancel: function() {
    +
    +		if ( this.dragging ) {
    +
    +			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
    +
    +			if ( this.options.helper === "original" ) {
    +				this.currentItem.css( this._storedCSS );
    +				this._removeClass( this.currentItem, "ui-sortable-helper" );
    +			} else {
    +				this.currentItem.show();
    +			}
    +
    +			//Post deactivating events to containers
    +			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
    +				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
    +				if ( this.containers[ i ].containerCache.over ) {
    +					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
    +					this.containers[ i ].containerCache.over = 0;
    +				}
    +			}
    +
    +		}
    +
    +		if ( this.placeholder ) {
    +
    +			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
    +			// it unbinds ALL events from the original node!
    +			if ( this.placeholder[ 0 ].parentNode ) {
    +				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
    +			}
    +			if ( this.options.helper !== "original" && this.helper &&
    +					this.helper[ 0 ].parentNode ) {
    +				this.helper.remove();
    +			}
    +
    +			$.extend( this, {
    +				helper: null,
    +				dragging: false,
    +				reverting: false,
    +				_noFinalSort: null
    +			} );
    +
    +			if ( this.domPosition.prev ) {
    +				$( this.domPosition.prev ).after( this.currentItem );
    +			} else {
    +				$( this.domPosition.parent ).prepend( this.currentItem );
    +			}
    +		}
    +
    +		return this;
    +
    +	},
    +
    +	serialize: function( o ) {
    +
    +		var items = this._getItemsAsjQuery( o && o.connected ),
    +			str = [];
    +		o = o || {};
    +
    +		$( items ).each( function() {
    +			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
    +				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
    +			if ( res ) {
    +				str.push(
    +					( o.key || res[ 1 ] + "[]" ) +
    +					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
    +			}
    +		} );
    +
    +		if ( !str.length && o.key ) {
    +			str.push( o.key + "=" );
    +		}
    +
    +		return str.join( "&" );
    +
    +	},
    +
    +	toArray: function( o ) {
    +
    +		var items = this._getItemsAsjQuery( o && o.connected ),
    +			ret = [];
    +
    +		o = o || {};
    +
    +		items.each( function() {
    +			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
    +		} );
    +		return ret;
    +
    +	},
    +
    +	/* Be careful with the following core functions */
    +	_intersectsWith: function( item ) {
    +
    +		var x1 = this.positionAbs.left,
    +			x2 = x1 + this.helperProportions.width,
    +			y1 = this.positionAbs.top,
    +			y2 = y1 + this.helperProportions.height,
    +			l = item.left,
    +			r = l + item.width,
    +			t = item.top,
    +			b = t + item.height,
    +			dyClick = this.offset.click.top,
    +			dxClick = this.offset.click.left,
    +			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
    +				( y1 + dyClick ) < b ),
    +			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
    +				( x1 + dxClick ) < r ),
    +			isOverElement = isOverElementHeight && isOverElementWidth;
    +
    +		if ( this.options.tolerance === "pointer" ||
    +			this.options.forcePointerForContainers ||
    +			( this.options.tolerance !== "pointer" &&
    +				this.helperProportions[ this.floating ? "width" : "height" ] >
    +				item[ this.floating ? "width" : "height" ] )
    +		) {
    +			return isOverElement;
    +		} else {
    +
    +			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
    +				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
    +				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
    +				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
    +
    +		}
    +	},
    +
    +	_intersectsWithPointer: function( item ) {
    +		var verticalDirection, horizontalDirection,
    +			isOverElementHeight = ( this.options.axis === "x" ) ||
    +				this._isOverAxis(
    +					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
    +			isOverElementWidth = ( this.options.axis === "y" ) ||
    +				this._isOverAxis(
    +					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
    +			isOverElement = isOverElementHeight && isOverElementWidth;
    +
    +		if ( !isOverElement ) {
    +			return false;
    +		}
    +
    +		verticalDirection = this._getDragVerticalDirection();
    +		horizontalDirection = this._getDragHorizontalDirection();
    +
    +		return this.floating ?
    +			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
    +			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
    +
    +	},
    +
    +	_intersectsWithSides: function( item ) {
    +
    +		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
    +				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
    +			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
    +				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
    +			verticalDirection = this._getDragVerticalDirection(),
    +			horizontalDirection = this._getDragHorizontalDirection();
    +
    +		if ( this.floating && horizontalDirection ) {
    +			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
    +				( horizontalDirection === "left" && !isOverRightHalf ) );
    +		} else {
    +			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
    +				( verticalDirection === "up" && !isOverBottomHalf ) );
    +		}
    +
    +	},
    +
    +	_getDragVerticalDirection: function() {
    +		var delta = this.positionAbs.top - this.lastPositionAbs.top;
    +		return delta !== 0 && ( delta > 0 ? "down" : "up" );
    +	},
    +
    +	_getDragHorizontalDirection: function() {
    +		var delta = this.positionAbs.left - this.lastPositionAbs.left;
    +		return delta !== 0 && ( delta > 0 ? "right" : "left" );
    +	},
    +
    +	refresh: function( event ) {
    +		this._refreshItems( event );
    +		this._setHandleClassName();
    +		this.refreshPositions();
    +		return this;
    +	},
    +
    +	_connectWith: function() {
    +		var options = this.options;
    +		return options.connectWith.constructor === String ?
    +			[ options.connectWith ] :
    +			options.connectWith;
    +	},
    +
    +	_getItemsAsjQuery: function( connected ) {
    +
    +		var i, j, cur, inst,
    +			items = [],
    +			queries = [],
    +			connectWith = this._connectWith();
    +
    +		if ( connectWith && connected ) {
    +			for ( i = connectWith.length - 1; i >= 0; i-- ) {
    +				cur = $( connectWith[ i ], this.document[ 0 ] );
    +				for ( j = cur.length - 1; j >= 0; j-- ) {
    +					inst = $.data( cur[ j ], this.widgetFullName );
    +					if ( inst && inst !== this && !inst.options.disabled ) {
    +						queries.push( [ $.isFunction( inst.options.items ) ?
    +							inst.options.items.call( inst.element ) :
    +							$( inst.options.items, inst.element )
    +								.not( ".ui-sortable-helper" )
    +								.not( ".ui-sortable-placeholder" ), inst ] );
    +					}
    +				}
    +			}
    +		}
    +
    +		queries.push( [ $.isFunction( this.options.items ) ?
    +			this.options.items
    +				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
    +			$( this.options.items, this.element )
    +				.not( ".ui-sortable-helper" )
    +				.not( ".ui-sortable-placeholder" ), this ] );
    +
    +		function addItems() {
    +			items.push( this );
    +		}
    +		for ( i = queries.length - 1; i >= 0; i-- ) {
    +			queries[ i ][ 0 ].each( addItems );
    +		}
    +
    +		return $( items );
    +
    +	},
    +
    +	_removeCurrentsFromItems: function() {
    +
    +		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
    +
    +		this.items = $.grep( this.items, function( item ) {
    +			for ( var j = 0; j < list.length; j++ ) {
    +				if ( list[ j ] === item.item[ 0 ] ) {
    +					return false;
    +				}
    +			}
    +			return true;
    +		} );
    +
    +	},
    +
    +	_refreshItems: function( event ) {
    +
    +		this.items = [];
    +		this.containers = [ this ];
    +
    +		var i, j, cur, inst, targetData, _queries, item, queriesLength,
    +			items = this.items,
    +			queries = [ [ $.isFunction( this.options.items ) ?
    +				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
    +				$( this.options.items, this.element ), this ] ],
    +			connectWith = this._connectWith();
    +
    +		//Shouldn't be run the first time through due to massive slow-down
    +		if ( connectWith && this.ready ) {
    +			for ( i = connectWith.length - 1; i >= 0; i-- ) {
    +				cur = $( connectWith[ i ], this.document[ 0 ] );
    +				for ( j = cur.length - 1; j >= 0; j-- ) {
    +					inst = $.data( cur[ j ], this.widgetFullName );
    +					if ( inst && inst !== this && !inst.options.disabled ) {
    +						queries.push( [ $.isFunction( inst.options.items ) ?
    +							inst.options.items
    +								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
    +							$( inst.options.items, inst.element ), inst ] );
    +						this.containers.push( inst );
    +					}
    +				}
    +			}
    +		}
    +
    +		for ( i = queries.length - 1; i >= 0; i-- ) {
    +			targetData = queries[ i ][ 1 ];
    +			_queries = queries[ i ][ 0 ];
    +
    +			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
    +				item = $( _queries[ j ] );
    +
    +				// Data for target checking (mouse manager)
    +				item.data( this.widgetName + "-item", targetData );
    +
    +				items.push( {
    +					item: item,
    +					instance: targetData,
    +					width: 0, height: 0,
    +					left: 0, top: 0
    +				} );
    +			}
    +		}
    +
    +	},
    +
    +	refreshPositions: function( fast ) {
    +
    +		// Determine whether items are being displayed horizontally
    +		this.floating = this.items.length ?
    +			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
    +			false;
    +
    +		//This has to be redone because due to the item being moved out/into the offsetParent,
    +		// the offsetParent's position will change
    +		if ( this.offsetParent && this.helper ) {
    +			this.offset.parent = this._getParentOffset();
    +		}
    +
    +		var i, item, t, p;
    +
    +		for ( i = this.items.length - 1; i >= 0; i-- ) {
    +			item = this.items[ i ];
    +
    +			//We ignore calculating positions of all connected containers when we're not over them
    +			if ( item.instance !== this.currentContainer && this.currentContainer &&
    +					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
    +				continue;
    +			}
    +
    +			t = this.options.toleranceElement ?
    +				$( this.options.toleranceElement, item.item ) :
    +				item.item;
    +
    +			if ( !fast ) {
    +				item.width = t.outerWidth();
    +				item.height = t.outerHeight();
    +			}
    +
    +			p = t.offset();
    +			item.left = p.left;
    +			item.top = p.top;
    +		}
    +
    +		if ( this.options.custom && this.options.custom.refreshContainers ) {
    +			this.options.custom.refreshContainers.call( this );
    +		} else {
    +			for ( i = this.containers.length - 1; i >= 0; i-- ) {
    +				p = this.containers[ i ].element.offset();
    +				this.containers[ i ].containerCache.left = p.left;
    +				this.containers[ i ].containerCache.top = p.top;
    +				this.containers[ i ].containerCache.width =
    +					this.containers[ i ].element.outerWidth();
    +				this.containers[ i ].containerCache.height =
    +					this.containers[ i ].element.outerHeight();
    +			}
    +		}
    +
    +		return this;
    +	},
    +
    +	_createPlaceholder: function( that ) {
    +		that = that || this;
    +		var className,
    +			o = that.options;
    +
    +		if ( !o.placeholder || o.placeholder.constructor === String ) {
    +			className = o.placeholder;
    +			o.placeholder = {
    +				element: function() {
    +
    +					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
    +						element = $( "<" + nodeName + ">", that.document[ 0 ] );
    +
    +						that._addClass( element, "ui-sortable-placeholder",
    +								className || that.currentItem[ 0 ].className )
    +							._removeClass( element, "ui-sortable-helper" );
    +
    +					if ( nodeName === "tbody" ) {
    +						that._createTrPlaceholder(
    +							that.currentItem.find( "tr" ).eq( 0 ),
    +							$( "<tr>", that.document[ 0 ] ).appendTo( element )
    +						);
    +					} else if ( nodeName === "tr" ) {
    +						that._createTrPlaceholder( that.currentItem, element );
    +					} else if ( nodeName === "img" ) {
    +						element.attr( "src", that.currentItem.attr( "src" ) );
    +					}
    +
    +					if ( !className ) {
    +						element.css( "visibility", "hidden" );
    +					}
    +
    +					return element;
    +				},
    +				update: function( container, p ) {
    +
    +					// 1. If a className is set as 'placeholder option, we don't force sizes -
    +					// the class is responsible for that
    +					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
    +					// class name is specified
    +					if ( className && !o.forcePlaceholderSize ) {
    +						return;
    +					}
    +
    +					//If the element doesn't have a actual height by itself (without styles coming
    +					// from a stylesheet), it receives the inline height from the dragged item
    +					if ( !p.height() ) {
    +						p.height(
    +							that.currentItem.innerHeight() -
    +							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
    +							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
    +					}
    +					if ( !p.width() ) {
    +						p.width(
    +							that.currentItem.innerWidth() -
    +							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
    +							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
    +					}
    +				}
    +			};
    +		}
    +
    +		//Create the placeholder
    +		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
    +
    +		//Append it after the actual current item
    +		that.currentItem.after( that.placeholder );
    +
    +		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
    +		o.placeholder.update( that, that.placeholder );
    +
    +	},
    +
    +	_createTrPlaceholder: function( sourceTr, targetTr ) {
    +		var that = this;
    +
    +		sourceTr.children().each( function() {
    +			$( "<td>&#160;</td>", that.document[ 0 ] )
    +				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
    +				.appendTo( targetTr );
    +		} );
    +	},
    +
    +	_contactContainers: function( event ) {
    +		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
    +			floating, axis,
    +			innermostContainer = null,
    +			innermostIndex = null;
    +
    +		// Get innermost container that intersects with item
    +		for ( i = this.containers.length - 1; i >= 0; i-- ) {
    +
    +			// Never consider a container that's located within the item itself
    +			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
    +				continue;
    +			}
    +
    +			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
    +
    +				// If we've already found a container and it's more "inner" than this, then continue
    +				if ( innermostContainer &&
    +						$.contains(
    +							this.containers[ i ].element[ 0 ],
    +							innermostContainer.element[ 0 ] ) ) {
    +					continue;
    +				}
    +
    +				innermostContainer = this.containers[ i ];
    +				innermostIndex = i;
    +
    +			} else {
    +
    +				// container doesn't intersect. trigger "out" event if necessary
    +				if ( this.containers[ i ].containerCache.over ) {
    +					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
    +					this.containers[ i ].containerCache.over = 0;
    +				}
    +			}
    +
    +		}
    +
    +		// If no intersecting containers found, return
    +		if ( !innermostContainer ) {
    +			return;
    +		}
    +
    +		// Move the item into the container if it's not there already
    +		if ( this.containers.length === 1 ) {
    +			if ( !this.containers[ innermostIndex ].containerCache.over ) {
    +				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
    +				this.containers[ innermostIndex ].containerCache.over = 1;
    +			}
    +		} else {
    +
    +			// When entering a new container, we will find the item with the least distance and
    +			// append our item near it
    +			dist = 10000;
    +			itemWithLeastDistance = null;
    +			floating = innermostContainer.floating || this._isFloating( this.currentItem );
    +			posProperty = floating ? "left" : "top";
    +			sizeProperty = floating ? "width" : "height";
    +			axis = floating ? "pageX" : "pageY";
    +
    +			for ( j = this.items.length - 1; j >= 0; j-- ) {
    +				if ( !$.contains(
    +						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
    +				) {
    +					continue;
    +				}
    +				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
    +					continue;
    +				}
    +
    +				cur = this.items[ j ].item.offset()[ posProperty ];
    +				nearBottom = false;
    +				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
    +					nearBottom = true;
    +				}
    +
    +				if ( Math.abs( event[ axis ] - cur ) < dist ) {
    +					dist = Math.abs( event[ axis ] - cur );
    +					itemWithLeastDistance = this.items[ j ];
    +					this.direction = nearBottom ? "up" : "down";
    +				}
    +			}
    +
    +			//Check if dropOnEmpty is enabled
    +			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
    +				return;
    +			}
    +
    +			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
    +				if ( !this.currentContainer.containerCache.over ) {
    +					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
    +					this.currentContainer.containerCache.over = 1;
    +				}
    +				return;
    +			}
    +
    +			itemWithLeastDistance ?
    +				this._rearrange( event, itemWithLeastDistance, null, true ) :
    +				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
    +			this._trigger( "change", event, this._uiHash() );
    +			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
    +			this.currentContainer = this.containers[ innermostIndex ];
    +
    +			//Update the placeholder
    +			this.options.placeholder.update( this.currentContainer, this.placeholder );
    +
    +			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
    +			this.containers[ innermostIndex ].containerCache.over = 1;
    +		}
    +
    +	},
    +
    +	_createHelper: function( event ) {
    +
    +		var o = this.options,
    +			helper = $.isFunction( o.helper ) ?
    +				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
    +				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
    +
    +		//Add the helper to the DOM if that didn't happen already
    +		if ( !helper.parents( "body" ).length ) {
    +			$( o.appendTo !== "parent" ?
    +				o.appendTo :
    +				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
    +		}
    +
    +		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
    +			this._storedCSS = {
    +				width: this.currentItem[ 0 ].style.width,
    +				height: this.currentItem[ 0 ].style.height,
    +				position: this.currentItem.css( "position" ),
    +				top: this.currentItem.css( "top" ),
    +				left: this.currentItem.css( "left" )
    +			};
    +		}
    +
    +		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
    +			helper.width( this.currentItem.width() );
    +		}
    +		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
    +			helper.height( this.currentItem.height() );
    +		}
    +
    +		return helper;
    +
    +	},
    +
    +	_adjustOffsetFromHelper: function( obj ) {
    +		if ( typeof obj === "string" ) {
    +			obj = obj.split( " " );
    +		}
    +		if ( $.isArray( obj ) ) {
    +			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
    +		}
    +		if ( "left" in obj ) {
    +			this.offset.click.left = obj.left + this.margins.left;
    +		}
    +		if ( "right" in obj ) {
    +			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
    +		}
    +		if ( "top" in obj ) {
    +			this.offset.click.top = obj.top + this.margins.top;
    +		}
    +		if ( "bottom" in obj ) {
    +			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
    +		}
    +	},
    +
    +	_getParentOffset: function() {
    +
    +		//Get the offsetParent and cache its position
    +		this.offsetParent = this.helper.offsetParent();
    +		var po = this.offsetParent.offset();
    +
    +		// This is a special case where we need to modify a offset calculated on start, since the
    +		// following happened:
    +		// 1. The position of the helper is absolute, so it's position is calculated based on the
    +		// next positioned parent
    +		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
    +		// the document, which means that the scroll is included in the initial calculation of the
    +		// offset of the parent, and never recalculated upon drag
    +		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
    +				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
    +			po.left += this.scrollParent.scrollLeft();
    +			po.top += this.scrollParent.scrollTop();
    +		}
    +
    +		// This needs to be actually done for all browsers, since pageX/pageY includes this
    +		// information with an ugly IE fix
    +		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
    +				( this.offsetParent[ 0 ].tagName &&
    +				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
    +			po = { top: 0, left: 0 };
    +		}
    +
    +		return {
    +			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
    +			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
    +		};
    +
    +	},
    +
    +	_getRelativeOffset: function() {
    +
    +		if ( this.cssPosition === "relative" ) {
    +			var p = this.currentItem.position();
    +			return {
    +				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
    +					this.scrollParent.scrollTop(),
    +				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
    +					this.scrollParent.scrollLeft()
    +			};
    +		} else {
    +			return { top: 0, left: 0 };
    +		}
    +
    +	},
    +
    +	_cacheMargins: function() {
    +		this.margins = {
    +			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
    +			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
    +		};
    +	},
    +
    +	_cacheHelperProportions: function() {
    +		this.helperProportions = {
    +			width: this.helper.outerWidth(),
    +			height: this.helper.outerHeight()
    +		};
    +	},
    +
    +	_setContainment: function() {
    +
    +		var ce, co, over,
    +			o = this.options;
    +		if ( o.containment === "parent" ) {
    +			o.containment = this.helper[ 0 ].parentNode;
    +		}
    +		if ( o.containment === "document" || o.containment === "window" ) {
    +			this.containment = [
    +				0 - this.offset.relative.left - this.offset.parent.left,
    +				0 - this.offset.relative.top - this.offset.parent.top,
    +				o.containment === "document" ?
    +					this.document.width() :
    +					this.window.width() - this.helperProportions.width - this.margins.left,
    +				( o.containment === "document" ?
    +					( this.document.height() || document.body.parentNode.scrollHeight ) :
    +					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
    +				) - this.helperProportions.height - this.margins.top
    +			];
    +		}
    +
    +		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
    +			ce = $( o.containment )[ 0 ];
    +			co = $( o.containment ).offset();
    +			over = ( $( ce ).css( "overflow" ) !== "hidden" );
    +
    +			this.containment = [
    +				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
    +					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
    +				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
    +					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
    +				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
    +					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
    +					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
    +					this.helperProportions.width - this.margins.left,
    +				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
    +					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
    +					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
    +					this.helperProportions.height - this.margins.top
    +			];
    +		}
    +
    +	},
    +
    +	_convertPositionTo: function( d, pos ) {
    +
    +		if ( !pos ) {
    +			pos = this.position;
    +		}
    +		var mod = d === "absolute" ? 1 : -1,
    +			scroll = this.cssPosition === "absolute" &&
    +				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
    +				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
    +					this.offsetParent :
    +					this.scrollParent,
    +			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
    +
    +		return {
    +			top: (
    +
    +				// The absolute mouse position
    +				pos.top	+
    +
    +				// Only for relative positioned nodes: Relative offset from element to offset parent
    +				this.offset.relative.top * mod +
    +
    +				// The offsetParent's offset without borders (offset + border)
    +				this.offset.parent.top * mod -
    +				( ( this.cssPosition === "fixed" ?
    +					-this.scrollParent.scrollTop() :
    +					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
    +			),
    +			left: (
    +
    +				// The absolute mouse position
    +				pos.left +
    +
    +				// Only for relative positioned nodes: Relative offset from element to offset parent
    +				this.offset.relative.left * mod +
    +
    +				// The offsetParent's offset without borders (offset + border)
    +				this.offset.parent.left * mod	-
    +				( ( this.cssPosition === "fixed" ?
    +					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
    +					scroll.scrollLeft() ) * mod )
    +			)
    +		};
    +
    +	},
    +
    +	_generatePosition: function( event ) {
    +
    +		var top, left,
    +			o = this.options,
    +			pageX = event.pageX,
    +			pageY = event.pageY,
    +			scroll = this.cssPosition === "absolute" &&
    +				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
    +				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
    +					this.offsetParent :
    +					this.scrollParent,
    +				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
    +
    +		// This is another very weird special case that only happens for relative elements:
    +		// 1. If the css position is relative
    +		// 2. and the scroll parent is the document or similar to the offset parent
    +		// we have to refresh the relative offset during the scroll so there are no jumps
    +		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
    +				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
    +			this.offset.relative = this._getRelativeOffset();
    +		}
    +
    +		/*
    +		 * - Position constraining -
    +		 * Constrain the position to a mix of grid, containment.
    +		 */
    +
    +		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
    +
    +			if ( this.containment ) {
    +				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
    +					pageX = this.containment[ 0 ] + this.offset.click.left;
    +				}
    +				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
    +					pageY = this.containment[ 1 ] + this.offset.click.top;
    +				}
    +				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
    +					pageX = this.containment[ 2 ] + this.offset.click.left;
    +				}
    +				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
    +					pageY = this.containment[ 3 ] + this.offset.click.top;
    +				}
    +			}
    +
    +			if ( o.grid ) {
    +				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
    +					o.grid[ 1 ] ) * o.grid[ 1 ];
    +				pageY = this.containment ?
    +					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
    +						top - this.offset.click.top <= this.containment[ 3 ] ) ?
    +							top :
    +							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
    +								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
    +								top;
    +
    +				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
    +					o.grid[ 0 ] ) * o.grid[ 0 ];
    +				pageX = this.containment ?
    +					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
    +						left - this.offset.click.left <= this.containment[ 2 ] ) ?
    +							left :
    +							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
    +								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
    +								left;
    +			}
    +
    +		}
    +
    +		return {
    +			top: (
    +
    +				// The absolute mouse position
    +				pageY -
    +
    +				// Click offset (relative to the element)
    +				this.offset.click.top -
    +
    +				// Only for relative positioned nodes: Relative offset from element to offset parent
    +				this.offset.relative.top -
    +
    +				// The offsetParent's offset without borders (offset + border)
    +				this.offset.parent.top +
    +				( ( this.cssPosition === "fixed" ?
    +					-this.scrollParent.scrollTop() :
    +					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
    +			),
    +			left: (
    +
    +				// The absolute mouse position
    +				pageX -
    +
    +				// Click offset (relative to the element)
    +				this.offset.click.left -
    +
    +				// Only for relative positioned nodes: Relative offset from element to offset parent
    +				this.offset.relative.left -
    +
    +				// The offsetParent's offset without borders (offset + border)
    +				this.offset.parent.left +
    +				( ( this.cssPosition === "fixed" ?
    +					-this.scrollParent.scrollLeft() :
    +					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
    +			)
    +		};
    +
    +	},
    +
    +	_rearrange: function( event, i, a, hardRefresh ) {
    +
    +		a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
    +			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
    +				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
    +
    +		//Various things done here to improve the performance:
    +		// 1. we create a setTimeout, that calls refreshPositions
    +		// 2. on the instance, we have a counter variable, that get's higher after every append
    +		// 3. on the local scope, we copy the counter variable, and check in the timeout,
    +		// if it's still the same
    +		// 4. this lets only the last addition to the timeout stack through
    +		this.counter = this.counter ? ++this.counter : 1;
    +		var counter = this.counter;
    +
    +		this._delay( function() {
    +			if ( counter === this.counter ) {
    +
    +				//Precompute after each DOM insertion, NOT on mousemove
    +				this.refreshPositions( !hardRefresh );
    +			}
    +		} );
    +
    +	},
    +
    +	_clear: function( event, noPropagation ) {
    +
    +		this.reverting = false;
    +
    +		// We delay all events that have to be triggered to after the point where the placeholder
    +		// has been removed and everything else normalized again
    +		var i,
    +			delayedTriggers = [];
    +
    +		// We first have to update the dom position of the actual currentItem
    +		// Note: don't do it if the current item is already removed (by a user), or it gets
    +		// reappended (see #4088)
    +		if ( !this._noFinalSort && this.currentItem.parent().length ) {
    +			this.placeholder.before( this.currentItem );
    +		}
    +		this._noFinalSort = null;
    +
    +		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
    +			for ( i in this._storedCSS ) {
    +				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
    +					this._storedCSS[ i ] = "";
    +				}
    +			}
    +			this.currentItem.css( this._storedCSS );
    +			this._removeClass( this.currentItem, "ui-sortable-helper" );
    +		} else {
    +			this.currentItem.show();
    +		}
    +
    +		if ( this.fromOutside && !noPropagation ) {
    +			delayedTriggers.push( function( event ) {
    +				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
    +			} );
    +		}
    +		if ( ( this.fromOutside ||
    +				this.domPosition.prev !==
    +				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
    +				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
    +
    +			// Trigger update callback if the DOM position has changed
    +			delayedTriggers.push( function( event ) {
    +				this._trigger( "update", event, this._uiHash() );
    +			} );
    +		}
    +
    +		// Check if the items Container has Changed and trigger appropriate
    +		// events.
    +		if ( this !== this.currentContainer ) {
    +			if ( !noPropagation ) {
    +				delayedTriggers.push( function( event ) {
    +					this._trigger( "remove", event, this._uiHash() );
    +				} );
    +				delayedTriggers.push( ( function( c ) {
    +					return function( event ) {
    +						c._trigger( "receive", event, this._uiHash( this ) );
    +					};
    +				} ).call( this, this.currentContainer ) );
    +				delayedTriggers.push( ( function( c ) {
    +					return function( event ) {
    +						c._trigger( "update", event, this._uiHash( this ) );
    +					};
    +				} ).call( this, this.currentContainer ) );
    +			}
    +		}
    +
    +		//Post events to containers
    +		function delayEvent( type, instance, container ) {
    +			return function( event ) {
    +				container._trigger( type, event, instance._uiHash( instance ) );
    +			};
    +		}
    +		for ( i = this.containers.length - 1; i >= 0; i-- ) {
    +			if ( !noPropagation ) {
    +				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
    +			}
    +			if ( this.containers[ i ].containerCache.over ) {
    +				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
    +				this.containers[ i ].containerCache.over = 0;
    +			}
    +		}
    +
    +		//Do what was originally in plugins
    +		if ( this.storedCursor ) {
    +			this.document.find( "body" ).css( "cursor", this.storedCursor );
    +			this.storedStylesheet.remove();
    +		}
    +		if ( this._storedOpacity ) {
    +			this.helper.css( "opacity", this._storedOpacity );
    +		}
    +		if ( this._storedZIndex ) {
    +			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
    +		}
    +
    +		this.dragging = false;
    +
    +		if ( !noPropagation ) {
    +			this._trigger( "beforeStop", event, this._uiHash() );
    +		}
    +
    +		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
    +		// it unbinds ALL events from the original node!
    +		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
    +
    +		if ( !this.cancelHelperRemoval ) {
    +			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
    +				this.helper.remove();
    +			}
    +			this.helper = null;
    +		}
    +
    +		if ( !noPropagation ) {
    +			for ( i = 0; i < delayedTriggers.length; i++ ) {
    +
    +				// Trigger all delayed events
    +				delayedTriggers[ i ].call( this, event );
    +			}
    +			this._trigger( "stop", event, this._uiHash() );
    +		}
    +
    +		this.fromOutside = false;
    +		return !this.cancelHelperRemoval;
    +
    +	},
    +
    +	_trigger: function() {
    +		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
    +			this.cancel();
    +		}
    +	},
    +
    +	_uiHash: function( _inst ) {
    +		var inst = _inst || this;
    +		return {
    +			helper: inst.helper,
    +			placeholder: inst.placeholder || $( [] ),
    +			position: inst.position,
    +			originalPosition: inst.originalPosition,
    +			offset: inst.positionAbs,
    +			item: inst.currentItem,
    +			sender: _inst ? _inst.element : null
    +		};
    +	}
    +
    +} );
    +
    +
    +/*!
    + * jQuery UI Spinner 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Spinner
    +//>>group: Widgets
    +//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
    +//>>docs: http://api.jqueryui.com/spinner/
    +//>>demos: http://jqueryui.com/spinner/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/spinner.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +function spinnerModifer( fn ) {
    +	return function() {
    +		var previous = this.element.val();
    +		fn.apply( this, arguments );
    +		this._refresh();
    +		if ( previous !== this.element.val() ) {
    +			this._trigger( "change" );
    +		}
    +	};
    +}
    +
    +$.widget( "ui.spinner", {
    +	version: "1.12.1",
    +	defaultElement: "<input>",
    +	widgetEventPrefix: "spin",
    +	options: {
    +		classes: {
    +			"ui-spinner": "ui-corner-all",
    +			"ui-spinner-down": "ui-corner-br",
    +			"ui-spinner-up": "ui-corner-tr"
    +		},
    +		culture: null,
    +		icons: {
    +			down: "ui-icon-triangle-1-s",
    +			up: "ui-icon-triangle-1-n"
    +		},
    +		incremental: true,
    +		max: null,
    +		min: null,
    +		numberFormat: null,
    +		page: 10,
    +		step: 1,
    +
    +		change: null,
    +		spin: null,
    +		start: null,
    +		stop: null
    +	},
    +
    +	_create: function() {
    +
    +		// handle string values that need to be parsed
    +		this._setOption( "max", this.options.max );
    +		this._setOption( "min", this.options.min );
    +		this._setOption( "step", this.options.step );
    +
    +		// Only format if there is a value, prevents the field from being marked
    +		// as invalid in Firefox, see #9573.
    +		if ( this.value() !== "" ) {
    +
    +			// Format the value, but don't constrain.
    +			this._value( this.element.val(), true );
    +		}
    +
    +		this._draw();
    +		this._on( this._events );
    +		this._refresh();
    +
    +		// Turning off autocomplete prevents the browser from remembering the
    +		// value when navigating through history, so we re-enable autocomplete
    +		// if the page is unloaded before the widget is destroyed. #7790
    +		this._on( this.window, {
    +			beforeunload: function() {
    +				this.element.removeAttr( "autocomplete" );
    +			}
    +		} );
    +	},
    +
    +	_getCreateOptions: function() {
    +		var options = this._super();
    +		var element = this.element;
    +
    +		$.each( [ "min", "max", "step" ], function( i, option ) {
    +			var value = element.attr( option );
    +			if ( value != null && value.length ) {
    +				options[ option ] = value;
    +			}
    +		} );
    +
    +		return options;
    +	},
    +
    +	_events: {
    +		keydown: function( event ) {
    +			if ( this._start( event ) && this._keydown( event ) ) {
    +				event.preventDefault();
    +			}
    +		},
    +		keyup: "_stop",
    +		focus: function() {
    +			this.previous = this.element.val();
    +		},
    +		blur: function( event ) {
    +			if ( this.cancelBlur ) {
    +				delete this.cancelBlur;
    +				return;
    +			}
    +
    +			this._stop();
    +			this._refresh();
    +			if ( this.previous !== this.element.val() ) {
    +				this._trigger( "change", event );
    +			}
    +		},
    +		mousewheel: function( event, delta ) {
    +			if ( !delta ) {
    +				return;
    +			}
    +			if ( !this.spinning && !this._start( event ) ) {
    +				return false;
    +			}
    +
    +			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
    +			clearTimeout( this.mousewheelTimer );
    +			this.mousewheelTimer = this._delay( function() {
    +				if ( this.spinning ) {
    +					this._stop( event );
    +				}
    +			}, 100 );
    +			event.preventDefault();
    +		},
    +		"mousedown .ui-spinner-button": function( event ) {
    +			var previous;
    +
    +			// We never want the buttons to have focus; whenever the user is
    +			// interacting with the spinner, the focus should be on the input.
    +			// If the input is focused then this.previous is properly set from
    +			// when the input first received focus. If the input is not focused
    +			// then we need to set this.previous based on the value before spinning.
    +			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
    +				this.previous : this.element.val();
    +			function checkFocus() {
    +				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
    +				if ( !isActive ) {
    +					this.element.trigger( "focus" );
    +					this.previous = previous;
    +
    +					// support: IE
    +					// IE sets focus asynchronously, so we need to check if focus
    +					// moved off of the input because the user clicked on the button.
    +					this._delay( function() {
    +						this.previous = previous;
    +					} );
    +				}
    +			}
    +
    +			// Ensure focus is on (or stays on) the text field
    +			event.preventDefault();
    +			checkFocus.call( this );
    +
    +			// Support: IE
    +			// IE doesn't prevent moving focus even with event.preventDefault()
    +			// so we set a flag to know when we should ignore the blur event
    +			// and check (again) if focus moved off of the input.
    +			this.cancelBlur = true;
    +			this._delay( function() {
    +				delete this.cancelBlur;
    +				checkFocus.call( this );
    +			} );
    +
    +			if ( this._start( event ) === false ) {
    +				return;
    +			}
    +
    +			this._repeat( null, $( event.currentTarget )
    +				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
    +		},
    +		"mouseup .ui-spinner-button": "_stop",
    +		"mouseenter .ui-spinner-button": function( event ) {
    +
    +			// button will add ui-state-active if mouse was down while mouseleave and kept down
    +			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
    +				return;
    +			}
    +
    +			if ( this._start( event ) === false ) {
    +				return false;
    +			}
    +			this._repeat( null, $( event.currentTarget )
    +				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
    +		},
    +
    +		// TODO: do we really want to consider this a stop?
    +		// shouldn't we just stop the repeater and wait until mouseup before
    +		// we trigger the stop event?
    +		"mouseleave .ui-spinner-button": "_stop"
    +	},
    +
    +	// Support mobile enhanced option and make backcompat more sane
    +	_enhance: function() {
    +		this.uiSpinner = this.element
    +			.attr( "autocomplete", "off" )
    +			.wrap( "<span>" )
    +			.parent()
    +
    +				// Add buttons
    +				.append(
    +					"<a></a><a></a>"
    +				);
    +	},
    +
    +	_draw: function() {
    +		this._enhance();
    +
    +		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
    +		this._addClass( "ui-spinner-input" );
    +
    +		this.element.attr( "role", "spinbutton" );
    +
    +		// Button bindings
    +		this.buttons = this.uiSpinner.children( "a" )
    +			.attr( "tabIndex", -1 )
    +			.attr( "aria-hidden", true )
    +			.button( {
    +				classes: {
    +					"ui-button": ""
    +				}
    +			} );
    +
    +		// TODO: Right now button does not support classes this is already updated in button PR
    +		this._removeClass( this.buttons, "ui-corner-all" );
    +
    +		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
    +		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
    +		this.buttons.first().button( {
    +			"icon": this.options.icons.up,
    +			"showLabel": false
    +		} );
    +		this.buttons.last().button( {
    +			"icon": this.options.icons.down,
    +			"showLabel": false
    +		} );
    +
    +		// IE 6 doesn't understand height: 50% for the buttons
    +		// unless the wrapper has an explicit height
    +		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
    +				this.uiSpinner.height() > 0 ) {
    +			this.uiSpinner.height( this.uiSpinner.height() );
    +		}
    +	},
    +
    +	_keydown: function( event ) {
    +		var options = this.options,
    +			keyCode = $.ui.keyCode;
    +
    +		switch ( event.keyCode ) {
    +		case keyCode.UP:
    +			this._repeat( null, 1, event );
    +			return true;
    +		case keyCode.DOWN:
    +			this._repeat( null, -1, event );
    +			return true;
    +		case keyCode.PAGE_UP:
    +			this._repeat( null, options.page, event );
    +			return true;
    +		case keyCode.PAGE_DOWN:
    +			this._repeat( null, -options.page, event );
    +			return true;
    +		}
    +
    +		return false;
    +	},
    +
    +	_start: function( event ) {
    +		if ( !this.spinning && this._trigger( "start", event ) === false ) {
    +			return false;
    +		}
    +
    +		if ( !this.counter ) {
    +			this.counter = 1;
    +		}
    +		this.spinning = true;
    +		return true;
    +	},
    +
    +	_repeat: function( i, steps, event ) {
    +		i = i || 500;
    +
    +		clearTimeout( this.timer );
    +		this.timer = this._delay( function() {
    +			this._repeat( 40, steps, event );
    +		}, i );
    +
    +		this._spin( steps * this.options.step, event );
    +	},
    +
    +	_spin: function( step, event ) {
    +		var value = this.value() || 0;
    +
    +		if ( !this.counter ) {
    +			this.counter = 1;
    +		}
    +
    +		value = this._adjustValue( value + step * this._increment( this.counter ) );
    +
    +		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
    +			this._value( value );
    +			this.counter++;
    +		}
    +	},
    +
    +	_increment: function( i ) {
    +		var incremental = this.options.incremental;
    +
    +		if ( incremental ) {
    +			return $.isFunction( incremental ) ?
    +				incremental( i ) :
    +				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
    +		}
    +
    +		return 1;
    +	},
    +
    +	_precision: function() {
    +		var precision = this._precisionOf( this.options.step );
    +		if ( this.options.min !== null ) {
    +			precision = Math.max( precision, this._precisionOf( this.options.min ) );
    +		}
    +		return precision;
    +	},
    +
    +	_precisionOf: function( num ) {
    +		var str = num.toString(),
    +			decimal = str.indexOf( "." );
    +		return decimal === -1 ? 0 : str.length - decimal - 1;
    +	},
    +
    +	_adjustValue: function( value ) {
    +		var base, aboveMin,
    +			options = this.options;
    +
    +		// Make sure we're at a valid step
    +		// - find out where we are relative to the base (min or 0)
    +		base = options.min !== null ? options.min : 0;
    +		aboveMin = value - base;
    +
    +		// - round to the nearest step
    +		aboveMin = Math.round( aboveMin / options.step ) * options.step;
    +
    +		// - rounding is based on 0, so adjust back to our base
    +		value = base + aboveMin;
    +
    +		// Fix precision from bad JS floating point math
    +		value = parseFloat( value.toFixed( this._precision() ) );
    +
    +		// Clamp the value
    +		if ( options.max !== null && value > options.max ) {
    +			return options.max;
    +		}
    +		if ( options.min !== null && value < options.min ) {
    +			return options.min;
    +		}
    +
    +		return value;
    +	},
    +
    +	_stop: function( event ) {
    +		if ( !this.spinning ) {
    +			return;
    +		}
    +
    +		clearTimeout( this.timer );
    +		clearTimeout( this.mousewheelTimer );
    +		this.counter = 0;
    +		this.spinning = false;
    +		this._trigger( "stop", event );
    +	},
    +
    +	_setOption: function( key, value ) {
    +		var prevValue, first, last;
    +
    +		if ( key === "culture" || key === "numberFormat" ) {
    +			prevValue = this._parse( this.element.val() );
    +			this.options[ key ] = value;
    +			this.element.val( this._format( prevValue ) );
    +			return;
    +		}
    +
    +		if ( key === "max" || key === "min" || key === "step" ) {
    +			if ( typeof value === "string" ) {
    +				value = this._parse( value );
    +			}
    +		}
    +		if ( key === "icons" ) {
    +			first = this.buttons.first().find( ".ui-icon" );
    +			this._removeClass( first, null, this.options.icons.up );
    +			this._addClass( first, null, value.up );
    +			last = this.buttons.last().find( ".ui-icon" );
    +			this._removeClass( last, null, this.options.icons.down );
    +			this._addClass( last, null, value.down );
    +		}
    +
    +		this._super( key, value );
    +	},
    +
    +	_setOptionDisabled: function( value ) {
    +		this._super( value );
    +
    +		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
    +		this.element.prop( "disabled", !!value );
    +		this.buttons.button( value ? "disable" : "enable" );
    +	},
    +
    +	_setOptions: spinnerModifer( function( options ) {
    +		this._super( options );
    +	} ),
    +
    +	_parse: function( val ) {
    +		if ( typeof val === "string" && val !== "" ) {
    +			val = window.Globalize && this.options.numberFormat ?
    +				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
    +		}
    +		return val === "" || isNaN( val ) ? null : val;
    +	},
    +
    +	_format: function( value ) {
    +		if ( value === "" ) {
    +			return "";
    +		}
    +		return window.Globalize && this.options.numberFormat ?
    +			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
    +			value;
    +	},
    +
    +	_refresh: function() {
    +		this.element.attr( {
    +			"aria-valuemin": this.options.min,
    +			"aria-valuemax": this.options.max,
    +
    +			// TODO: what should we do with values that can't be parsed?
    +			"aria-valuenow": this._parse( this.element.val() )
    +		} );
    +	},
    +
    +	isValid: function() {
    +		var value = this.value();
    +
    +		// Null is invalid
    +		if ( value === null ) {
    +			return false;
    +		}
    +
    +		// If value gets adjusted, it's invalid
    +		return value === this._adjustValue( value );
    +	},
    +
    +	// Update the value without triggering change
    +	_value: function( value, allowAny ) {
    +		var parsed;
    +		if ( value !== "" ) {
    +			parsed = this._parse( value );
    +			if ( parsed !== null ) {
    +				if ( !allowAny ) {
    +					parsed = this._adjustValue( parsed );
    +				}
    +				value = this._format( parsed );
    +			}
    +		}
    +		this.element.val( value );
    +		this._refresh();
    +	},
    +
    +	_destroy: function() {
    +		this.element
    +			.prop( "disabled", false )
    +			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
    +
    +		this.uiSpinner.replaceWith( this.element );
    +	},
    +
    +	stepUp: spinnerModifer( function( steps ) {
    +		this._stepUp( steps );
    +	} ),
    +	_stepUp: function( steps ) {
    +		if ( this._start() ) {
    +			this._spin( ( steps || 1 ) * this.options.step );
    +			this._stop();
    +		}
    +	},
    +
    +	stepDown: spinnerModifer( function( steps ) {
    +		this._stepDown( steps );
    +	} ),
    +	_stepDown: function( steps ) {
    +		if ( this._start() ) {
    +			this._spin( ( steps || 1 ) * -this.options.step );
    +			this._stop();
    +		}
    +	},
    +
    +	pageUp: spinnerModifer( function( pages ) {
    +		this._stepUp( ( pages || 1 ) * this.options.page );
    +	} ),
    +
    +	pageDown: spinnerModifer( function( pages ) {
    +		this._stepDown( ( pages || 1 ) * this.options.page );
    +	} ),
    +
    +	value: function( newVal ) {
    +		if ( !arguments.length ) {
    +			return this._parse( this.element.val() );
    +		}
    +		spinnerModifer( this._value ).call( this, newVal );
    +	},
    +
    +	widget: function() {
    +		return this.uiSpinner;
    +	}
    +} );
    +
    +// DEPRECATED
    +// TODO: switch return back to widget declaration at top of file when this is removed
    +if ( $.uiBackCompat !== false ) {
    +
    +	// Backcompat for spinner html extension points
    +	$.widget( "ui.spinner", $.ui.spinner, {
    +		_enhance: function() {
    +			this.uiSpinner = this.element
    +				.attr( "autocomplete", "off" )
    +				.wrap( this._uiSpinnerHtml() )
    +				.parent()
    +
    +					// Add buttons
    +					.append( this._buttonHtml() );
    +		},
    +		_uiSpinnerHtml: function() {
    +			return "<span>";
    +		},
    +
    +		_buttonHtml: function() {
    +			return "<a></a><a></a>";
    +		}
    +	} );
    +}
    +
    +var widgetsSpinner = $.ui.spinner;
    +
    +
    +/*!
    + * jQuery UI Tabs 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Tabs
    +//>>group: Widgets
    +//>>description: Transforms a set of container elements into a tab structure.
    +//>>docs: http://api.jqueryui.com/tabs/
    +//>>demos: http://jqueryui.com/tabs/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/tabs.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +$.widget( "ui.tabs", {
    +	version: "1.12.1",
    +	delay: 300,
    +	options: {
    +		active: null,
    +		classes: {
    +			"ui-tabs": "ui-corner-all",
    +			"ui-tabs-nav": "ui-corner-all",
    +			"ui-tabs-panel": "ui-corner-bottom",
    +			"ui-tabs-tab": "ui-corner-top"
    +		},
    +		collapsible: false,
    +		event: "click",
    +		heightStyle: "content",
    +		hide: null,
    +		show: null,
    +
    +		// Callbacks
    +		activate: null,
    +		beforeActivate: null,
    +		beforeLoad: null,
    +		load: null
    +	},
    +
    +	_isLocal: ( function() {
    +		var rhash = /#.*$/;
    +
    +		return function( anchor ) {
    +			var anchorUrl, locationUrl;
    +
    +			anchorUrl = anchor.href.replace( rhash, "" );
    +			locationUrl = location.href.replace( rhash, "" );
    +
    +			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
    +			try {
    +				anchorUrl = decodeURIComponent( anchorUrl );
    +			} catch ( error ) {}
    +			try {
    +				locationUrl = decodeURIComponent( locationUrl );
    +			} catch ( error ) {}
    +
    +			return anchor.hash.length > 1 && anchorUrl === locationUrl;
    +		};
    +	} )(),
    +
    +	_create: function() {
    +		var that = this,
    +			options = this.options;
    +
    +		this.running = false;
    +
    +		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
    +		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
    +
    +		this._processTabs();
    +		options.active = this._initialActive();
    +
    +		// Take disabling tabs via class attribute from HTML
    +		// into account and update option properly.
    +		if ( $.isArray( options.disabled ) ) {
    +			options.disabled = $.unique( options.disabled.concat(
    +				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
    +					return that.tabs.index( li );
    +				} )
    +			) ).sort();
    +		}
    +
    +		// Check for length avoids error when initializing empty list
    +		if ( this.options.active !== false && this.anchors.length ) {
    +			this.active = this._findActive( options.active );
    +		} else {
    +			this.active = $();
    +		}
    +
    +		this._refresh();
    +
    +		if ( this.active.length ) {
    +			this.load( options.active );
    +		}
    +	},
    +
    +	_initialActive: function() {
    +		var active = this.options.active,
    +			collapsible = this.options.collapsible,
    +			locationHash = location.hash.substring( 1 );
    +
    +		if ( active === null ) {
    +
    +			// check the fragment identifier in the URL
    +			if ( locationHash ) {
    +				this.tabs.each( function( i, tab ) {
    +					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
    +						active = i;
    +						return false;
    +					}
    +				} );
    +			}
    +
    +			// Check for a tab marked active via a class
    +			if ( active === null ) {
    +				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
    +			}
    +
    +			// No active tab, set to false
    +			if ( active === null || active === -1 ) {
    +				active = this.tabs.length ? 0 : false;
    +			}
    +		}
    +
    +		// Handle numbers: negative, out of range
    +		if ( active !== false ) {
    +			active = this.tabs.index( this.tabs.eq( active ) );
    +			if ( active === -1 ) {
    +				active = collapsible ? false : 0;
    +			}
    +		}
    +
    +		// Don't allow collapsible: false and active: false
    +		if ( !collapsible && active === false && this.anchors.length ) {
    +			active = 0;
    +		}
    +
    +		return active;
    +	},
    +
    +	_getCreateEventData: function() {
    +		return {
    +			tab: this.active,
    +			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
    +		};
    +	},
    +
    +	_tabKeydown: function( event ) {
    +		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
    +			selectedIndex = this.tabs.index( focusedTab ),
    +			goingForward = true;
    +
    +		if ( this._handlePageNav( event ) ) {
    +			return;
    +		}
    +
    +		switch ( event.keyCode ) {
    +		case $.ui.keyCode.RIGHT:
    +		case $.ui.keyCode.DOWN:
    +			selectedIndex++;
    +			break;
    +		case $.ui.keyCode.UP:
    +		case $.ui.keyCode.LEFT:
    +			goingForward = false;
    +			selectedIndex--;
    +			break;
    +		case $.ui.keyCode.END:
    +			selectedIndex = this.anchors.length - 1;
    +			break;
    +		case $.ui.keyCode.HOME:
    +			selectedIndex = 0;
    +			break;
    +		case $.ui.keyCode.SPACE:
    +
    +			// Activate only, no collapsing
    +			event.preventDefault();
    +			clearTimeout( this.activating );
    +			this._activate( selectedIndex );
    +			return;
    +		case $.ui.keyCode.ENTER:
    +
    +			// Toggle (cancel delayed activation, allow collapsing)
    +			event.preventDefault();
    +			clearTimeout( this.activating );
    +
    +			// Determine if we should collapse or activate
    +			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
    +			return;
    +		default:
    +			return;
    +		}
    +
    +		// Focus the appropriate tab, based on which key was pressed
    +		event.preventDefault();
    +		clearTimeout( this.activating );
    +		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
    +
    +		// Navigating with control/command key will prevent automatic activation
    +		if ( !event.ctrlKey && !event.metaKey ) {
    +
    +			// Update aria-selected immediately so that AT think the tab is already selected.
    +			// Otherwise AT may confuse the user by stating that they need to activate the tab,
    +			// but the tab will already be activated by the time the announcement finishes.
    +			focusedTab.attr( "aria-selected", "false" );
    +			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
    +
    +			this.activating = this._delay( function() {
    +				this.option( "active", selectedIndex );
    +			}, this.delay );
    +		}
    +	},
    +
    +	_panelKeydown: function( event ) {
    +		if ( this._handlePageNav( event ) ) {
    +			return;
    +		}
    +
    +		// Ctrl+up moves focus to the current tab
    +		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
    +			event.preventDefault();
    +			this.active.trigger( "focus" );
    +		}
    +	},
    +
    +	// Alt+page up/down moves focus to the previous/next tab (and activates)
    +	_handlePageNav: function( event ) {
    +		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
    +			this._activate( this._focusNextTab( this.options.active - 1, false ) );
    +			return true;
    +		}
    +		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
    +			this._activate( this._focusNextTab( this.options.active + 1, true ) );
    +			return true;
    +		}
    +	},
    +
    +	_findNextTab: function( index, goingForward ) {
    +		var lastTabIndex = this.tabs.length - 1;
    +
    +		function constrain() {
    +			if ( index > lastTabIndex ) {
    +				index = 0;
    +			}
    +			if ( index < 0 ) {
    +				index = lastTabIndex;
    +			}
    +			return index;
    +		}
    +
    +		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
    +			index = goingForward ? index + 1 : index - 1;
    +		}
    +
    +		return index;
    +	},
    +
    +	_focusNextTab: function( index, goingForward ) {
    +		index = this._findNextTab( index, goingForward );
    +		this.tabs.eq( index ).trigger( "focus" );
    +		return index;
    +	},
    +
    +	_setOption: function( key, value ) {
    +		if ( key === "active" ) {
    +
    +			// _activate() will handle invalid values and update this.options
    +			this._activate( value );
    +			return;
    +		}
    +
    +		this._super( key, value );
    +
    +		if ( key === "collapsible" ) {
    +			this._toggleClass( "ui-tabs-collapsible", null, value );
    +
    +			// Setting collapsible: false while collapsed; open first panel
    +			if ( !value && this.options.active === false ) {
    +				this._activate( 0 );
    +			}
    +		}
    +
    +		if ( key === "event" ) {
    +			this._setupEvents( value );
    +		}
    +
    +		if ( key === "heightStyle" ) {
    +			this._setupHeightStyle( value );
    +		}
    +	},
    +
    +	_sanitizeSelector: function( hash ) {
    +		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
    +	},
    +
    +	refresh: function() {
    +		var options = this.options,
    +			lis = this.tablist.children( ":has(a[href])" );
    +
    +		// Get disabled tabs from class attribute from HTML
    +		// this will get converted to a boolean if needed in _refresh()
    +		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
    +			return lis.index( tab );
    +		} );
    +
    +		this._processTabs();
    +
    +		// Was collapsed or no tabs
    +		if ( options.active === false || !this.anchors.length ) {
    +			options.active = false;
    +			this.active = $();
    +
    +		// was active, but active tab is gone
    +		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
    +
    +			// all remaining tabs are disabled
    +			if ( this.tabs.length === options.disabled.length ) {
    +				options.active = false;
    +				this.active = $();
    +
    +			// activate previous tab
    +			} else {
    +				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
    +			}
    +
    +		// was active, active tab still exists
    +		} else {
    +
    +			// make sure active index is correct
    +			options.active = this.tabs.index( this.active );
    +		}
    +
    +		this._refresh();
    +	},
    +
    +	_refresh: function() {
    +		this._setOptionDisabled( this.options.disabled );
    +		this._setupEvents( this.options.event );
    +		this._setupHeightStyle( this.options.heightStyle );
    +
    +		this.tabs.not( this.active ).attr( {
    +			"aria-selected": "false",
    +			"aria-expanded": "false",
    +			tabIndex: -1
    +		} );
    +		this.panels.not( this._getPanelForTab( this.active ) )
    +			.hide()
    +			.attr( {
    +				"aria-hidden": "true"
    +			} );
    +
    +		// Make sure one tab is in the tab order
    +		if ( !this.active.length ) {
    +			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
    +		} else {
    +			this.active
    +				.attr( {
    +					"aria-selected": "true",
    +					"aria-expanded": "true",
    +					tabIndex: 0
    +				} );
    +			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
    +			this._getPanelForTab( this.active )
    +				.show()
    +				.attr( {
    +					"aria-hidden": "false"
    +				} );
    +		}
    +	},
    +
    +	_processTabs: function() {
    +		var that = this,
    +			prevTabs = this.tabs,
    +			prevAnchors = this.anchors,
    +			prevPanels = this.panels;
    +
    +		this.tablist = this._getList().attr( "role", "tablist" );
    +		this._addClass( this.tablist, "ui-tabs-nav",
    +			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
    +
    +		// Prevent users from focusing disabled tabs via click
    +		this.tablist
    +			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
    +				if ( $( this ).is( ".ui-state-disabled" ) ) {
    +					event.preventDefault();
    +				}
    +			} )
    +
    +			// Support: IE <9
    +			// Preventing the default action in mousedown doesn't prevent IE
    +			// from focusing the element, so if the anchor gets focused, blur.
    +			// We don't have to worry about focusing the previously focused
    +			// element since clicking on a non-focusable element should focus
    +			// the body anyway.
    +			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
    +				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
    +					this.blur();
    +				}
    +			} );
    +
    +		this.tabs = this.tablist.find( "> li:has(a[href])" )
    +			.attr( {
    +				role: "tab",
    +				tabIndex: -1
    +			} );
    +		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
    +
    +		this.anchors = this.tabs.map( function() {
    +			return $( "a", this )[ 0 ];
    +		} )
    +			.attr( {
    +				role: "presentation",
    +				tabIndex: -1
    +			} );
    +		this._addClass( this.anchors, "ui-tabs-anchor" );
    +
    +		this.panels = $();
    +
    +		this.anchors.each( function( i, anchor ) {
    +			var selector, panel, panelId,
    +				anchorId = $( anchor ).uniqueId().attr( "id" ),
    +				tab = $( anchor ).closest( "li" ),
    +				originalAriaControls = tab.attr( "aria-controls" );
    +
    +			// Inline tab
    +			if ( that._isLocal( anchor ) ) {
    +				selector = anchor.hash;
    +				panelId = selector.substring( 1 );
    +				panel = that.element.find( that._sanitizeSelector( selector ) );
    +
    +			// remote tab
    +			} else {
    +
    +				// If the tab doesn't already have aria-controls,
    +				// generate an id by using a throw-away element
    +				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
    +				selector = "#" + panelId;
    +				panel = that.element.find( selector );
    +				if ( !panel.length ) {
    +					panel = that._createPanel( panelId );
    +					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
    +				}
    +				panel.attr( "aria-live", "polite" );
    +			}
    +
    +			if ( panel.length ) {
    +				that.panels = that.panels.add( panel );
    +			}
    +			if ( originalAriaControls ) {
    +				tab.data( "ui-tabs-aria-controls", originalAriaControls );
    +			}
    +			tab.attr( {
    +				"aria-controls": panelId,
    +				"aria-labelledby": anchorId
    +			} );
    +			panel.attr( "aria-labelledby", anchorId );
    +		} );
    +
    +		this.panels.attr( "role", "tabpanel" );
    +		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
    +
    +		// Avoid memory leaks (#10056)
    +		if ( prevTabs ) {
    +			this._off( prevTabs.not( this.tabs ) );
    +			this._off( prevAnchors.not( this.anchors ) );
    +			this._off( prevPanels.not( this.panels ) );
    +		}
    +	},
    +
    +	// Allow overriding how to find the list for rare usage scenarios (#7715)
    +	_getList: function() {
    +		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
    +	},
    +
    +	_createPanel: function( id ) {
    +		return $( "<div>" )
    +			.attr( "id", id )
    +			.data( "ui-tabs-destroy", true );
    +	},
    +
    +	_setOptionDisabled: function( disabled ) {
    +		var currentItem, li, i;
    +
    +		if ( $.isArray( disabled ) ) {
    +			if ( !disabled.length ) {
    +				disabled = false;
    +			} else if ( disabled.length === this.anchors.length ) {
    +				disabled = true;
    +			}
    +		}
    +
    +		// Disable tabs
    +		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
    +			currentItem = $( li );
    +			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
    +				currentItem.attr( "aria-disabled", "true" );
    +				this._addClass( currentItem, null, "ui-state-disabled" );
    +			} else {
    +				currentItem.removeAttr( "aria-disabled" );
    +				this._removeClass( currentItem, null, "ui-state-disabled" );
    +			}
    +		}
    +
    +		this.options.disabled = disabled;
    +
    +		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
    +			disabled === true );
    +	},
    +
    +	_setupEvents: function( event ) {
    +		var events = {};
    +		if ( event ) {
    +			$.each( event.split( " " ), function( index, eventName ) {
    +				events[ eventName ] = "_eventHandler";
    +			} );
    +		}
    +
    +		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
    +
    +		// Always prevent the default action, even when disabled
    +		this._on( true, this.anchors, {
    +			click: function( event ) {
    +				event.preventDefault();
    +			}
    +		} );
    +		this._on( this.anchors, events );
    +		this._on( this.tabs, { keydown: "_tabKeydown" } );
    +		this._on( this.panels, { keydown: "_panelKeydown" } );
    +
    +		this._focusable( this.tabs );
    +		this._hoverable( this.tabs );
    +	},
    +
    +	_setupHeightStyle: function( heightStyle ) {
    +		var maxHeight,
    +			parent = this.element.parent();
    +
    +		if ( heightStyle === "fill" ) {
    +			maxHeight = parent.height();
    +			maxHeight -= this.element.outerHeight() - this.element.height();
    +
    +			this.element.siblings( ":visible" ).each( function() {
    +				var elem = $( this ),
    +					position = elem.css( "position" );
    +
    +				if ( position === "absolute" || position === "fixed" ) {
    +					return;
    +				}
    +				maxHeight -= elem.outerHeight( true );
    +			} );
    +
    +			this.element.children().not( this.panels ).each( function() {
    +				maxHeight -= $( this ).outerHeight( true );
    +			} );
    +
    +			this.panels.each( function() {
    +				$( this ).height( Math.max( 0, maxHeight -
    +					$( this ).innerHeight() + $( this ).height() ) );
    +			} )
    +				.css( "overflow", "auto" );
    +		} else if ( heightStyle === "auto" ) {
    +			maxHeight = 0;
    +			this.panels.each( function() {
    +				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
    +			} ).height( maxHeight );
    +		}
    +	},
    +
    +	_eventHandler: function( event ) {
    +		var options = this.options,
    +			active = this.active,
    +			anchor = $( event.currentTarget ),
    +			tab = anchor.closest( "li" ),
    +			clickedIsActive = tab[ 0 ] === active[ 0 ],
    +			collapsing = clickedIsActive && options.collapsible,
    +			toShow = collapsing ? $() : this._getPanelForTab( tab ),
    +			toHide = !active.length ? $() : this._getPanelForTab( active ),
    +			eventData = {
    +				oldTab: active,
    +				oldPanel: toHide,
    +				newTab: collapsing ? $() : tab,
    +				newPanel: toShow
    +			};
    +
    +		event.preventDefault();
    +
    +		if ( tab.hasClass( "ui-state-disabled" ) ||
    +
    +				// tab is already loading
    +				tab.hasClass( "ui-tabs-loading" ) ||
    +
    +				// can't switch durning an animation
    +				this.running ||
    +
    +				// click on active header, but not collapsible
    +				( clickedIsActive && !options.collapsible ) ||
    +
    +				// allow canceling activation
    +				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
    +			return;
    +		}
    +
    +		options.active = collapsing ? false : this.tabs.index( tab );
    +
    +		this.active = clickedIsActive ? $() : tab;
    +		if ( this.xhr ) {
    +			this.xhr.abort();
    +		}
    +
    +		if ( !toHide.length && !toShow.length ) {
    +			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
    +		}
    +
    +		if ( toShow.length ) {
    +			this.load( this.tabs.index( tab ), event );
    +		}
    +		this._toggle( event, eventData );
    +	},
    +
    +	// Handles show/hide for selecting tabs
    +	_toggle: function( event, eventData ) {
    +		var that = this,
    +			toShow = eventData.newPanel,
    +			toHide = eventData.oldPanel;
    +
    +		this.running = true;
    +
    +		function complete() {
    +			that.running = false;
    +			that._trigger( "activate", event, eventData );
    +		}
    +
    +		function show() {
    +			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
    +
    +			if ( toShow.length && that.options.show ) {
    +				that._show( toShow, that.options.show, complete );
    +			} else {
    +				toShow.show();
    +				complete();
    +			}
    +		}
    +
    +		// Start out by hiding, then showing, then completing
    +		if ( toHide.length && this.options.hide ) {
    +			this._hide( toHide, this.options.hide, function() {
    +				that._removeClass( eventData.oldTab.closest( "li" ),
    +					"ui-tabs-active", "ui-state-active" );
    +				show();
    +			} );
    +		} else {
    +			this._removeClass( eventData.oldTab.closest( "li" ),
    +				"ui-tabs-active", "ui-state-active" );
    +			toHide.hide();
    +			show();
    +		}
    +
    +		toHide.attr( "aria-hidden", "true" );
    +		eventData.oldTab.attr( {
    +			"aria-selected": "false",
    +			"aria-expanded": "false"
    +		} );
    +
    +		// If we're switching tabs, remove the old tab from the tab order.
    +		// If we're opening from collapsed state, remove the previous tab from the tab order.
    +		// If we're collapsing, then keep the collapsing tab in the tab order.
    +		if ( toShow.length && toHide.length ) {
    +			eventData.oldTab.attr( "tabIndex", -1 );
    +		} else if ( toShow.length ) {
    +			this.tabs.filter( function() {
    +				return $( this ).attr( "tabIndex" ) === 0;
    +			} )
    +				.attr( "tabIndex", -1 );
    +		}
    +
    +		toShow.attr( "aria-hidden", "false" );
    +		eventData.newTab.attr( {
    +			"aria-selected": "true",
    +			"aria-expanded": "true",
    +			tabIndex: 0
    +		} );
    +	},
    +
    +	_activate: function( index ) {
    +		var anchor,
    +			active = this._findActive( index );
    +
    +		// Trying to activate the already active panel
    +		if ( active[ 0 ] === this.active[ 0 ] ) {
    +			return;
    +		}
    +
    +		// Trying to collapse, simulate a click on the current active header
    +		if ( !active.length ) {
    +			active = this.active;
    +		}
    +
    +		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
    +		this._eventHandler( {
    +			target: anchor,
    +			currentTarget: anchor,
    +			preventDefault: $.noop
    +		} );
    +	},
    +
    +	_findActive: function( index ) {
    +		return index === false ? $() : this.tabs.eq( index );
    +	},
    +
    +	_getIndex: function( index ) {
    +
    +		// meta-function to give users option to provide a href string instead of a numerical index.
    +		if ( typeof index === "string" ) {
    +			index = this.anchors.index( this.anchors.filter( "[href$='" +
    +				$.ui.escapeSelector( index ) + "']" ) );
    +		}
    +
    +		return index;
    +	},
    +
    +	_destroy: function() {
    +		if ( this.xhr ) {
    +			this.xhr.abort();
    +		}
    +
    +		this.tablist
    +			.removeAttr( "role" )
    +			.off( this.eventNamespace );
    +
    +		this.anchors
    +			.removeAttr( "role tabIndex" )
    +			.removeUniqueId();
    +
    +		this.tabs.add( this.panels ).each( function() {
    +			if ( $.data( this, "ui-tabs-destroy" ) ) {
    +				$( this ).remove();
    +			} else {
    +				$( this ).removeAttr( "role tabIndex " +
    +					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
    +			}
    +		} );
    +
    +		this.tabs.each( function() {
    +			var li = $( this ),
    +				prev = li.data( "ui-tabs-aria-controls" );
    +			if ( prev ) {
    +				li
    +					.attr( "aria-controls", prev )
    +					.removeData( "ui-tabs-aria-controls" );
    +			} else {
    +				li.removeAttr( "aria-controls" );
    +			}
    +		} );
    +
    +		this.panels.show();
    +
    +		if ( this.options.heightStyle !== "content" ) {
    +			this.panels.css( "height", "" );
    +		}
    +	},
    +
    +	enable: function( index ) {
    +		var disabled = this.options.disabled;
    +		if ( disabled === false ) {
    +			return;
    +		}
    +
    +		if ( index === undefined ) {
    +			disabled = false;
    +		} else {
    +			index = this._getIndex( index );
    +			if ( $.isArray( disabled ) ) {
    +				disabled = $.map( disabled, function( num ) {
    +					return num !== index ? num : null;
    +				} );
    +			} else {
    +				disabled = $.map( this.tabs, function( li, num ) {
    +					return num !== index ? num : null;
    +				} );
    +			}
    +		}
    +		this._setOptionDisabled( disabled );
    +	},
    +
    +	disable: function( index ) {
    +		var disabled = this.options.disabled;
    +		if ( disabled === true ) {
    +			return;
    +		}
    +
    +		if ( index === undefined ) {
    +			disabled = true;
    +		} else {
    +			index = this._getIndex( index );
    +			if ( $.inArray( index, disabled ) !== -1 ) {
    +				return;
    +			}
    +			if ( $.isArray( disabled ) ) {
    +				disabled = $.merge( [ index ], disabled ).sort();
    +			} else {
    +				disabled = [ index ];
    +			}
    +		}
    +		this._setOptionDisabled( disabled );
    +	},
    +
    +	load: function( index, event ) {
    +		index = this._getIndex( index );
    +		var that = this,
    +			tab = this.tabs.eq( index ),
    +			anchor = tab.find( ".ui-tabs-anchor" ),
    +			panel = this._getPanelForTab( tab ),
    +			eventData = {
    +				tab: tab,
    +				panel: panel
    +			},
    +			complete = function( jqXHR, status ) {
    +				if ( status === "abort" ) {
    +					that.panels.stop( false, true );
    +				}
    +
    +				that._removeClass( tab, "ui-tabs-loading" );
    +				panel.removeAttr( "aria-busy" );
    +
    +				if ( jqXHR === that.xhr ) {
    +					delete that.xhr;
    +				}
    +			};
    +
    +		// Not remote
    +		if ( this._isLocal( anchor[ 0 ] ) ) {
    +			return;
    +		}
    +
    +		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
    +
    +		// Support: jQuery <1.8
    +		// jQuery <1.8 returns false if the request is canceled in beforeSend,
    +		// but as of 1.8, $.ajax() always returns a jqXHR object.
    +		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
    +			this._addClass( tab, "ui-tabs-loading" );
    +			panel.attr( "aria-busy", "true" );
    +
    +			this.xhr
    +				.done( function( response, status, jqXHR ) {
    +
    +					// support: jQuery <1.8
    +					// http://bugs.jquery.com/ticket/11778
    +					setTimeout( function() {
    +						panel.html( response );
    +						that._trigger( "load", event, eventData );
    +
    +						complete( jqXHR, status );
    +					}, 1 );
    +				} )
    +				.fail( function( jqXHR, status ) {
    +
    +					// support: jQuery <1.8
    +					// http://bugs.jquery.com/ticket/11778
    +					setTimeout( function() {
    +						complete( jqXHR, status );
    +					}, 1 );
    +				} );
    +		}
    +	},
    +
    +	_ajaxSettings: function( anchor, event, eventData ) {
    +		var that = this;
    +		return {
    +
    +			// Support: IE <11 only
    +			// Strip any hash that exists to prevent errors with the Ajax request
    +			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
    +			beforeSend: function( jqXHR, settings ) {
    +				return that._trigger( "beforeLoad", event,
    +					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
    +			}
    +		};
    +	},
    +
    +	_getPanelForTab: function( tab ) {
    +		var id = $( tab ).attr( "aria-controls" );
    +		return this.element.find( this._sanitizeSelector( "#" + id ) );
    +	}
    +} );
    +
    +// DEPRECATED
    +// TODO: Switch return back to widget declaration at top of file when this is removed
    +if ( $.uiBackCompat !== false ) {
    +
    +	// Backcompat for ui-tab class (now ui-tabs-tab)
    +	$.widget( "ui.tabs", $.ui.tabs, {
    +		_processTabs: function() {
    +			this._superApply( arguments );
    +			this._addClass( this.tabs, "ui-tab" );
    +		}
    +	} );
    +}
    +
    +var widgetsTabs = $.ui.tabs;
    +
    +
    +/*!
    + * jQuery UI Tooltip 1.12.1
    + * http://jqueryui.com
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license.
    + * http://jquery.org/license
    + */
    +
    +//>>label: Tooltip
    +//>>group: Widgets
    +//>>description: Shows additional information for any element on hover or focus.
    +//>>docs: http://api.jqueryui.com/tooltip/
    +//>>demos: http://jqueryui.com/tooltip/
    +//>>css.structure: ../../themes/base/core.css
    +//>>css.structure: ../../themes/base/tooltip.css
    +//>>css.theme: ../../themes/base/theme.css
    +
    +
    +
    +$.widget( "ui.tooltip", {
    +	version: "1.12.1",
    +	options: {
    +		classes: {
    +			"ui-tooltip": "ui-corner-all ui-widget-shadow"
    +		},
    +		content: function() {
    +
    +			// support: IE<9, Opera in jQuery <1.7
    +			// .text() can't accept undefined, so coerce to a string
    +			var title = $( this ).attr( "title" ) || "";
    +
    +			// Escape title, since we're going from an attribute to raw HTML
    +			return $( "<a>" ).text( title ).html();
    +		},
    +		hide: true,
    +
    +		// Disabled elements have inconsistent behavior across browsers (#8661)
    +		items: "[title]:not([disabled])",
    +		position: {
    +			my: "left top+15",
    +			at: "left bottom",
    +			collision: "flipfit flip"
    +		},
    +		show: true,
    +		track: false,
    +
    +		// Callbacks
    +		close: null,
    +		open: null
    +	},
    +
    +	_addDescribedBy: function( elem, id ) {
    +		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
    +		describedby.push( id );
    +		elem
    +			.data( "ui-tooltip-id", id )
    +			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
    +	},
    +
    +	_removeDescribedBy: function( elem ) {
    +		var id = elem.data( "ui-tooltip-id" ),
    +			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
    +			index = $.inArray( id, describedby );
    +
    +		if ( index !== -1 ) {
    +			describedby.splice( index, 1 );
    +		}
    +
    +		elem.removeData( "ui-tooltip-id" );
    +		describedby = $.trim( describedby.join( " " ) );
    +		if ( describedby ) {
    +			elem.attr( "aria-describedby", describedby );
    +		} else {
    +			elem.removeAttr( "aria-describedby" );
    +		}
    +	},
    +
    +	_create: function() {
    +		this._on( {
    +			mouseover: "open",
    +			focusin: "open"
    +		} );
    +
    +		// IDs of generated tooltips, needed for destroy
    +		this.tooltips = {};
    +
    +		// IDs of parent tooltips where we removed the title attribute
    +		this.parents = {};
    +
    +		// Append the aria-live region so tooltips announce correctly
    +		this.liveRegion = $( "<div>" )
    +			.attr( {
    +				role: "log",
    +				"aria-live": "assertive",
    +				"aria-relevant": "additions"
    +			} )
    +			.appendTo( this.document[ 0 ].body );
    +		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
    +
    +		this.disabledTitles = $( [] );
    +	},
    +
    +	_setOption: function( key, value ) {
    +		var that = this;
    +
    +		this._super( key, value );
    +
    +		if ( key === "content" ) {
    +			$.each( this.tooltips, function( id, tooltipData ) {
    +				that._updateContent( tooltipData.element );
    +			} );
    +		}
    +	},
    +
    +	_setOptionDisabled: function( value ) {
    +		this[ value ? "_disable" : "_enable" ]();
    +	},
    +
    +	_disable: function() {
    +		var that = this;
    +
    +		// Close open tooltips
    +		$.each( this.tooltips, function( id, tooltipData ) {
    +			var event = $.Event( "blur" );
    +			event.target = event.currentTarget = tooltipData.element[ 0 ];
    +			that.close( event, true );
    +		} );
    +
    +		// Remove title attributes to prevent native tooltips
    +		this.disabledTitles = this.disabledTitles.add(
    +			this.element.find( this.options.items ).addBack()
    +				.filter( function() {
    +					var element = $( this );
    +					if ( element.is( "[title]" ) ) {
    +						return element
    +							.data( "ui-tooltip-title", element.attr( "title" ) )
    +							.removeAttr( "title" );
    +					}
    +				} )
    +		);
    +	},
    +
    +	_enable: function() {
    +
    +		// restore title attributes
    +		this.disabledTitles.each( function() {
    +			var element = $( this );
    +			if ( element.data( "ui-tooltip-title" ) ) {
    +				element.attr( "title", element.data( "ui-tooltip-title" ) );
    +			}
    +		} );
    +		this.disabledTitles = $( [] );
    +	},
    +
    +	open: function( event ) {
    +		var that = this,
    +			target = $( event ? event.target : this.element )
    +
    +				// we need closest here due to mouseover bubbling,
    +				// but always pointing at the same event target
    +				.closest( this.options.items );
    +
    +		// No element to show a tooltip for or the tooltip is already open
    +		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
    +			return;
    +		}
    +
    +		if ( target.attr( "title" ) ) {
    +			target.data( "ui-tooltip-title", target.attr( "title" ) );
    +		}
    +
    +		target.data( "ui-tooltip-open", true );
    +
    +		// Kill parent tooltips, custom or native, for hover
    +		if ( event && event.type === "mouseover" ) {
    +			target.parents().each( function() {
    +				var parent = $( this ),
    +					blurEvent;
    +				if ( parent.data( "ui-tooltip-open" ) ) {
    +					blurEvent = $.Event( "blur" );
    +					blurEvent.target = blurEvent.currentTarget = this;
    +					that.close( blurEvent, true );
    +				}
    +				if ( parent.attr( "title" ) ) {
    +					parent.uniqueId();
    +					that.parents[ this.id ] = {
    +						element: this,
    +						title: parent.attr( "title" )
    +					};
    +					parent.attr( "title", "" );
    +				}
    +			} );
    +		}
    +
    +		this._registerCloseHandlers( event, target );
    +		this._updateContent( target, event );
    +	},
    +
    +	_updateContent: function( target, event ) {
    +		var content,
    +			contentOption = this.options.content,
    +			that = this,
    +			eventType = event ? event.type : null;
    +
    +		if ( typeof contentOption === "string" || contentOption.nodeType ||
    +				contentOption.jquery ) {
    +			return this._open( event, target, contentOption );
    +		}
    +
    +		content = contentOption.call( target[ 0 ], function( response ) {
    +
    +			// IE may instantly serve a cached response for ajax requests
    +			// delay this call to _open so the other call to _open runs first
    +			that._delay( function() {
    +
    +				// Ignore async response if tooltip was closed already
    +				if ( !target.data( "ui-tooltip-open" ) ) {
    +					return;
    +				}
    +
    +				// JQuery creates a special event for focusin when it doesn't
    +				// exist natively. To improve performance, the native event
    +				// object is reused and the type is changed. Therefore, we can't
    +				// rely on the type being correct after the event finished
    +				// bubbling, so we set it back to the previous value. (#8740)
    +				if ( event ) {
    +					event.type = eventType;
    +				}
    +				this._open( event, target, response );
    +			} );
    +		} );
    +		if ( content ) {
    +			this._open( event, target, content );
    +		}
    +	},
    +
    +	_open: function( event, target, content ) {
    +		var tooltipData, tooltip, delayedShow, a11yContent,
    +			positionOption = $.extend( {}, this.options.position );
    +
    +		if ( !content ) {
    +			return;
    +		}
    +
    +		// Content can be updated multiple times. If the tooltip already
    +		// exists, then just update the content and bail.
    +		tooltipData = this._find( target );
    +		if ( tooltipData ) {
    +			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
    +			return;
    +		}
    +
    +		// If we have a title, clear it to prevent the native tooltip
    +		// we have to check first to avoid defining a title if none exists
    +		// (we don't want to cause an element to start matching [title])
    +		//
    +		// We use removeAttr only for key events, to allow IE to export the correct
    +		// accessible attributes. For mouse events, set to empty string to avoid
    +		// native tooltip showing up (happens only when removing inside mouseover).
    +		if ( target.is( "[title]" ) ) {
    +			if ( event && event.type === "mouseover" ) {
    +				target.attr( "title", "" );
    +			} else {
    +				target.removeAttr( "title" );
    +			}
    +		}
    +
    +		tooltipData = this._tooltip( target );
    +		tooltip = tooltipData.tooltip;
    +		this._addDescribedBy( target, tooltip.attr( "id" ) );
    +		tooltip.find( ".ui-tooltip-content" ).html( content );
    +
    +		// Support: Voiceover on OS X, JAWS on IE <= 9
    +		// JAWS announces deletions even when aria-relevant="additions"
    +		// Voiceover will sometimes re-read the entire log region's contents from the beginning
    +		this.liveRegion.children().hide();
    +		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
    +		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
    +		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
    +		a11yContent.appendTo( this.liveRegion );
    +
    +		function position( event ) {
    +			positionOption.of = event;
    +			if ( tooltip.is( ":hidden" ) ) {
    +				return;
    +			}
    +			tooltip.position( positionOption );
    +		}
    +		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
    +			this._on( this.document, {
    +				mousemove: position
    +			} );
    +
    +			// trigger once to override element-relative positioning
    +			position( event );
    +		} else {
    +			tooltip.position( $.extend( {
    +				of: target
    +			}, this.options.position ) );
    +		}
    +
    +		tooltip.hide();
    +
    +		this._show( tooltip, this.options.show );
    +
    +		// Handle tracking tooltips that are shown with a delay (#8644). As soon
    +		// as the tooltip is visible, position the tooltip using the most recent
    +		// event.
    +		// Adds the check to add the timers only when both delay and track options are set (#14682)
    +		if ( this.options.track && this.options.show && this.options.show.delay ) {
    +			delayedShow = this.delayedShow = setInterval( function() {
    +				if ( tooltip.is( ":visible" ) ) {
    +					position( positionOption.of );
    +					clearInterval( delayedShow );
    +				}
    +			}, $.fx.interval );
    +		}
    +
    +		this._trigger( "open", event, { tooltip: tooltip } );
    +	},
    +
    +	_registerCloseHandlers: function( event, target ) {
    +		var events = {
    +			keyup: function( event ) {
    +				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
    +					var fakeEvent = $.Event( event );
    +					fakeEvent.currentTarget = target[ 0 ];
    +					this.close( fakeEvent, true );
    +				}
    +			}
    +		};
    +
    +		// Only bind remove handler for delegated targets. Non-delegated
    +		// tooltips will handle this in destroy.
    +		if ( target[ 0 ] !== this.element[ 0 ] ) {
    +			events.remove = function() {
    +				this._removeTooltip( this._find( target ).tooltip );
    +			};
    +		}
    +
    +		if ( !event || event.type === "mouseover" ) {
    +			events.mouseleave = "close";
    +		}
    +		if ( !event || event.type === "focusin" ) {
    +			events.focusout = "close";
    +		}
    +		this._on( true, target, events );
    +	},
    +
    +	close: function( event ) {
    +		var tooltip,
    +			that = this,
    +			target = $( event ? event.currentTarget : this.element ),
    +			tooltipData = this._find( target );
    +
    +		// The tooltip may already be closed
    +		if ( !tooltipData ) {
    +
    +			// We set ui-tooltip-open immediately upon open (in open()), but only set the
    +			// additional data once there's actually content to show (in _open()). So even if the
    +			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
    +			// the period between open() and _open().
    +			target.removeData( "ui-tooltip-open" );
    +			return;
    +		}
    +
    +		tooltip = tooltipData.tooltip;
    +
    +		// Disabling closes the tooltip, so we need to track when we're closing
    +		// to avoid an infinite loop in case the tooltip becomes disabled on close
    +		if ( tooltipData.closing ) {
    +			return;
    +		}
    +
    +		// Clear the interval for delayed tracking tooltips
    +		clearInterval( this.delayedShow );
    +
    +		// Only set title if we had one before (see comment in _open())
    +		// If the title attribute has changed since open(), don't restore
    +		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
    +			target.attr( "title", target.data( "ui-tooltip-title" ) );
    +		}
    +
    +		this._removeDescribedBy( target );
    +
    +		tooltipData.hiding = true;
    +		tooltip.stop( true );
    +		this._hide( tooltip, this.options.hide, function() {
    +			that._removeTooltip( $( this ) );
    +		} );
    +
    +		target.removeData( "ui-tooltip-open" );
    +		this._off( target, "mouseleave focusout keyup" );
    +
    +		// Remove 'remove' binding only on delegated targets
    +		if ( target[ 0 ] !== this.element[ 0 ] ) {
    +			this._off( target, "remove" );
    +		}
    +		this._off( this.document, "mousemove" );
    +
    +		if ( event && event.type === "mouseleave" ) {
    +			$.each( this.parents, function( id, parent ) {
    +				$( parent.element ).attr( "title", parent.title );
    +				delete that.parents[ id ];
    +			} );
    +		}
    +
    +		tooltipData.closing = true;
    +		this._trigger( "close", event, { tooltip: tooltip } );
    +		if ( !tooltipData.hiding ) {
    +			tooltipData.closing = false;
    +		}
    +	},
    +
    +	_tooltip: function( element ) {
    +		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
    +			content = $( "<div>" ).appendTo( tooltip ),
    +			id = tooltip.uniqueId().attr( "id" );
    +
    +		this._addClass( content, "ui-tooltip-content" );
    +		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
    +
    +		tooltip.appendTo( this._appendTo( element ) );
    +
    +		return this.tooltips[ id ] = {
    +			element: element,
    +			tooltip: tooltip
    +		};
    +	},
    +
    +	_find: function( target ) {
    +		var id = target.data( "ui-tooltip-id" );
    +		return id ? this.tooltips[ id ] : null;
    +	},
    +
    +	_removeTooltip: function( tooltip ) {
    +		tooltip.remove();
    +		delete this.tooltips[ tooltip.attr( "id" ) ];
    +	},
    +
    +	_appendTo: function( target ) {
    +		var element = target.closest( ".ui-front, dialog" );
    +
    +		if ( !element.length ) {
    +			element = this.document[ 0 ].body;
    +		}
    +
    +		return element;
    +	},
    +
    +	_destroy: function() {
    +		var that = this;
    +
    +		// Close open tooltips
    +		$.each( this.tooltips, function( id, tooltipData ) {
    +
    +			// Delegate to close method to handle common cleanup
    +			var event = $.Event( "blur" ),
    +				element = tooltipData.element;
    +			event.target = event.currentTarget = element[ 0 ];
    +			that.close( event, true );
    +
    +			// Remove immediately; destroying an open tooltip doesn't use the
    +			// hide animation
    +			$( "#" + id ).remove();
    +
    +			// Restore the title
    +			if ( element.data( "ui-tooltip-title" ) ) {
    +
    +				// If the title attribute has changed since open(), don't restore
    +				if ( !element.attr( "title" ) ) {
    +					element.attr( "title", element.data( "ui-tooltip-title" ) );
    +				}
    +				element.removeData( "ui-tooltip-title" );
    +			}
    +		} );
    +		this.liveRegion.remove();
    +	}
    +} );
    +
    +// DEPRECATED
    +// TODO: Switch return back to widget declaration at top of file when this is removed
    +if ( $.uiBackCompat !== false ) {
    +
    +	// Backcompat for tooltipClass option
    +	$.widget( "ui.tooltip", $.ui.tooltip, {
    +		options: {
    +			tooltipClass: null
    +		},
    +		_tooltip: function() {
    +			var tooltipData = this._superApply( arguments );
    +			if ( this.options.tooltipClass ) {
    +				tooltipData.tooltip.addClass( this.options.tooltipClass );
    +			}
    +			return tooltipData;
    +		}
    +	} );
    +}
    +
    +var widgetsTooltip = $.ui.tooltip;
    +
    +
    +
    +
    +}));
    \ No newline at end of file
    diff --git a/vendor/jquery.js b/vendor/jquery.js
    new file mode 100644
    index 0000000..9b5206b
    --- /dev/null
    +++ b/vendor/jquery.js
    @@ -0,0 +1,10364 @@
    +/*!
    + * jQuery JavaScript Library v3.3.1
    + * https://jquery.com/
    + *
    + * Includes Sizzle.js
    + * https://sizzlejs.com/
    + *
    + * Copyright JS Foundation and other contributors
    + * Released under the MIT license
    + * https://jquery.org/license
    + *
    + * Date: 2018-01-20T17:24Z
    + */
    +( function( global, factory ) {
    +
    +	"use strict";
    +
    +	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 have a `window` with a `document`
    +		// (such as Node.js), expose a 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 ) {
    +
    +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
    +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
    +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
    +// enough that all such attempts are guarded in a try block.
    +"use strict";
    +
    +var arr = [];
    +
    +var document = window.document;
    +
    +var getProto = Object.getPrototypeOf;
    +
    +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 fnToString = hasOwn.toString;
    +
    +var ObjectFunctionString = fnToString.call( Object );
    +
    +var support = {};
    +
    +var isFunction = function isFunction( obj ) {
    +
    +      // Support: Chrome <=57, Firefox <=52
    +      // In some browsers, typeof returns "function" for HTML <object> elements
    +      // (i.e., `typeof document.createElement( "object" ) === "function"`).
    +      // We don't want to classify *any* DOM node as a function.
    +      return typeof obj === "function" && typeof obj.nodeType !== "number";
    +  };
    +
    +
    +var isWindow = function isWindow( obj ) {
    +		return obj != null && obj === obj.window;
    +	};
    +
    +
    +
    +
    +	var preservedScriptAttributes = {
    +		type: true,
    +		src: true,
    +		noModule: true
    +	};
    +
    +	function DOMEval( code, doc, node ) {
    +		doc = doc || document;
    +
    +		var i,
    +			script = doc.createElement( "script" );
    +
    +		script.text = code;
    +		if ( node ) {
    +			for ( i in preservedScriptAttributes ) {
    +				if ( node[ i ] ) {
    +					script[ i ] = node[ i ];
    +				}
    +			}
    +		}
    +		doc.head.appendChild( script ).parentNode.removeChild( script );
    +	}
    +
    +
    +function toType( obj ) {
    +	if ( obj == null ) {
    +		return obj + "";
    +	}
    +
    +	// Support: Android <=2.3 only (functionish RegExp)
    +	return typeof obj === "object" || typeof obj === "function" ?
    +		class2type[ toString.call( obj ) ] || "object" :
    +		typeof obj;
    +}
    +/* global Symbol */
    +// Defining this global in .eslintrc.json would create a danger of using the global
    +// unguarded in another place, it seems safer to define global only for this module
    +
    +
    +
    +var
    +	version = "3.3.1",
    +
    +	// 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 );
    +	},
    +
    +	// Support: Android <=4.0 only
    +	// Make sure we trim BOM and NBSP
    +	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
    +
    +jQuery.fn = jQuery.prototype = {
    +
    +	// The current version of jQuery being used
    +	jquery: version,
    +
    +	constructor: jQuery,
    +
    +	// 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 all the elements in a clean array
    +		if ( num == null ) {
    +			return slice.call( this );
    +		}
    +
    +		// Return just the one element from the set
    +		return num < 0 ? this[ num + this.length ] : this[ num ];
    +	},
    +
    +	// 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;
    +
    +		// Return the newly-formed element set
    +		return ret;
    +	},
    +
    +	// Execute a callback for every element in the matched set.
    +	each: function( callback ) {
    +		return jQuery.each( this, callback );
    +	},
    +
    +	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();
    +	},
    +
    +	// 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" && !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 = Array.isArray( copy ) ) ) ) {
    +
    +					if ( copyIsArray ) {
    +						copyIsArray = false;
    +						clone = src && Array.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() {},
    +
    +	isPlainObject: function( obj ) {
    +		var proto, Ctor;
    +
    +		// Detect obvious negatives
    +		// Use toString instead of jQuery.type to catch host objects
    +		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
    +			return false;
    +		}
    +
    +		proto = getProto( obj );
    +
    +		// Objects with no prototype (e.g., `Object.create( null )`) are plain
    +		if ( !proto ) {
    +			return true;
    +		}
    +
    +		// Objects with prototype are plain iff they were constructed by a global Object function
    +		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
    +		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
    +	},
    +
    +	isEmptyObject: function( obj ) {
    +
    +		/* eslint-disable no-unused-vars */
    +		// See https://github.com/eslint/eslint/issues/6125
    +		var name;
    +
    +		for ( name in obj ) {
    +			return false;
    +		}
    +		return true;
    +	},
    +
    +	// Evaluates a script in a global context
    +	globalEval: function( code ) {
    +		DOMEval( code );
    +	},
    +
    +	each: function( obj, callback ) {
    +		var length, i = 0;
    +
    +		if ( isArrayLike( obj ) ) {
    +			length = obj.length;
    +			for ( ; i < length; i++ ) {
    +				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
    +					break;
    +				}
    +			}
    +		} else {
    +			for ( i in obj ) {
    +				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
    +					break;
    +				}
    +			}
    +		}
    +
    +		return obj;
    +	},
    +
    +	// Support: Android <=4.0 only
    +	trim: function( text ) {
    +		return text == null ?
    +			"" :
    +			( text + "" ).replace( rtrim, "" );
    +	},
    +
    +	// 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 );
    +	},
    +
    +	// Support: Android <=4.0 only, PhantomJS 1 only
    +	// push.apply(_, arraylike) throws on ancient WebKit
    +	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 length, value,
    +			i = 0,
    +			ret = [];
    +
    +		// Go through the array, translating each of the items to their new values
    +		if ( isArrayLike( elems ) ) {
    +			length = elems.length;
    +			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,
    +
    +	// jQuery.support is not used in Core but other projects attach their
    +	// properties to it so it needs to exist.
    +	support: support
    +} );
    +
    +if ( typeof Symbol === "function" ) {
    +	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
    +}
    +
    +// Populate the class2type map
    +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
    +function( i, name ) {
    +	class2type[ "[object " + name + "]" ] = name.toLowerCase();
    +} );
    +
    +function isArrayLike( obj ) {
    +
    +	// Support: real iOS 8.2 only (not reproducible in simulator)
    +	// `in` check used to prevent JIT error (gh-2145)
    +	// hasOwn isn't used here due to false negatives
    +	// regarding Nodelist length in IE
    +	var length = !!obj && "length" in obj && obj.length,
    +		type = toType( obj );
    +
    +	if ( isFunction( obj ) || isWindow( obj ) ) {
    +		return false;
    +	}
    +
    +	return type === "array" || length === 0 ||
    +		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
    +}
    +var Sizzle =
    +/*!
    + * Sizzle CSS Selector Engine v2.3.3
    + * https://sizzlejs.com/
    + *
    + * Copyright jQuery Foundation and other contributors
    + * Released under the MIT license
    + * http://jquery.org/license
    + *
    + * Date: 2016-08-08
    + */
    +(function( window ) {
    +
    +var i,
    +	support,
    +	Expr,
    +	getText,
    +	isXML,
    +	tokenize,
    +	compile,
    +	select,
    +	outermostContext,
    +	sortInput,
    +	hasDuplicate,
    +
    +	// Local document vars
    +	setDocument,
    +	document,
    +	docElem,
    +	documentIsHTML,
    +	rbuggyQSA,
    +	rbuggyMatches,
    +	matches,
    +	contains,
    +
    +	// Instance-specific data
    +	expando = "sizzle" + 1 * 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;
    +	},
    +
    +	// Instance methods
    +	hasOwn = ({}).hasOwnProperty,
    +	arr = [],
    +	pop = arr.pop,
    +	push_native = arr.push,
    +	push = arr.push,
    +	slice = arr.slice,
    +	// Use a stripped-down indexOf as it's faster than native
    +	// https://jsperf.com/thor-indexof-vs-for/5
    +	indexOf = function( list, elem ) {
    +		var i = 0,
    +			len = list.length;
    +		for ( ; i < len; i++ ) {
    +			if ( list[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
    +
    +	// http://www.w3.org/TR/css3-selectors/#whitespace
    +	whitespace = "[\\x20\\t\\r\\n\\f]",
    +
    +	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
    +	identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
    +
    +	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
    +	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
    +		// Operator (capture 2)
    +		"*([*^$|!~]?=)" + whitespace +
    +		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
    +		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
    +		"*\\]",
    +
    +	pseudos = ":(" + identifier + ")(?:\\((" +
    +		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
    +		// 1. quoted (capture 3; capture 4 or capture 5)
    +		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
    +		// 2. simple (capture 6)
    +		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
    +		// 3. anything else (capture 2)
    +		".*" +
    +		")\\)|)",
    +
    +	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
    +	rwhitespace = new RegExp( whitespace + "+", "g" ),
    +	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( "^#(" + identifier + ")" ),
    +		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
    +		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
    +		"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 = /[+~]/,
    +
    +	// 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<24
    +		// 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 );
    +	},
    +
    +	// CSS string/identifier serialization
    +	// https://drafts.csswg.org/cssom/#common-serializing-idioms
    +	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
    +	fcssescape = function( ch, asCodePoint ) {
    +		if ( asCodePoint ) {
    +
    +			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
    +			if ( ch === "\0" ) {
    +				return "\uFFFD";
    +			}
    +
    +			// Control characters and (dependent upon position) numbers get escaped as code points
    +			return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
    +		}
    +
    +		// Other potentially-special ASCII characters get backslash-escaped
    +		return "\\" + ch;
    +	},
    +
    +	// Used for iframes
    +	// See setDocument()
    +	// Removing the function wrapper causes a "Permission Denied"
    +	// error in IE
    +	unloadHandler = function() {
    +		setDocument();
    +	},
    +
    +	disabledAncestor = addCombinator(
    +		function( elem ) {
    +			return elem.disabled === true && ("form" in elem || "label" in elem);
    +		},
    +		{ dir: "parentNode", next: "legend" }
    +	);
    +
    +// 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 m, i, elem, nid, match, groups, newSelector,
    +		newContext = context && context.ownerDocument,
    +
    +		// nodeType defaults to 9, since context defaults to document
    +		nodeType = context ? context.nodeType : 9;
    +
    +	results = results || [];
    +
    +	// Return early from calls with invalid selector or context
    +	if ( typeof selector !== "string" || !selector ||
    +		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
    +
    +		return results;
    +	}
    +
    +	// Try to shortcut find operations (as opposed to filters) in HTML documents
    +	if ( !seed ) {
    +
    +		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
    +			setDocument( context );
    +		}
    +		context = context || document;
    +
    +		if ( documentIsHTML ) {
    +
    +			// If the selector is sufficiently simple, try using a "get*By*" DOM method
    +			// (excepting DocumentFragment context, where the methods don't exist)
    +			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
    +
    +				// ID selector
    +				if ( (m = match[1]) ) {
    +
    +					// Document context
    +					if ( nodeType === 9 ) {
    +						if ( (elem = context.getElementById( m )) ) {
    +
    +							// Support: IE, Opera, Webkit
    +							// TODO: identify versions
    +							// getElementById can match elements by name instead of ID
    +							if ( elem.id === m ) {
    +								results.push( elem );
    +								return results;
    +							}
    +						} else {
    +							return results;
    +						}
    +
    +					// Element context
    +					} else {
    +
    +						// Support: IE, Opera, Webkit
    +						// TODO: identify versions
    +						// getElementById can match elements by name instead of ID
    +						if ( newContext && (elem = newContext.getElementById( m )) &&
    +							contains( context, elem ) &&
    +							elem.id === m ) {
    +
    +							results.push( elem );
    +							return results;
    +						}
    +					}
    +
    +				// Type selector
    +				} else if ( match[2] ) {
    +					push.apply( results, context.getElementsByTagName( selector ) );
    +					return results;
    +
    +				// Class selector
    +				} else if ( (m = match[3]) && support.getElementsByClassName &&
    +					context.getElementsByClassName ) {
    +
    +					push.apply( results, context.getElementsByClassName( m ) );
    +					return results;
    +				}
    +			}
    +
    +			// Take advantage of querySelectorAll
    +			if ( support.qsa &&
    +				!compilerCache[ selector + " " ] &&
    +				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
    +
    +				if ( nodeType !== 1 ) {
    +					newContext = context;
    +					newSelector = selector;
    +
    +				// qSA looks outside Element context, which is not what we want
    +				// Thanks to Andrew Dupont for this workaround technique
    +				// Support: IE <=8
    +				// Exclude object elements
    +				} else if ( context.nodeName.toLowerCase() !== "object" ) {
    +
    +					// Capture the context ID, setting it first if necessary
    +					if ( (nid = context.getAttribute( "id" )) ) {
    +						nid = nid.replace( rcssescape, fcssescape );
    +					} else {
    +						context.setAttribute( "id", (nid = expando) );
    +					}
    +
    +					// Prefix every selector in the list
    +					groups = tokenize( selector );
    +					i = groups.length;
    +					while ( i-- ) {
    +						groups[i] = "#" + nid + " " + toSelector( groups[i] );
    +					}
    +					newSelector = groups.join( "," );
    +
    +					// Expand context for sibling selectors
    +					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
    +						context;
    +				}
    +
    +				if ( newSelector ) {
    +					try {
    +						push.apply( results,
    +							newContext.querySelectorAll( newSelector )
    +						);
    +						return results;
    +					} catch ( qsaError ) {
    +					} finally {
    +						if ( nid === expando ) {
    +							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 element and returns a boolean result
    + */
    +function assert( fn ) {
    +	var el = document.createElement("fieldset");
    +
    +	try {
    +		return !!fn( el );
    +	} catch (e) {
    +		return false;
    +	} finally {
    +		// Remove from its parent by default
    +		if ( el.parentNode ) {
    +			el.parentNode.removeChild( el );
    +		}
    +		// release memory in IE
    +		el = 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 = arr.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 &&
    +			a.sourceIndex - b.sourceIndex;
    +
    +	// 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 :enabled/:disabled
    + * @param {Boolean} disabled true for :disabled; false for :enabled
    + */
    +function createDisabledPseudo( disabled ) {
    +
    +	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
    +	return function( elem ) {
    +
    +		// Only certain elements can match :enabled or :disabled
    +		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
    +		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
    +		if ( "form" in elem ) {
    +
    +			// Check for inherited disabledness on relevant non-disabled elements:
    +			// * listed form-associated elements in a disabled fieldset
    +			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
    +			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
    +			// * option elements in a disabled optgroup
    +			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
    +			// All such elements have a "form" property.
    +			if ( elem.parentNode && elem.disabled === false ) {
    +
    +				// Option elements defer to a parent optgroup if present
    +				if ( "label" in elem ) {
    +					if ( "label" in elem.parentNode ) {
    +						return elem.parentNode.disabled === disabled;
    +					} else {
    +						return elem.disabled === disabled;
    +					}
    +				}
    +
    +				// Support: IE 6 - 11
    +				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
    +				return elem.isDisabled === disabled ||
    +
    +					// Where there is no isDisabled, check manually
    +					/* jshint -W018 */
    +					elem.isDisabled !== !disabled &&
    +						disabledAncestor( elem ) === disabled;
    +			}
    +
    +			return elem.disabled === disabled;
    +
    +		// Try to winnow out elements that can't be disabled before trusting the disabled property.
    +		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
    +		// even exist on them, let alone have a boolean value.
    +		} else if ( "label" in elem ) {
    +			return elem.disabled === disabled;
    +		}
    +
    +		// Remaining elements are neither :enabled nor :disabled
    +		return false;
    +	};
    +}
    +
    +/**
    + * 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 !== "undefined" && 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, subWindow,
    +		doc = node ? node.ownerDocument || node : preferredDoc;
    +
    +	// Return early if doc is invalid or already selected
    +	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
    +		return document;
    +	}
    +
    +	// Update global variables
    +	document = doc;
    +	docElem = document.documentElement;
    +	documentIsHTML = !isXML( document );
    +
    +	// Support: IE 9-11, Edge
    +	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
    +	if ( preferredDoc !== document &&
    +		(subWindow = document.defaultView) && subWindow.top !== subWindow ) {
    +
    +		// Support: IE 11, Edge
    +		if ( subWindow.addEventListener ) {
    +			subWindow.addEventListener( "unload", unloadHandler, false );
    +
    +		// Support: IE 9 - 10 only
    +		} else if ( subWindow.attachEvent ) {
    +			subWindow.attachEvent( "onunload", unloadHandler );
    +		}
    +	}
    +
    +	/* Attributes
    +	---------------------------------------------------------------------- */
    +
    +	// Support: IE<8
    +	// Verify that getAttribute really returns attributes and not properties
    +	// (excepting IE8 booleans)
    +	support.attributes = assert(function( el ) {
    +		el.className = "i";
    +		return !el.getAttribute("className");
    +	});
    +
    +	/* getElement(s)By*
    +	---------------------------------------------------------------------- */
    +
    +	// Check if getElementsByTagName("*") returns only elements
    +	support.getElementsByTagName = assert(function( el ) {
    +		el.appendChild( document.createComment("") );
    +		return !el.getElementsByTagName("*").length;
    +	});
    +
    +	// Support: IE<9
    +	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
    +
    +	// Support: IE<10
    +	// Check if getElementById returns elements by name
    +	// The broken getElementById methods don't pick up programmatically-set names,
    +	// so use a roundabout getElementsByName test
    +	support.getById = assert(function( el ) {
    +		docElem.appendChild( el ).id = expando;
    +		return !document.getElementsByName || !document.getElementsByName( expando ).length;
    +	});
    +
    +	// ID filter and find
    +	if ( support.getById ) {
    +		Expr.filter["ID"] = function( id ) {
    +			var attrId = id.replace( runescape, funescape );
    +			return function( elem ) {
    +				return elem.getAttribute("id") === attrId;
    +			};
    +		};
    +		Expr.find["ID"] = function( id, context ) {
    +			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
    +				var elem = context.getElementById( id );
    +				return elem ? [ elem ] : [];
    +			}
    +		};
    +	} else {
    +		Expr.filter["ID"] =  function( id ) {
    +			var attrId = id.replace( runescape, funescape );
    +			return function( elem ) {
    +				var node = typeof elem.getAttributeNode !== "undefined" &&
    +					elem.getAttributeNode("id");
    +				return node && node.value === attrId;
    +			};
    +		};
    +
    +		// Support: IE 6 - 7 only
    +		// getElementById is not reliable as a find shortcut
    +		Expr.find["ID"] = function( id, context ) {
    +			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
    +				var node, i, elems,
    +					elem = context.getElementById( id );
    +
    +				if ( elem ) {
    +
    +					// Verify the id attribute
    +					node = elem.getAttributeNode("id");
    +					if ( node && node.value === id ) {
    +						return [ elem ];
    +					}
    +
    +					// Fall back on getElementsByName
    +					elems = context.getElementsByName( id );
    +					i = 0;
    +					while ( (elem = elems[i++]) ) {
    +						node = elem.getAttributeNode("id");
    +						if ( node && node.value === id ) {
    +							return [ elem ];
    +						}
    +					}
    +				}
    +
    +				return [];
    +			}
    +		};
    +	}
    +
    +	// Tag
    +	Expr.find["TAG"] = support.getElementsByTagName ?
    +		function( tag, context ) {
    +			if ( typeof context.getElementsByTagName !== "undefined" ) {
    +				return context.getElementsByTagName( tag );
    +
    +			// DocumentFragment nodes don't have gEBTN
    +			} else if ( support.qsa ) {
    +				return context.querySelectorAll( tag );
    +			}
    +		} :
    +
    +		function( tag, context ) {
    +			var elem,
    +				tmp = [],
    +				i = 0,
    +				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
    +				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 !== "undefined" && 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 https://bugs.jquery.com/ticket/13378
    +	rbuggyQSA = [];
    +
    +	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
    +		// Build QSA regex
    +		// Regex strategy adopted from Diego Perini
    +		assert(function( el ) {
    +			// 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
    +			// https://bugs.jquery.com/ticket/12359
    +			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
    +				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
    +				"<option selected=''></option></select>";
    +
    +			// Support: IE8, Opera 11-12.16
    +			// Nothing should be selected when empty strings follow ^= or $= or *=
    +			// The test attribute must be unknown in Opera but "safe" for WinRT
    +			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
    +			if ( el.querySelectorAll("[msallowcapture^='']").length ) {
    +				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
    +			}
    +
    +			// Support: IE8
    +			// Boolean attributes and "value" are not treated correctly
    +			if ( !el.querySelectorAll("[selected]").length ) {
    +				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
    +			}
    +
    +			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
    +			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
    +				rbuggyQSA.push("~=");
    +			}
    +
    +			// 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 ( !el.querySelectorAll(":checked").length ) {
    +				rbuggyQSA.push(":checked");
    +			}
    +
    +			// Support: Safari 8+, iOS 8+
    +			// https://bugs.webkit.org/show_bug.cgi?id=136851
    +			// In-page `selector#id sibling-combinator selector` fails
    +			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
    +				rbuggyQSA.push(".#.+[+~]");
    +			}
    +		});
    +
    +		assert(function( el ) {
    +			el.innerHTML = "<a href='' disabled='disabled'></a>" +
    +				"<select disabled='disabled'><option/></select>";
    +
    +			// Support: Windows 8 Native Apps
    +			// The type and name attributes are restricted during .innerHTML assignment
    +			var input = document.createElement("input");
    +			input.setAttribute( "type", "hidden" );
    +			el.appendChild( input ).setAttribute( "name", "D" );
    +
    +			// Support: IE8
    +			// Enforce case-sensitivity of name attribute
    +			if ( el.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 ( el.querySelectorAll(":enabled").length !== 2 ) {
    +				rbuggyQSA.push( ":enabled", ":disabled" );
    +			}
    +
    +			// Support: IE9-11+
    +			// IE's :disabled selector does not pick up the children of disabled fieldsets
    +			docElem.appendChild( el ).disabled = true;
    +			if ( el.querySelectorAll(":disabled").length !== 2 ) {
    +				rbuggyQSA.push( ":enabled", ":disabled" );
    +			}
    +
    +			// Opera 10-11 does not throw on post-comma invalid pseudos
    +			el.querySelectorAll("*,:x");
    +			rbuggyQSA.push(",.*:");
    +		});
    +	}
    +
    +	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
    +		docElem.webkitMatchesSelector ||
    +		docElem.mozMatchesSelector ||
    +		docElem.oMatchesSelector ||
    +		docElem.msMatchesSelector) )) ) {
    +
    +		assert(function( el ) {
    +			// Check to see if it's possible to do matchesSelector
    +			// on a disconnected node (IE 9)
    +			support.disconnectedMatch = matches.call( el, "*" );
    +
    +			// This should fail with an exception
    +			// Gecko does not error, returns false instead
    +			matches.call( el, "[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 self-exclusive
    +	// 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 === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
    +				return -1;
    +			}
    +			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
    +				return 1;
    +			}
    +
    +			// Maintain original order
    +			return sortInput ?
    +				( indexOf( sortInput, a ) - indexOf( 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 === document ? -1 :
    +				b === document ? 1 :
    +				aup ? -1 :
    +				bup ? 1 :
    +				sortInput ?
    +				( indexOf( sortInput, a ) - indexOf( 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 document;
    +};
    +
    +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 &&
    +		!compilerCache[ expr + " " ] &&
    +		( !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.escape = function( sel ) {
    +	return (sel + "").replace( rcssescape, fcssescape );
    +};
    +
    +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[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[6] && match[2];
    +
    +			if ( matchExpr["CHILD"].test( match[0] ) ) {
    +				return null;
    +			}
    +
    +			// Accept quoted arguments as-is
    +			if ( match[3] ) {
    +				match[2] = match[4] || match[5] || "";
    +
    +			// 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 !== "undefined" && 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.replace( rwhitespace, " " ) + " " ).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, uniqueCache, outerCache, node, nodeIndex, start,
    +						dir = simple !== forward ? "nextSibling" : "previousSibling",
    +						parent = elem.parentNode,
    +						name = ofType && elem.nodeName.toLowerCase(),
    +						useCache = !xml && !ofType,
    +						diff = false;
    +
    +					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
    +
    +							// ...in a gzip-friendly way
    +							node = parent;
    +							outerCache = node[ expando ] || (node[ expando ] = {});
    +
    +							// Support: IE <9 only
    +							// Defend against cloned attroperties (jQuery gh-1709)
    +							uniqueCache = outerCache[ node.uniqueID ] ||
    +								(outerCache[ node.uniqueID ] = {});
    +
    +							cache = uniqueCache[ type ] || [];
    +							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
    +							diff = nodeIndex && 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 ) {
    +									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
    +									break;
    +								}
    +							}
    +
    +						} else {
    +							// Use previously-cached element index if available
    +							if ( useCache ) {
    +								// ...in a gzip-friendly way
    +								node = elem;
    +								outerCache = node[ expando ] || (node[ expando ] = {});
    +
    +								// Support: IE <9 only
    +								// Defend against cloned attroperties (jQuery gh-1709)
    +								uniqueCache = outerCache[ node.uniqueID ] ||
    +									(outerCache[ node.uniqueID ] = {});
    +
    +								cache = uniqueCache[ type ] || [];
    +								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
    +								diff = nodeIndex;
    +							}
    +
    +							// xml :nth-child(...)
    +							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
    +							if ( diff === false ) {
    +								// 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 ) {
    +											outerCache = node[ expando ] || (node[ expando ] = {});
    +
    +											// Support: IE <9 only
    +											// Defend against cloned attroperties (jQuery gh-1709)
    +											uniqueCache = outerCache[ node.uniqueID ] ||
    +												(outerCache[ node.uniqueID ] = {});
    +
    +											uniqueCache[ 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( 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 );
    +					// Don't keep the element (issue #299)
    +					input[0] = null;
    +					return !results.pop();
    +				};
    +		}),
    +
    +		"has": markFunction(function( selector ) {
    +			return function( elem ) {
    +				return Sizzle( selector, elem ).length > 0;
    +			};
    +		}),
    +
    +		"contains": markFunction(function( text ) {
    +			text = text.replace( runescape, funescape );
    +			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": createDisabledPseudo( false ),
    +		"disabled": createDisabledPseudo( 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();
    +
    +tokenize = Sizzle.tokenize = function( 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,
    +		skip = combinator.next,
    +		key = skip || dir,
    +		checkNonElements = base && key === "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 );
    +				}
    +			}
    +			return false;
    +		} :
    +
    +		// Check against all ancestor/preceding elements
    +		function( elem, context, xml ) {
    +			var oldCache, uniqueCache, outerCache,
    +				newCache = [ dirruns, doneName ];
    +
    +			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator 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 ] = {});
    +
    +						// Support: IE <9 only
    +						// Defend against cloned attroperties (jQuery gh-1709)
    +						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
    +
    +						if ( skip && skip === elem.nodeName.toLowerCase() ) {
    +							elem = elem[ dir ] || elem;
    +						} else if ( (oldCache = uniqueCache[ key ]) &&
    +							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
    +							uniqueCache[ key ] = newCache;
    +
    +							// A match means we're done; a fail means we have to keep checking
    +							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
    +								return true;
    +							}
    +						}
    +					}
    +				}
    +			}
    +			return false;
    +		};
    +}
    +
    +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 multipleContexts( selector, contexts, results ) {
    +	var i = 0,
    +		len = contexts.length;
    +	for ( ; i < len; i++ ) {
    +		Sizzle( selector, contexts[i], results );
    +	}
    +	return results;
    +}
    +
    +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( 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( checkContext, elem ) > -1;
    +		}, implicitRelative, true ),
    +		matchers = [ function( elem, context, xml ) {
    +			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
    +				(checkContext = context).nodeType ?
    +					matchContext( elem, context, xml ) :
    +					matchAnyContext( elem, context, xml ) );
    +			// Avoid hanging onto element (issue #299)
    +			checkContext = null;
    +			return ret;
    +		} ];
    +
    +	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 || outermost;
    +			}
    +
    +			// Add elements passing elementMatchers directly to results
    +			// Support: IE<9, Safari
    +			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
    +			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
    +				if ( byElement && elem ) {
    +					j = 0;
    +					if ( !context && elem.ownerDocument !== document ) {
    +						setDocument( elem );
    +						xml = !documentIsHTML;
    +					}
    +					while ( (matcher = elementMatchers[j++]) ) {
    +						if ( matcher( elem, context || document, 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 );
    +					}
    +				}
    +			}
    +
    +			// `i` is now the count of elements visited above, and adding it to `matchedCount`
    +			// makes the latter nonnegative.
    +			matchedCount += i;
    +
    +			// Apply set filters to unmatched elements
    +			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
    +			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
    +			// no element matchers and no seed.
    +			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
    +			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
    +			// numerically zero.
    +			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, match /* 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 ( !match ) {
    +			match = tokenize( selector );
    +		}
    +		i = match.length;
    +		while ( i-- ) {
    +			cached = matcherFromTokens( match[i] );
    +			if ( cached[ expando ] ) {
    +				setMatchers.push( cached );
    +			} else {
    +				elementMatchers.push( cached );
    +			}
    +		}
    +
    +		// Cache the compiled function
    +		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
    +
    +		// Save selector and tokenization
    +		cached.selector = selector;
    +	}
    +	return cached;
    +};
    +
    +/**
    + * A low-level selection function that works with Sizzle's compiled
    + *  selector functions
    + * @param {String|Function} selector A selector or a pre-compiled
    + *  selector function built with Sizzle.compile
    + * @param {Element} context
    + * @param {Array} [results]
    + * @param {Array} [seed] A set of elements to match against
    + */
    +select = Sizzle.select = function( selector, context, results, seed ) {
    +	var i, tokens, token, type, find,
    +		compiled = typeof selector === "function" && selector,
    +		match = !seed && tokenize( (selector = compiled.selector || selector) );
    +
    +	results = results || [];
    +
    +	// Try to minimize operations if there is only one selector in the list and no seed
    +	// (the latter of which guarantees us context)
    +	if ( match.length === 1 ) {
    +
    +		// Reduce context if the leading compound selector is an ID
    +		tokens = match[0] = match[0].slice( 0 );
    +		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
    +				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;
    +
    +			// Precompiled matchers will still verify ancestry, so step up a level
    +			} else if ( compiled ) {
    +				context = context.parentNode;
    +			}
    +
    +			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 if one is not provided
    +	// Provide `match` to avoid retokenization if we modified the selector above
    +	( compiled || compile( selector, match ) )(
    +		seed,
    +		context,
    +		!documentIsHTML,
    +		results,
    +		!context || 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-35+
    +// 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( el ) {
    +	// Should return 1, but returns 4 (following)
    +	return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
    +});
    +
    +// Support: IE<8
    +// Prevent attribute/property "interpolation"
    +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
    +if ( !assert(function( el ) {
    +	el.innerHTML = "<a href='#'></a>";
    +	return el.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( el ) {
    +	el.innerHTML = "<input/>";
    +	el.firstChild.setAttribute( "value", "" );
    +	return el.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( el ) {
    +	return el.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;
    +
    +// Deprecated
    +jQuery.expr[ ":" ] = jQuery.expr.pseudos;
    +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
    +jQuery.text = Sizzle.getText;
    +jQuery.isXMLDoc = Sizzle.isXML;
    +jQuery.contains = Sizzle.contains;
    +jQuery.escapeSelector = Sizzle.escape;
    +
    +
    +
    +
    +var 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;
    +};
    +
    +
    +var siblings = function( n, elem ) {
    +	var matched = [];
    +
    +	for ( ; n; n = n.nextSibling ) {
    +		if ( n.nodeType === 1 && n !== elem ) {
    +			matched.push( n );
    +		}
    +	}
    +
    +	return matched;
    +};
    +
    +
    +var rneedsContext = jQuery.expr.match.needsContext;
    +
    +
    +
    +function nodeName( elem, name ) {
    +
    +  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
    +
    +};
    +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
    +
    +
    +
    +// Implement the identical functionality for filter and not
    +function winnow( elements, qualifier, not ) {
    +	if ( isFunction( qualifier ) ) {
    +		return jQuery.grep( elements, function( elem, i ) {
    +			return !!qualifier.call( elem, i, elem ) !== not;
    +		} );
    +	}
    +
    +	// Single element
    +	if ( qualifier.nodeType ) {
    +		return jQuery.grep( elements, function( elem ) {
    +			return ( elem === qualifier ) !== not;
    +		} );
    +	}
    +
    +	// Arraylike of elements (jQuery, arguments, Array)
    +	if ( typeof qualifier !== "string" ) {
    +		return jQuery.grep( elements, function( elem ) {
    +			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
    +		} );
    +	}
    +
    +	// Filtered directly for both simple and complex selectors
    +	return jQuery.filter( qualifier, elements, not );
    +}
    +
    +jQuery.filter = function( expr, elems, not ) {
    +	var elem = elems[ 0 ];
    +
    +	if ( not ) {
    +		expr = ":not(" + expr + ")";
    +	}
    +
    +	if ( elems.length === 1 && elem.nodeType === 1 ) {
    +		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
    +	}
    +
    +	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
    +		return elem.nodeType === 1;
    +	} ) );
    +};
    +
    +jQuery.fn.extend( {
    +	find: function( selector ) {
    +		var i, ret,
    +			len = this.length,
    +			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;
    +					}
    +				}
    +			} ) );
    +		}
    +
    +		ret = this.pushStack( [] );
    +
    +		for ( i = 0; i < len; i++ ) {
    +			jQuery.find( selector, self[ i ], ret );
    +		}
    +
    +		return len > 1 ? jQuery.uniqueSort( ret ) : 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 <tag> to avoid XSS via location.hash (#9521)
    +	// Strict HTML recognition (#11290: must start with <)
    +	// Shortcut simple #id case for speed
    +	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
    +
    +	init = jQuery.fn.init = function( selector, context, root ) {
    +		var match, elem;
    +
    +		// HANDLE: $(""), $(null), $(undefined), $(false)
    +		if ( !selector ) {
    +			return this;
    +		}
    +
    +		// Method init() accepts an alternate rootjQuery
    +		// so migrate can support jQuery.sub (gh-2101)
    +		root = root || rootjQuery;
    +
    +		// 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;
    +
    +					// Option to run 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 ( 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 ] );
    +
    +					if ( elem ) {
    +
    +						// Inject the element directly into the jQuery object
    +						this[ 0 ] = elem;
    +						this.length = 1;
    +					}
    +					return this;
    +				}
    +
    +			// HANDLE: $(expr, $(...))
    +			} else if ( !context || context.jquery ) {
    +				return ( context || root ).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[ 0 ] = selector;
    +			this.length = 1;
    +			return this;
    +
    +		// HANDLE: $(function)
    +		// Shortcut for document ready
    +		} else if ( isFunction( selector ) ) {
    +			return root.ready !== undefined ?
    +				root.ready( selector ) :
    +
    +				// Execute immediately if ready is not present
    +				selector( jQuery );
    +		}
    +
    +		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.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 = [],
    +			targets = typeof selectors !== "string" && jQuery( selectors );
    +
    +		// Positional selectors never match, since there's no _selection_ context
    +		if ( !rneedsContext.test( selectors ) ) {
    +			for ( ; i < l; i++ ) {
    +				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
    +
    +					// Always skip document fragments
    +					if ( cur.nodeType < 11 && ( targets ?
    +						targets.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.uniqueSort( matched ) : matched );
    +	},
    +
    +	// Determine the position of an element within the set
    +	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.uniqueSort(
    +				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 dir( elem, "parentNode" );
    +	},
    +	parentsUntil: function( elem, i, until ) {
    +		return dir( elem, "parentNode", until );
    +	},
    +	next: function( elem ) {
    +		return sibling( elem, "nextSibling" );
    +	},
    +	prev: function( elem ) {
    +		return sibling( elem, "previousSibling" );
    +	},
    +	nextAll: function( elem ) {
    +		return dir( elem, "nextSibling" );
    +	},
    +	prevAll: function( elem ) {
    +		return dir( elem, "previousSibling" );
    +	},
    +	nextUntil: function( elem, i, until ) {
    +		return dir( elem, "nextSibling", until );
    +	},
    +	prevUntil: function( elem, i, until ) {
    +		return dir( elem, "previousSibling", until );
    +	},
    +	siblings: function( elem ) {
    +		return siblings( ( elem.parentNode || {} ).firstChild, elem );
    +	},
    +	children: function( elem ) {
    +		return siblings( elem.firstChild );
    +	},
    +	contents: function( elem ) {
    +        if ( nodeName( elem, "iframe" ) ) {
    +            return elem.contentDocument;
    +        }
    +
    +        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
    +        // Treat the template element as a regular one in browsers that
    +        // don't support it.
    +        if ( nodeName( elem, "template" ) ) {
    +            elem = elem.content || elem;
    +        }
    +
    +        return 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.uniqueSort( matched );
    +			}
    +
    +			// Reverse order for parents* and prev-derivatives
    +			if ( rparentsprev.test( name ) ) {
    +				matched.reverse();
    +			}
    +		}
    +
    +		return this.pushStack( matched );
    +	};
    +} );
    +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
    +
    +
    +
    +// Convert String-formatted options into Object-formatted ones
    +function createOptions( options ) {
    +	var object = {};
    +	jQuery.each( options.match( rnothtmlwhite ) || [], 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" ?
    +		createOptions( options ) :
    +		jQuery.extend( {}, options );
    +
    +	var // Flag to know if list is currently firing
    +		firing,
    +
    +		// Last fire value for non-forgettable lists
    +		memory,
    +
    +		// Flag to know if list was already fired
    +		fired,
    +
    +		// Flag to prevent firing
    +		locked,
    +
    +		// Actual callback list
    +		list = [],
    +
    +		// Queue of execution data for repeatable lists
    +		queue = [],
    +
    +		// Index of currently firing callback (modified by add/remove as needed)
    +		firingIndex = -1,
    +
    +		// Fire callbacks
    +		fire = function() {
    +
    +			// Enforce single-firing
    +			locked = locked || options.once;
    +
    +			// Execute callbacks for all pending executions,
    +			// respecting firingIndex overrides and runtime changes
    +			fired = firing = true;
    +			for ( ; queue.length; firingIndex = -1 ) {
    +				memory = queue.shift();
    +				while ( ++firingIndex < list.length ) {
    +
    +					// Run callback and check for early termination
    +					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
    +						options.stopOnFalse ) {
    +
    +						// Jump to end and forget the data so .add doesn't re-fire
    +						firingIndex = list.length;
    +						memory = false;
    +					}
    +				}
    +			}
    +
    +			// Forget the data if we're done with it
    +			if ( !options.memory ) {
    +				memory = false;
    +			}
    +
    +			firing = false;
    +
    +			// Clean up if we're done firing for good
    +			if ( locked ) {
    +
    +				// Keep an empty list if we have data for future add calls
    +				if ( memory ) {
    +					list = [];
    +
    +				// Otherwise, this object is spent
    +				} else {
    +					list = "";
    +				}
    +			}
    +		},
    +
    +		// Actual Callbacks object
    +		self = {
    +
    +			// Add a callback or a collection of callbacks to the list
    +			add: function() {
    +				if ( list ) {
    +
    +					// If we have memory from a past run, we should fire after adding
    +					if ( memory && !firing ) {
    +						firingIndex = list.length - 1;
    +						queue.push( memory );
    +					}
    +
    +					( function add( args ) {
    +						jQuery.each( args, function( _, arg ) {
    +							if ( isFunction( arg ) ) {
    +								if ( !options.unique || !self.has( arg ) ) {
    +									list.push( arg );
    +								}
    +							} else if ( arg && arg.length && toType( arg ) !== "string" ) {
    +
    +								// Inspect recursively
    +								add( arg );
    +							}
    +						} );
    +					} )( arguments );
    +
    +					if ( memory && !firing ) {
    +						fire();
    +					}
    +				}
    +				return this;
    +			},
    +
    +			// Remove a callback from the list
    +			remove: function() {
    +				jQuery.each( arguments, function( _, arg ) {
    +					var index;
    +					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
    +						list.splice( index, 1 );
    +
    +						// Handle firing indexes
    +						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.length > 0;
    +			},
    +
    +			// Remove all callbacks from the list
    +			empty: function() {
    +				if ( list ) {
    +					list = [];
    +				}
    +				return this;
    +			},
    +
    +			// Disable .fire and .add
    +			// Abort any current/pending executions
    +			// Clear all callbacks and values
    +			disable: function() {
    +				locked = queue = [];
    +				list = memory = "";
    +				return this;
    +			},
    +			disabled: function() {
    +				return !list;
    +			},
    +
    +			// Disable .fire
    +			// Also disable .add unless we have memory (since it would have no effect)
    +			// Abort any pending executions
    +			lock: function() {
    +				locked = queue = [];
    +				if ( !memory && !firing ) {
    +					list = memory = "";
    +				}
    +				return this;
    +			},
    +			locked: function() {
    +				return !!locked;
    +			},
    +
    +			// Call all callbacks with the given context and arguments
    +			fireWith: function( context, args ) {
    +				if ( !locked ) {
    +					args = args || [];
    +					args = [ context, args.slice ? args.slice() : args ];
    +					queue.push( args );
    +					if ( !firing ) {
    +						fire();
    +					}
    +				}
    +				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;
    +};
    +
    +
    +function Identity( v ) {
    +	return v;
    +}
    +function Thrower( ex ) {
    +	throw ex;
    +}
    +
    +function adoptValue( value, resolve, reject, noValue ) {
    +	var method;
    +
    +	try {
    +
    +		// Check for promise aspect first to privilege synchronous behavior
    +		if ( value && isFunction( ( method = value.promise ) ) ) {
    +			method.call( value ).done( resolve ).fail( reject );
    +
    +		// Other thenables
    +		} else if ( value && isFunction( ( method = value.then ) ) ) {
    +			method.call( value, resolve, reject );
    +
    +		// Other non-thenables
    +		} else {
    +
    +			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
    +			// * false: [ value ].slice( 0 ) => resolve( value )
    +			// * true: [ value ].slice( 1 ) => resolve()
    +			resolve.apply( undefined, [ value ].slice( noValue ) );
    +		}
    +
    +	// For Promises/A+, convert exceptions into rejections
    +	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
    +	// Deferred#then to conditionally suppress rejection.
    +	} catch ( value ) {
    +
    +		// Support: Android 4.0 only
    +		// Strict mode functions invoked without .call/.apply get global-object context
    +		reject.apply( undefined, [ value ] );
    +	}
    +}
    +
    +jQuery.extend( {
    +
    +	Deferred: function( func ) {
    +		var tuples = [
    +
    +				// action, add listener, callbacks,
    +				// ... .then handlers, argument index, [final state]
    +				[ "notify", "progress", jQuery.Callbacks( "memory" ),
    +					jQuery.Callbacks( "memory" ), 2 ],
    +				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
    +					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
    +				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
    +					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
    +			],
    +			state = "pending",
    +			promise = {
    +				state: function() {
    +					return state;
    +				},
    +				always: function() {
    +					deferred.done( arguments ).fail( arguments );
    +					return this;
    +				},
    +				"catch": function( fn ) {
    +					return promise.then( null, fn );
    +				},
    +
    +				// Keep pipe for back-compat
    +				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
    +					var fns = arguments;
    +
    +					return jQuery.Deferred( function( newDefer ) {
    +						jQuery.each( tuples, function( i, tuple ) {
    +
    +							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
    +							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
    +
    +							// deferred.progress(function() { bind to newDefer or newDefer.notify })
    +							// deferred.done(function() { bind to newDefer or newDefer.resolve })
    +							// deferred.fail(function() { bind to newDefer or newDefer.reject })
    +							deferred[ tuple[ 1 ] ]( function() {
    +								var returned = fn && fn.apply( this, arguments );
    +								if ( returned && isFunction( returned.promise ) ) {
    +									returned.promise()
    +										.progress( newDefer.notify )
    +										.done( newDefer.resolve )
    +										.fail( newDefer.reject );
    +								} else {
    +									newDefer[ tuple[ 0 ] + "With" ](
    +										this,
    +										fn ? [ returned ] : arguments
    +									);
    +								}
    +							} );
    +						} );
    +						fns = null;
    +					} ).promise();
    +				},
    +				then: function( onFulfilled, onRejected, onProgress ) {
    +					var maxDepth = 0;
    +					function resolve( depth, deferred, handler, special ) {
    +						return function() {
    +							var that = this,
    +								args = arguments,
    +								mightThrow = function() {
    +									var returned, then;
    +
    +									// Support: Promises/A+ section 2.3.3.3.3
    +									// https://promisesaplus.com/#point-59
    +									// Ignore double-resolution attempts
    +									if ( depth < maxDepth ) {
    +										return;
    +									}
    +
    +									returned = handler.apply( that, args );
    +
    +									// Support: Promises/A+ section 2.3.1
    +									// https://promisesaplus.com/#point-48
    +									if ( returned === deferred.promise() ) {
    +										throw new TypeError( "Thenable self-resolution" );
    +									}
    +
    +									// Support: Promises/A+ sections 2.3.3.1, 3.5
    +									// https://promisesaplus.com/#point-54
    +									// https://promisesaplus.com/#point-75
    +									// Retrieve `then` only once
    +									then = returned &&
    +
    +										// Support: Promises/A+ section 2.3.4
    +										// https://promisesaplus.com/#point-64
    +										// Only check objects and functions for thenability
    +										( typeof returned === "object" ||
    +											typeof returned === "function" ) &&
    +										returned.then;
    +
    +									// Handle a returned thenable
    +									if ( isFunction( then ) ) {
    +
    +										// Special processors (notify) just wait for resolution
    +										if ( special ) {
    +											then.call(
    +												returned,
    +												resolve( maxDepth, deferred, Identity, special ),
    +												resolve( maxDepth, deferred, Thrower, special )
    +											);
    +
    +										// Normal processors (resolve) also hook into progress
    +										} else {
    +
    +											// ...and disregard older resolution values
    +											maxDepth++;
    +
    +											then.call(
    +												returned,
    +												resolve( maxDepth, deferred, Identity, special ),
    +												resolve( maxDepth, deferred, Thrower, special ),
    +												resolve( maxDepth, deferred, Identity,
    +													deferred.notifyWith )
    +											);
    +										}
    +
    +									// Handle all other returned values
    +									} else {
    +
    +										// Only substitute handlers pass on context
    +										// and multiple values (non-spec behavior)
    +										if ( handler !== Identity ) {
    +											that = undefined;
    +											args = [ returned ];
    +										}
    +
    +										// Process the value(s)
    +										// Default process is resolve
    +										( special || deferred.resolveWith )( that, args );
    +									}
    +								},
    +
    +								// Only normal processors (resolve) catch and reject exceptions
    +								process = special ?
    +									mightThrow :
    +									function() {
    +										try {
    +											mightThrow();
    +										} catch ( e ) {
    +
    +											if ( jQuery.Deferred.exceptionHook ) {
    +												jQuery.Deferred.exceptionHook( e,
    +													process.stackTrace );
    +											}
    +
    +											// Support: Promises/A+ section 2.3.3.3.4.1
    +											// https://promisesaplus.com/#point-61
    +											// Ignore post-resolution exceptions
    +											if ( depth + 1 >= maxDepth ) {
    +
    +												// Only substitute handlers pass on context
    +												// and multiple values (non-spec behavior)
    +												if ( handler !== Thrower ) {
    +													that = undefined;
    +													args = [ e ];
    +												}
    +
    +												deferred.rejectWith( that, args );
    +											}
    +										}
    +									};
    +
    +							// Support: Promises/A+ section 2.3.3.3.1
    +							// https://promisesaplus.com/#point-57
    +							// Re-resolve promises immediately to dodge false rejection from
    +							// subsequent errors
    +							if ( depth ) {
    +								process();
    +							} else {
    +
    +								// Call an optional hook to record the stack, in case of exception
    +								// since it's otherwise lost when execution goes async
    +								if ( jQuery.Deferred.getStackHook ) {
    +									process.stackTrace = jQuery.Deferred.getStackHook();
    +								}
    +								window.setTimeout( process );
    +							}
    +						};
    +					}
    +
    +					return jQuery.Deferred( function( newDefer ) {
    +
    +						// progress_handlers.add( ... )
    +						tuples[ 0 ][ 3 ].add(
    +							resolve(
    +								0,
    +								newDefer,
    +								isFunction( onProgress ) ?
    +									onProgress :
    +									Identity,
    +								newDefer.notifyWith
    +							)
    +						);
    +
    +						// fulfilled_handlers.add( ... )
    +						tuples[ 1 ][ 3 ].add(
    +							resolve(
    +								0,
    +								newDefer,
    +								isFunction( onFulfilled ) ?
    +									onFulfilled :
    +									Identity
    +							)
    +						);
    +
    +						// rejected_handlers.add( ... )
    +						tuples[ 2 ][ 3 ].add(
    +							resolve(
    +								0,
    +								newDefer,
    +								isFunction( onRejected ) ?
    +									onRejected :
    +									Thrower
    +							)
    +						);
    +					} ).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 = {};
    +
    +		// Add list-specific methods
    +		jQuery.each( tuples, function( i, tuple ) {
    +			var list = tuple[ 2 ],
    +				stateString = tuple[ 5 ];
    +
    +			// promise.progress = list.add
    +			// promise.done = list.add
    +			// promise.fail = list.add
    +			promise[ tuple[ 1 ] ] = list.add;
    +
    +			// Handle state
    +			if ( stateString ) {
    +				list.add(
    +					function() {
    +
    +						// state = "resolved" (i.e., fulfilled)
    +						// state = "rejected"
    +						state = stateString;
    +					},
    +
    +					// rejected_callbacks.disable
    +					// fulfilled_callbacks.disable
    +					tuples[ 3 - i ][ 2 ].disable,
    +
    +					// rejected_handlers.disable
    +					// fulfilled_handlers.disable
    +					tuples[ 3 - i ][ 3 ].disable,
    +
    +					// progress_callbacks.lock
    +					tuples[ 0 ][ 2 ].lock,
    +
    +					// progress_handlers.lock
    +					tuples[ 0 ][ 3 ].lock
    +				);
    +			}
    +
    +			// progress_handlers.fire
    +			// fulfilled_handlers.fire
    +			// rejected_handlers.fire
    +			list.add( tuple[ 3 ].fire );
    +
    +			// deferred.notify = function() { deferred.notifyWith(...) }
    +			// deferred.resolve = function() { deferred.resolveWith(...) }
    +			// deferred.reject = function() { deferred.rejectWith(...) }
    +			deferred[ tuple[ 0 ] ] = function() {
    +				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
    +				return this;
    +			};
    +
    +			// deferred.notifyWith = list.fireWith
    +			// deferred.resolveWith = list.fireWith
    +			// deferred.rejectWith = list.fireWith
    +			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( singleValue ) {
    +		var
    +
    +			// count of uncompleted subordinates
    +			remaining = arguments.length,
    +
    +			// count of unprocessed arguments
    +			i = remaining,
    +
    +			// subordinate fulfillment data
    +			resolveContexts = Array( i ),
    +			resolveValues = slice.call( arguments ),
    +
    +			// the master Deferred
    +			master = jQuery.Deferred(),
    +
    +			// subordinate callback factory
    +			updateFunc = function( i ) {
    +				return function( value ) {
    +					resolveContexts[ i ] = this;
    +					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
    +					if ( !( --remaining ) ) {
    +						master.resolveWith( resolveContexts, resolveValues );
    +					}
    +				};
    +			};
    +
    +		// Single- and empty arguments are adopted like Promise.resolve
    +		if ( remaining <= 1 ) {
    +			adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
    +				!remaining );
    +
    +			// Use .then() to unwrap secondary thenables (cf. gh-3000)
    +			if ( master.state() === "pending" ||
    +				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
    +
    +				return master.then();
    +			}
    +		}
    +
    +		// Multiple arguments are aggregated like Promise.all array elements
    +		while ( i-- ) {
    +			adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
    +		}
    +
    +		return master.promise();
    +	}
    +} );
    +
    +
    +// These usually indicate a programmer mistake during development,
    +// warn about them ASAP rather than swallowing them by default.
    +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
    +
    +jQuery.Deferred.exceptionHook = function( error, stack ) {
    +
    +	// Support: IE 8 - 9 only
    +	// Console exists when dev tools are open, which can happen at any time
    +	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
    +		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
    +	}
    +};
    +
    +
    +
    +
    +jQuery.readyException = function( error ) {
    +	window.setTimeout( function() {
    +		throw error;
    +	} );
    +};
    +
    +
    +
    +
    +// The deferred used on DOM ready
    +var readyList = jQuery.Deferred();
    +
    +jQuery.fn.ready = function( fn ) {
    +
    +	readyList
    +		.then( fn )
    +
    +		// Wrap jQuery.readyException in a function so that the lookup
    +		// happens at the time of error handling instead of callback
    +		// registration.
    +		.catch( function( error ) {
    +			jQuery.readyException( error );
    +		} );
    +
    +	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,
    +
    +	// 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 ] );
    +	}
    +} );
    +
    +jQuery.ready.then = readyList.then;
    +
    +// The ready event handler and self cleanup method
    +function completed() {
    +	document.removeEventListener( "DOMContentLoaded", completed );
    +	window.removeEventListener( "load", completed );
    +	jQuery.ready();
    +}
    +
    +// Catch cases where $(document).ready() is called
    +// after the browser event has already occurred.
    +// Support: IE <=9 - 10 only
    +// Older IE sometimes signals "interactive" too soon
    +if ( document.readyState === "complete" ||
    +	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
    +
    +	// Handle it asynchronously to allow scripts the opportunity to delay ready
    +	window.setTimeout( jQuery.ready );
    +
    +} else {
    +
    +	// Use the handy event callback
    +	document.addEventListener( "DOMContentLoaded", completed );
    +
    +	// A fallback to window.onload, that will always work
    +	window.addEventListener( "load", completed );
    +}
    +
    +
    +
    +
    +// Multifunctional method to get and set values of a collection
    +// The value/s can optionally be executed if it's a function
    +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
    +	var i = 0,
    +		len = elems.length,
    +		bulk = key == null;
    +
    +	// Sets many values
    +	if ( toType( key ) === "object" ) {
    +		chainable = true;
    +		for ( i in key ) {
    +			access( elems, fn, i, key[ i ], true, emptyGet, raw );
    +		}
    +
    +	// Sets one value
    +	} else if ( value !== undefined ) {
    +		chainable = true;
    +
    +		if ( !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 ) )
    +				);
    +			}
    +		}
    +	}
    +
    +	if ( chainable ) {
    +		return elems;
    +	}
    +
    +	// Gets
    +	if ( bulk ) {
    +		return fn.call( elems );
    +	}
    +
    +	return len ? fn( elems[ 0 ], key ) : emptyGet;
    +};
    +
    +
    +// Matches dashed string for camelizing
    +var rmsPrefix = /^-ms-/,
    +	rdashAlpha = /-([a-z])/g;
    +
    +// Used by camelCase as callback to replace()
    +function fcamelCase( all, letter ) {
    +	return letter.toUpperCase();
    +}
    +
    +// Convert dashed to camelCase; used by the css and data modules
    +// Support: IE <=9 - 11, Edge 12 - 15
    +// Microsoft forgot to hump their vendor prefix (#9572)
    +function camelCase( string ) {
    +	return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
    +}
    +var acceptData = function( owner ) {
    +
    +	// Accepts only:
    +	//  - Node
    +	//    - Node.ELEMENT_NODE
    +	//    - Node.DOCUMENT_NODE
    +	//  - Object
    +	//    - Any
    +	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
    +};
    +
    +
    +
    +
    +function Data() {
    +	this.expando = jQuery.expando + Data.uid++;
    +}
    +
    +Data.uid = 1;
    +
    +Data.prototype = {
    +
    +	cache: function( owner ) {
    +
    +		// Check if the owner object already has a cache
    +		var value = owner[ this.expando ];
    +
    +		// If not, create one
    +		if ( !value ) {
    +			value = {};
    +
    +			// We can accept data for non-element nodes in modern browsers,
    +			// but we should not, see #8335.
    +			// Always return an empty object.
    +			if ( acceptData( owner ) ) {
    +
    +				// If it is a node unlikely to be stringify-ed or looped over
    +				// use plain assignment
    +				if ( owner.nodeType ) {
    +					owner[ this.expando ] = value;
    +
    +				// Otherwise secure it in a non-enumerable property
    +				// configurable must be true to allow the property to be
    +				// deleted when data is removed
    +				} else {
    +					Object.defineProperty( owner, this.expando, {
    +						value: value,
    +						configurable: true
    +					} );
    +				}
    +			}
    +		}
    +
    +		return value;
    +	},
    +	set: function( owner, data, value ) {
    +		var prop,
    +			cache = this.cache( owner );
    +
    +		// Handle: [ owner, key, value ] args
    +		// Always use camelCase key (gh-2257)
    +		if ( typeof data === "string" ) {
    +			cache[ camelCase( data ) ] = value;
    +
    +		// Handle: [ owner, { properties } ] args
    +		} else {
    +
    +			// Copy the properties one-by-one to the cache object
    +			for ( prop in data ) {
    +				cache[ camelCase( prop ) ] = data[ prop ];
    +			}
    +		}
    +		return cache;
    +	},
    +	get: function( owner, key ) {
    +		return key === undefined ?
    +			this.cache( owner ) :
    +
    +			// Always use camelCase key (gh-2257)
    +			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
    +	},
    +	access: function( owner, key, value ) {
    +
    +		// 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 ) ) {
    +
    +			return this.get( owner, 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,
    +			cache = owner[ this.expando ];
    +
    +		if ( cache === undefined ) {
    +			return;
    +		}
    +
    +		if ( key !== undefined ) {
    +
    +			// Support array or space separated string of keys
    +			if ( Array.isArray( key ) ) {
    +
    +				// If key is an array of keys...
    +				// We always set camelCase keys, so remove that.
    +				key = key.map( camelCase );
    +			} else {
    +				key = camelCase( key );
    +
    +				// If a key with the spaces exists, use it.
    +				// Otherwise, create an array by matching non-whitespace
    +				key = key in cache ?
    +					[ key ] :
    +					( key.match( rnothtmlwhite ) || [] );
    +			}
    +
    +			i = key.length;
    +
    +			while ( i-- ) {
    +				delete cache[ key[ i ] ];
    +			}
    +		}
    +
    +		// Remove the expando if there's no more data
    +		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
    +
    +			// Support: Chrome <=35 - 45
    +			// Webkit & Blink performance suffers when deleting properties
    +			// from DOM nodes, so set to undefined instead
    +			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
    +			if ( owner.nodeType ) {
    +				owner[ this.expando ] = undefined;
    +			} else {
    +				delete owner[ this.expando ];
    +			}
    +		}
    +	},
    +	hasData: function( owner ) {
    +		var cache = owner[ this.expando ];
    +		return cache !== undefined && !jQuery.isEmptyObject( cache );
    +	}
    +};
    +var dataPriv = new Data();
    +
    +var dataUser = 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 getData( data ) {
    +	if ( data === "true" ) {
    +		return true;
    +	}
    +
    +	if ( data === "false" ) {
    +		return false;
    +	}
    +
    +	if ( data === "null" ) {
    +		return null;
    +	}
    +
    +	// Only convert to a number if it doesn't change the string
    +	if ( data === +data + "" ) {
    +		return +data;
    +	}
    +
    +	if ( rbrace.test( data ) ) {
    +		return JSON.parse( data );
    +	}
    +
    +	return data;
    +}
    +
    +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, "-$&" ).toLowerCase();
    +		data = elem.getAttribute( name );
    +
    +		if ( typeof data === "string" ) {
    +			try {
    +				data = getData( data );
    +			} catch ( e ) {}
    +
    +			// Make sure we set the data so it isn't changed later
    +			dataUser.set( elem, key, data );
    +		} else {
    +			data = undefined;
    +		}
    +	}
    +	return data;
    +}
    +
    +jQuery.extend( {
    +	hasData: function( elem ) {
    +		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
    +	},
    +
    +	data: function( elem, name, data ) {
    +		return dataUser.access( elem, name, data );
    +	},
    +
    +	removeData: function( elem, name ) {
    +		dataUser.remove( elem, name );
    +	},
    +
    +	// TODO: Now that all calls to _data and _removeData have been replaced
    +	// with direct calls to dataPriv methods, these can be deprecated.
    +	_data: function( elem, name, data ) {
    +		return dataPriv.access( elem, name, data );
    +	},
    +
    +	_removeData: function( elem, name ) {
    +		dataPriv.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 = dataUser.get( elem );
    +
    +				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
    +					i = attrs.length;
    +					while ( i-- ) {
    +
    +						// Support: IE 11 only
    +						// The attrs elements can be null (#14894)
    +						if ( attrs[ i ] ) {
    +							name = attrs[ i ].name;
    +							if ( name.indexOf( "data-" ) === 0 ) {
    +								name = camelCase( name.slice( 5 ) );
    +								dataAttr( elem, name, data[ name ] );
    +							}
    +						}
    +					}
    +					dataPriv.set( elem, "hasDataAttrs", true );
    +				}
    +			}
    +
    +			return data;
    +		}
    +
    +		// Sets multiple values
    +		if ( typeof key === "object" ) {
    +			return this.each( function() {
    +				dataUser.set( this, key );
    +			} );
    +		}
    +
    +		return access( this, function( value ) {
    +			var data;
    +
    +			// 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
    +				// The key will always be camelCased in Data
    +				data = dataUser.get( elem, key );
    +				if ( data !== undefined ) {
    +					return data;
    +				}
    +
    +				// Attempt to "discover" the data in
    +				// HTML5 custom data-* attrs
    +				data = dataAttr( elem, key );
    +				if ( data !== undefined ) {
    +					return data;
    +				}
    +
    +				// We tried really hard, but the data doesn't exist.
    +				return;
    +			}
    +
    +			// Set the data...
    +			this.each( function() {
    +
    +				// We always store the camelCased key
    +				dataUser.set( this, key, value );
    +			} );
    +		}, null, value, arguments.length > 1, null, true );
    +	},
    +
    +	removeData: function( key ) {
    +		return this.each( function() {
    +			dataUser.remove( this, key );
    +		} );
    +	}
    +} );
    +
    +
    +jQuery.extend( {
    +	queue: function( elem, type, data ) {
    +		var queue;
    +
    +		if ( elem ) {
    +			type = ( type || "fx" ) + "queue";
    +			queue = dataPriv.get( elem, type );
    +
    +			// Speed up dequeue by getting out quickly if this is just a lookup
    +			if ( data ) {
    +				if ( !queue || Array.isArray( data ) ) {
    +					queue = dataPriv.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 public - generate a queueHooks object, or return the current one
    +	_queueHooks: function( elem, type ) {
    +		var key = type + "queueHooks";
    +		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
    +			empty: jQuery.Callbacks( "once memory" ).add( function() {
    +				dataPriv.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 = dataPriv.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 rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
    +
    +
    +var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
    +
    +var isHiddenWithinTree = function( elem, el ) {
    +
    +		// isHiddenWithinTree might be called from jQuery#filter function;
    +		// in that case, element will be second argument
    +		elem = el || elem;
    +
    +		// Inline style trumps all
    +		return elem.style.display === "none" ||
    +			elem.style.display === "" &&
    +
    +			// Otherwise, check computed style
    +			// Support: Firefox <=43 - 45
    +			// Disconnected elements can have computed display: none, so first confirm that elem is
    +			// in the document.
    +			jQuery.contains( elem.ownerDocument, elem ) &&
    +
    +			jQuery.css( elem, "display" ) === "none";
    +	};
    +
    +var swap = function( elem, options, callback, args ) {
    +	var ret, name,
    +		old = {};
    +
    +	// Remember the old values, and insert the new ones
    +	for ( name in options ) {
    +		old[ name ] = elem.style[ name ];
    +		elem.style[ name ] = options[ name ];
    +	}
    +
    +	ret = callback.apply( elem, args || [] );
    +
    +	// Revert the old values
    +	for ( name in options ) {
    +		elem.style[ name ] = old[ name ];
    +	}
    +
    +	return ret;
    +};
    +
    +
    +
    +
    +function adjustCSS( elem, prop, valueParts, tween ) {
    +	var adjusted, scale,
    +		maxIterations = 20,
    +		currentValue = tween ?
    +			function() {
    +				return tween.cur();
    +			} :
    +			function() {
    +				return jQuery.css( elem, prop, "" );
    +			},
    +		initial = currentValue(),
    +		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
    +
    +		// Starting value computation is required for potential unit mismatches
    +		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
    +			rcssNum.exec( jQuery.css( elem, prop ) );
    +
    +	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
    +
    +		// Support: Firefox <=54
    +		// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
    +		initial = initial / 2;
    +
    +		// Trust units reported by jQuery.css
    +		unit = unit || initialInUnit[ 3 ];
    +
    +		// Iteratively approximate from a nonzero starting point
    +		initialInUnit = +initial || 1;
    +
    +		while ( maxIterations-- ) {
    +
    +			// Evaluate and update our best guess (doubling guesses that zero out).
    +			// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
    +			jQuery.style( elem, prop, initialInUnit + unit );
    +			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
    +				maxIterations = 0;
    +			}
    +			initialInUnit = initialInUnit / scale;
    +
    +		}
    +
    +		initialInUnit = initialInUnit * 2;
    +		jQuery.style( elem, prop, initialInUnit + unit );
    +
    +		// Make sure we update the tween properties later on
    +		valueParts = valueParts || [];
    +	}
    +
    +	if ( valueParts ) {
    +		initialInUnit = +initialInUnit || +initial || 0;
    +
    +		// Apply relative offset (+=/-=) if specified
    +		adjusted = valueParts[ 1 ] ?
    +			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
    +			+valueParts[ 2 ];
    +		if ( tween ) {
    +			tween.unit = unit;
    +			tween.start = initialInUnit;
    +			tween.end = adjusted;
    +		}
    +	}
    +	return adjusted;
    +}
    +
    +
    +var defaultDisplayMap = {};
    +
    +function getDefaultDisplay( elem ) {
    +	var temp,
    +		doc = elem.ownerDocument,
    +		nodeName = elem.nodeName,
    +		display = defaultDisplayMap[ nodeName ];
    +
    +	if ( display ) {
    +		return display;
    +	}
    +
    +	temp = doc.body.appendChild( doc.createElement( nodeName ) );
    +	display = jQuery.css( temp, "display" );
    +
    +	temp.parentNode.removeChild( temp );
    +
    +	if ( display === "none" ) {
    +		display = "block";
    +	}
    +	defaultDisplayMap[ nodeName ] = display;
    +
    +	return display;
    +}
    +
    +function showHide( elements, show ) {
    +	var display, elem,
    +		values = [],
    +		index = 0,
    +		length = elements.length;
    +
    +	// Determine new display value for elements that need to change
    +	for ( ; index < length; index++ ) {
    +		elem = elements[ index ];
    +		if ( !elem.style ) {
    +			continue;
    +		}
    +
    +		display = elem.style.display;
    +		if ( show ) {
    +
    +			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
    +			// check is required in this first loop unless we have a nonempty display value (either
    +			// inline or about-to-be-restored)
    +			if ( display === "none" ) {
    +				values[ index ] = dataPriv.get( elem, "display" ) || null;
    +				if ( !values[ index ] ) {
    +					elem.style.display = "";
    +				}
    +			}
    +			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
    +				values[ index ] = getDefaultDisplay( elem );
    +			}
    +		} else {
    +			if ( display !== "none" ) {
    +				values[ index ] = "none";
    +
    +				// Remember what we're overwriting
    +				dataPriv.set( elem, "display", display );
    +			}
    +		}
    +	}
    +
    +	// Set the display of the elements in a second loop to avoid constant reflow
    +	for ( index = 0; index < length; index++ ) {
    +		if ( values[ index ] != null ) {
    +			elements[ index ].style.display = values[ index ];
    +		}
    +	}
    +
    +	return elements;
    +}
    +
    +jQuery.fn.extend( {
    +	show: function() {
    +		return showHide( this, true );
    +	},
    +	hide: function() {
    +		return showHide( this );
    +	},
    +	toggle: function( state ) {
    +		if ( typeof state === "boolean" ) {
    +			return state ? this.show() : this.hide();
    +		}
    +
    +		return this.each( function() {
    +			if ( isHiddenWithinTree( this ) ) {
    +				jQuery( this ).show();
    +			} else {
    +				jQuery( this ).hide();
    +			}
    +		} );
    +	}
    +} );
    +var rcheckableType = ( /^(?:checkbox|radio)$/i );
    +
    +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
    +
    +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
    +
    +
    +
    +// We have to close these tags to support XHTML (#13200)
    +var wrapMap = {
    +
    +	// Support: IE <=9 only
    +	option: [ 1, "<select multiple='multiple'>", "</select>" ],
    +
    +	// XHTML parsers do not magically insert elements in the
    +	// same way that tag soup parsers do. So we cannot shorten
    +	// this by omitting <tbody> or other required elements.
    +	thead: [ 1, "<table>", "</table>" ],
    +	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
    +	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
    +	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
    +
    +	_default: [ 0, "", "" ]
    +};
    +
    +// Support: IE <=9 only
    +wrapMap.optgroup = wrapMap.option;
    +
    +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
    +wrapMap.th = wrapMap.td;
    +
    +
    +function getAll( context, tag ) {
    +
    +	// Support: IE <=9 - 11 only
    +	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
    +	var ret;
    +
    +	if ( typeof context.getElementsByTagName !== "undefined" ) {
    +		ret = context.getElementsByTagName( tag || "*" );
    +
    +	} else if ( typeof context.querySelectorAll !== "undefined" ) {
    +		ret = context.querySelectorAll( tag || "*" );
    +
    +	} else {
    +		ret = [];
    +	}
    +
    +	if ( tag === undefined || tag && nodeName( context, tag ) ) {
    +		return jQuery.merge( [ context ], ret );
    +	}
    +
    +	return ret;
    +}
    +
    +
    +// Mark scripts as having already been evaluated
    +function setGlobalEval( elems, refElements ) {
    +	var i = 0,
    +		l = elems.length;
    +
    +	for ( ; i < l; i++ ) {
    +		dataPriv.set(
    +			elems[ i ],
    +			"globalEval",
    +			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
    +		);
    +	}
    +}
    +
    +
    +var rhtml = /<|&#?\w+;/;
    +
    +function buildFragment( elems, context, scripts, selection, ignored ) {
    +	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 ( toType( elem ) === "object" ) {
    +
    +				// Support: Android <=4.0 only, PhantomJS 1 only
    +				// push.apply(_, arraylike) throws on ancient WebKit
    +				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 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
    +
    +				// Descend through wrappers to the right content
    +				j = wrap[ 0 ];
    +				while ( j-- ) {
    +					tmp = tmp.lastChild;
    +				}
    +
    +				// Support: Android <=4.0 only, PhantomJS 1 only
    +				// push.apply(_, arraylike) throws on ancient WebKit
    +				jQuery.merge( nodes, tmp.childNodes );
    +
    +				// Remember the top-level container
    +				tmp = fragment.firstChild;
    +
    +				// Ensure the created nodes are orphaned (#12392)
    +				tmp.textContent = "";
    +			}
    +		}
    +	}
    +
    +	// Remove wrapper from fragment
    +	fragment.textContent = "";
    +
    +	i = 0;
    +	while ( ( elem = nodes[ i++ ] ) ) {
    +
    +		// Skip elements already in the context collection (trac-4087)
    +		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
    +			if ( ignored ) {
    +				ignored.push( elem );
    +			}
    +			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;
    +}
    +
    +
    +( function() {
    +	var fragment = document.createDocumentFragment(),
    +		div = fragment.appendChild( document.createElement( "div" ) ),
    +		input = document.createElement( "input" );
    +
    +	// Support: Android 4.0 - 4.3 only
    +	// Check state lost if the name is set (#11217)
    +	// Support: Windows Web Apps (WWA)
    +	// `name` and `type` must use .setAttribute for WWA (#14901)
    +	input.setAttribute( "type", "radio" );
    +	input.setAttribute( "checked", "checked" );
    +	input.setAttribute( "name", "t" );
    +
    +	div.appendChild( input );
    +
    +	// Support: Android <=4.1 only
    +	// Older WebKit doesn't clone checked state correctly in fragments
    +	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
    +
    +	// Support: IE <=11 only
    +	// Make sure textarea (and checkbox) defaultValue is properly cloned
    +	div.innerHTML = "<textarea>x</textarea>";
    +	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
    +} )();
    +var documentElement = document.documentElement;
    +
    +
    +
    +var
    +	rkeyEvent = /^key/,
    +	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
    +	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
    +
    +function returnTrue() {
    +	return true;
    +}
    +
    +function returnFalse() {
    +	return false;
    +}
    +
    +// Support: IE <=9 only
    +// See #13393 for more info
    +function safeActiveElement() {
    +	try {
    +		return document.activeElement;
    +	} catch ( err ) { }
    +}
    +
    +function on( elem, types, selector, data, fn, 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 ) {
    +			on( elem, type, selector, data, types[ type ], one );
    +		}
    +		return elem;
    +	}
    +
    +	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 elem;
    +	}
    +
    +	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 elem.each( function() {
    +		jQuery.event.add( this, types, fn, data, selector );
    +	} );
    +}
    +
    +/*
    + * 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 = dataPriv.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;
    +		}
    +
    +		// Ensure that invalid selectors throw exceptions at attach time
    +		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
    +		if ( selector ) {
    +			jQuery.find.matchesSelector( documentElement, 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 !== "undefined" && jQuery.event.triggered !== e.type ?
    +					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
    +			};
    +		}
    +
    +		// Handle multiple events separated by a space
    +		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
    +		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 );
    +					}
    +				}
    +			}
    +
    +			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 = dataPriv.hasData( elem ) && dataPriv.get( elem );
    +
    +		if ( !elemData || !( events = elemData.events ) ) {
    +			return;
    +		}
    +
    +		// Once for each type.namespace in types; type may be omitted
    +		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
    +		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 data and the expando if it's no longer used
    +		if ( jQuery.isEmptyObject( events ) ) {
    +			dataPriv.remove( elem, "handle events" );
    +		}
    +	},
    +
    +	dispatch: function( nativeEvent ) {
    +
    +		// Make a writable jQuery.Event from the native event object
    +		var event = jQuery.event.fix( nativeEvent );
    +
    +		var i, j, ret, matched, handleObj, handlerQueue,
    +			args = new Array( arguments.length ),
    +			handlers = ( dataPriv.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;
    +
    +		for ( i = 1; i < arguments.length; i++ ) {
    +			args[ i ] = arguments[ i ];
    +		}
    +
    +		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.rnamespace || event.rnamespace.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, handleObj, sel, matchedHandlers, matchedSelectors,
    +			handlerQueue = [],
    +			delegateCount = handlers.delegateCount,
    +			cur = event.target;
    +
    +		// Find delegate handlers
    +		if ( delegateCount &&
    +
    +			// Support: IE <=9
    +			// Black-hole SVG <use> instance trees (trac-13180)
    +			cur.nodeType &&
    +
    +			// Support: Firefox <=42
    +			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
    +			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
    +			// Support: IE 11 only
    +			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
    +			!( event.type === "click" && event.button >= 1 ) ) {
    +
    +			for ( ; cur !== this; cur = cur.parentNode || this ) {
    +
    +				// Don't check non-elements (#13208)
    +				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
    +				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
    +					matchedHandlers = [];
    +					matchedSelectors = {};
    +					for ( i = 0; i < delegateCount; i++ ) {
    +						handleObj = handlers[ i ];
    +
    +						// Don't conflict with Object.prototype properties (#13203)
    +						sel = handleObj.selector + " ";
    +
    +						if ( matchedSelectors[ sel ] === undefined ) {
    +							matchedSelectors[ sel ] = handleObj.needsContext ?
    +								jQuery( sel, this ).index( cur ) > -1 :
    +								jQuery.find( sel, this, null, [ cur ] ).length;
    +						}
    +						if ( matchedSelectors[ sel ] ) {
    +							matchedHandlers.push( handleObj );
    +						}
    +					}
    +					if ( matchedHandlers.length ) {
    +						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
    +					}
    +				}
    +			}
    +		}
    +
    +		// Add the remaining (directly-bound) handlers
    +		cur = this;
    +		if ( delegateCount < handlers.length ) {
    +			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
    +		}
    +
    +		return handlerQueue;
    +	},
    +
    +	addProp: function( name, hook ) {
    +		Object.defineProperty( jQuery.Event.prototype, name, {
    +			enumerable: true,
    +			configurable: true,
    +
    +			get: isFunction( hook ) ?
    +				function() {
    +					if ( this.originalEvent ) {
    +							return hook( this.originalEvent );
    +					}
    +				} :
    +				function() {
    +					if ( this.originalEvent ) {
    +							return this.originalEvent[ name ];
    +					}
    +				},
    +
    +			set: function( value ) {
    +				Object.defineProperty( this, name, {
    +					enumerable: true,
    +					configurable: true,
    +					writable: true,
    +					value: value
    +				} );
    +			}
    +		} );
    +	},
    +
    +	fix: function( originalEvent ) {
    +		return originalEvent[ jQuery.expando ] ?
    +			originalEvent :
    +			new jQuery.Event( originalEvent );
    +	},
    +
    +	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 && nodeName( this, "input" ) ) {
    +					this.click();
    +					return false;
    +				}
    +			},
    +
    +			// For cross-browser consistency, don't fire native .click() on links
    +			_default: function( event ) {
    +				return 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 ) {
    +					event.originalEvent.returnValue = event.result;
    +				}
    +			}
    +		}
    +	}
    +};
    +
    +jQuery.removeEvent = function( elem, type, handle ) {
    +
    +	// This "if" is needed for plain objects
    +	if ( elem.removeEventListener ) {
    +		elem.removeEventListener( type, handle );
    +	}
    +};
    +
    +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 ||
    +				src.defaultPrevented === undefined &&
    +
    +				// Support: Android <=2.3 only
    +				src.returnValue === false ?
    +			returnTrue :
    +			returnFalse;
    +
    +		// Create target properties
    +		// Support: Safari <=6 - 7 only
    +		// Target should not be a text node (#504, #13143)
    +		this.target = ( src.target && src.target.nodeType === 3 ) ?
    +			src.target.parentNode :
    +			src.target;
    +
    +		this.currentTarget = src.currentTarget;
    +		this.relatedTarget = src.relatedTarget;
    +
    +	// 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 || Date.now();
    +
    +	// Mark it as fixed
    +	this[ jQuery.expando ] = true;
    +};
    +
    +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
    +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
    +jQuery.Event.prototype = {
    +	constructor: jQuery.Event,
    +	isDefaultPrevented: returnFalse,
    +	isPropagationStopped: returnFalse,
    +	isImmediatePropagationStopped: returnFalse,
    +	isSimulated: false,
    +
    +	preventDefault: function() {
    +		var e = this.originalEvent;
    +
    +		this.isDefaultPrevented = returnTrue;
    +
    +		if ( e && !this.isSimulated ) {
    +			e.preventDefault();
    +		}
    +	},
    +	stopPropagation: function() {
    +		var e = this.originalEvent;
    +
    +		this.isPropagationStopped = returnTrue;
    +
    +		if ( e && !this.isSimulated ) {
    +			e.stopPropagation();
    +		}
    +	},
    +	stopImmediatePropagation: function() {
    +		var e = this.originalEvent;
    +
    +		this.isImmediatePropagationStopped = returnTrue;
    +
    +		if ( e && !this.isSimulated ) {
    +			e.stopImmediatePropagation();
    +		}
    +
    +		this.stopPropagation();
    +	}
    +};
    +
    +// Includes all common event props including KeyEvent and MouseEvent specific props
    +jQuery.each( {
    +	altKey: true,
    +	bubbles: true,
    +	cancelable: true,
    +	changedTouches: true,
    +	ctrlKey: true,
    +	detail: true,
    +	eventPhase: true,
    +	metaKey: true,
    +	pageX: true,
    +	pageY: true,
    +	shiftKey: true,
    +	view: true,
    +	"char": true,
    +	charCode: true,
    +	key: true,
    +	keyCode: true,
    +	button: true,
    +	buttons: true,
    +	clientX: true,
    +	clientY: true,
    +	offsetX: true,
    +	offsetY: true,
    +	pointerId: true,
    +	pointerType: true,
    +	screenX: true,
    +	screenY: true,
    +	targetTouches: true,
    +	toElement: true,
    +	touches: true,
    +
    +	which: function( event ) {
    +		var button = event.button;
    +
    +		// Add which for key events
    +		if ( event.which == null && rkeyEvent.test( event.type ) ) {
    +			return event.charCode != null ? event.charCode : event.keyCode;
    +		}
    +
    +		// Add which for click: 1 === left; 2 === middle; 3 === right
    +		if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
    +			if ( button & 1 ) {
    +				return 1;
    +			}
    +
    +			if ( button & 2 ) {
    +				return 3;
    +			}
    +
    +			if ( button & 4 ) {
    +				return 2;
    +			}
    +
    +			return 0;
    +		}
    +
    +		return event.which;
    +	}
    +}, jQuery.event.addProp );
    +
    +// Create mouseenter/leave events using mouseover/out and event-time checks
    +// so that event delegation works in jQuery.
    +// Do the same for pointerenter/pointerleave and pointerover/pointerout
    +//
    +// Support: Safari 7 only
    +// Safari sends mouseenter too often; see:
    +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
    +// for the description of the bug (it existed in older Chrome versions as well).
    +jQuery.each( {
    +	mouseenter: "mouseover",
    +	mouseleave: "mouseout",
    +	pointerenter: "pointerover",
    +	pointerleave: "pointerout"
    +}, 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 mouseenter/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;
    +		}
    +	};
    +} );
    +
    +jQuery.fn.extend( {
    +
    +	on: function( types, selector, data, fn ) {
    +		return on( this, types, selector, data, fn );
    +	},
    +	one: function( types, selector, data, fn ) {
    +		return on( this, 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 );
    +		} );
    +	}
    +} );
    +
    +
    +var
    +
    +	/* eslint-disable max-len */
    +
    +	// See https://github.com/eslint/eslint/issues/3229
    +	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
    +
    +	/* eslint-enable */
    +
    +	// Support: IE <=10 - 11, Edge 12 - 13 only
    +	// In IE/Edge using regex groups here causes severe slowdowns.
    +	// See https://connect.microsoft.com/IE/feedback/details/1736512/
    +	rnoInnerhtml = /<script|<style|<link/i,
    +
    +	// checked="checked" or checked
    +	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
    +	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
    +
    +// Prefer a tbody over its parent table for containing new rows
    +function manipulationTarget( elem, content ) {
    +	if ( nodeName( elem, "table" ) &&
    +		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
    +
    +		return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
    +	}
    +
    +	return 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 ) {
    +	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
    +		elem.type = elem.type.slice( 5 );
    +	} else {
    +		elem.removeAttribute( "type" );
    +	}
    +
    +	return elem;
    +}
    +
    +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 ( dataPriv.hasData( src ) ) {
    +		pdataOld = dataPriv.access( src );
    +		pdataCur = dataPriv.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 ( dataUser.hasData( src ) ) {
    +		udataOld = dataUser.access( src );
    +		udataCur = jQuery.extend( {}, udataOld );
    +
    +		dataUser.set( dest, udataCur );
    +	}
    +}
    +
    +// Fix IE bugs, see support tests
    +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;
    +	}
    +}
    +
    +function domManip( collection, args, callback, ignored ) {
    +
    +	// Flatten any nested arrays
    +	args = concat.apply( [], args );
    +
    +	var fragment, first, scripts, hasScripts, node, doc,
    +		i = 0,
    +		l = collection.length,
    +		iNoClone = l - 1,
    +		value = args[ 0 ],
    +		valueIsFunction = isFunction( value );
    +
    +	// We can't cloneNode fragments that contain checked, in WebKit
    +	if ( valueIsFunction ||
    +			( l > 1 && typeof value === "string" &&
    +				!support.checkClone && rchecked.test( value ) ) ) {
    +		return collection.each( function( index ) {
    +			var self = collection.eq( index );
    +			if ( valueIsFunction ) {
    +				args[ 0 ] = value.call( this, index, self.html() );
    +			}
    +			domManip( self, args, callback, ignored );
    +		} );
    +	}
    +
    +	if ( l ) {
    +		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
    +		first = fragment.firstChild;
    +
    +		if ( fragment.childNodes.length === 1 ) {
    +			fragment = first;
    +		}
    +
    +		// Require either new content or an interest in ignored elements to invoke the callback
    +		if ( first || ignored ) {
    +			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: Android <=4.0 only, PhantomJS 1 only
    +						// push.apply(_, arraylike) throws on ancient WebKit
    +						jQuery.merge( scripts, getAll( node, "script" ) );
    +					}
    +				}
    +
    +				callback.call( collection[ 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 || "" ) &&
    +						!dataPriv.access( node, "globalEval" ) &&
    +						jQuery.contains( doc, node ) ) {
    +
    +						if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
    +
    +							// Optional AJAX dependency, but won't run scripts if not present
    +							if ( jQuery._evalUrl ) {
    +								jQuery._evalUrl( node.src );
    +							}
    +						} else {
    +							DOMEval( node.textContent.replace( rcleanScript, "" ), doc, node );
    +						}
    +					}
    +				}
    +			}
    +		}
    +	}
    +
    +	return collection;
    +}
    +
    +function remove( elem, selector, keepData ) {
    +	var node,
    +		nodes = selector ? jQuery.filter( selector, elem ) : elem,
    +		i = 0;
    +
    +	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
    +		if ( !keepData && node.nodeType === 1 ) {
    +			jQuery.cleanData( getAll( node ) );
    +		}
    +
    +		if ( node.parentNode ) {
    +			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
    +				setGlobalEval( getAll( node, "script" ) );
    +			}
    +			node.parentNode.removeChild( node );
    +		}
    +	}
    +
    +	return elem;
    +}
    +
    +jQuery.extend( {
    +	htmlPrefilter: function( html ) {
    +		return html.replace( rxhtmlTag, "<$1></$2>" );
    +	},
    +
    +	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
    +		var i, l, srcElements, destElements,
    +			clone = elem.cloneNode( true ),
    +			inPage = jQuery.contains( elem.ownerDocument, elem );
    +
    +		// Fix IE cloning issues
    +		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
    +				!jQuery.isXMLDoc( elem ) ) {
    +
    +			// We eschew Sizzle here for performance reasons: https://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;
    +	},
    +
    +	cleanData: function( elems ) {
    +		var data, elem, type,
    +			special = jQuery.event.special,
    +			i = 0;
    +
    +		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
    +			if ( acceptData( elem ) ) {
    +				if ( ( data = elem[ dataPriv.expando ] ) ) {
    +					if ( data.events ) {
    +						for ( type in data.events ) {
    +							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 );
    +							}
    +						}
    +					}
    +
    +					// Support: Chrome <=35 - 45+
    +					// Assign undefined instead of using delete, see Data#remove
    +					elem[ dataPriv.expando ] = undefined;
    +				}
    +				if ( elem[ dataUser.expando ] ) {
    +
    +					// Support: Chrome <=35 - 45+
    +					// Assign undefined instead of using delete, see Data#remove
    +					elem[ dataUser.expando ] = undefined;
    +				}
    +			}
    +		}
    +	}
    +} );
    +
    +jQuery.fn.extend( {
    +	detach: function( selector ) {
    +		return remove( this, selector, true );
    +	},
    +
    +	remove: function( selector ) {
    +		return remove( this, selector );
    +	},
    +
    +	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 domManip( this, arguments, function( elem ) {
    +			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
    +				var target = manipulationTarget( this, elem );
    +				target.appendChild( elem );
    +			}
    +		} );
    +	},
    +
    +	prepend: function() {
    +		return domManip( this, 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 domManip( this, arguments, function( elem ) {
    +			if ( this.parentNode ) {
    +				this.parentNode.insertBefore( elem, this );
    +			}
    +		} );
    +	},
    +
    +	after: function() {
    +		return domManip( this, arguments, function( elem ) {
    +			if ( this.parentNode ) {
    +				this.parentNode.insertBefore( elem, this.nextSibling );
    +			}
    +		} );
    +	},
    +
    +	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 = jQuery.htmlPrefilter( value );
    +
    +				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 ignored = [];
    +
    +		// Make the changes, replacing each non-ignored context element with the new content
    +		return domManip( this, arguments, function( elem ) {
    +			var parent = this.parentNode;
    +
    +			if ( jQuery.inArray( this, ignored ) < 0 ) {
    +				jQuery.cleanData( getAll( this ) );
    +				if ( parent ) {
    +					parent.replaceChild( elem, this );
    +				}
    +			}
    +
    +		// Force callback invocation
    +		}, ignored );
    +	}
    +} );
    +
    +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: Android <=4.0 only, PhantomJS 1 only
    +			// .get() because push.apply(_, arraylike) throws on ancient WebKit
    +			push.apply( ret, elems.get() );
    +		}
    +
    +		return this.pushStack( ret );
    +	};
    +} );
    +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
    +
    +var getStyles = function( elem ) {
    +
    +		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
    +		// IE throws on elements created in popups
    +		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
    +		var view = elem.ownerDocument.defaultView;
    +
    +		if ( !view || !view.opener ) {
    +			view = window;
    +		}
    +
    +		return view.getComputedStyle( elem );
    +	};
    +
    +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
    +
    +
    +
    +( function() {
    +
    +	// Executing both pixelPosition & boxSizingReliable tests require only one layout
    +	// so they're executed at the same time to save the second computation.
    +	function computeStyleTests() {
    +
    +		// This is a singleton, we need to execute it only once
    +		if ( !div ) {
    +			return;
    +		}
    +
    +		container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
    +			"margin-top:1px;padding:0;border:0";
    +		div.style.cssText =
    +			"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
    +			"margin:auto;border:1px;padding:1px;" +
    +			"width:60%;top:1%";
    +		documentElement.appendChild( container ).appendChild( div );
    +
    +		var divStyle = window.getComputedStyle( div );
    +		pixelPositionVal = divStyle.top !== "1%";
    +
    +		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
    +		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
    +
    +		// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
    +		// Some styles come back with percentage values, even though they shouldn't
    +		div.style.right = "60%";
    +		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
    +
    +		// Support: IE 9 - 11 only
    +		// Detect misreporting of content dimensions for box-sizing:border-box elements
    +		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
    +
    +		// Support: IE 9 only
    +		// Detect overflow:scroll screwiness (gh-3699)
    +		div.style.position = "absolute";
    +		scrollboxSizeVal = div.offsetWidth === 36 || "absolute";
    +
    +		documentElement.removeChild( container );
    +
    +		// Nullify the div so it wouldn't be stored in the memory and
    +		// it will also be a sign that checks already performed
    +		div = null;
    +	}
    +
    +	function roundPixelMeasures( measure ) {
    +		return Math.round( parseFloat( measure ) );
    +	}
    +
    +	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
    +		reliableMarginLeftVal,
    +		container = document.createElement( "div" ),
    +		div = document.createElement( "div" );
    +
    +	// Finish early in limited (non-browser) environments
    +	if ( !div.style ) {
    +		return;
    +	}
    +
    +	// Support: IE <=9 - 11 only
    +	// Style of cloned element affects source element cloned (#8908)
    +	div.style.backgroundClip = "content-box";
    +	div.cloneNode( true ).style.backgroundClip = "";
    +	support.clearCloneStyle = div.style.backgroundClip === "content-box";
    +
    +	jQuery.extend( support, {
    +		boxSizingReliable: function() {
    +			computeStyleTests();
    +			return boxSizingReliableVal;
    +		},
    +		pixelBoxStyles: function() {
    +			computeStyleTests();
    +			return pixelBoxStylesVal;
    +		},
    +		pixelPosition: function() {
    +			computeStyleTests();
    +			return pixelPositionVal;
    +		},
    +		reliableMarginLeft: function() {
    +			computeStyleTests();
    +			return reliableMarginLeftVal;
    +		},
    +		scrollboxSize: function() {
    +			computeStyleTests();
    +			return scrollboxSizeVal;
    +		}
    +	} );
    +} )();
    +
    +
    +function curCSS( elem, name, computed ) {
    +	var width, minWidth, maxWidth, ret,
    +
    +		// Support: Firefox 51+
    +		// Retrieving style before computed somehow
    +		// fixes an issue with getting wrong values
    +		// on detached elements
    +		style = elem.style;
    +
    +	computed = computed || getStyles( elem );
    +
    +	// getPropertyValue is needed for:
    +	//   .css('filter') (IE 9 only, #12537)
    +	//   .css('--customProperty) (#3144)
    +	if ( computed ) {
    +		ret = computed.getPropertyValue( name ) || computed[ name ];
    +
    +		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
    +			ret = jQuery.style( elem, name );
    +		}
    +
    +		// A tribute to the "awesome hack by Dean Edwards"
    +		// Android Browser returns percentage for some values,
    +		// but width seems to be reliably pixels.
    +		// This is against the CSSOM draft spec:
    +		// https://drafts.csswg.org/cssom/#resolved-values
    +		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
    +
    +			// Remember the original values
    +			width = style.width;
    +			minWidth = style.minWidth;
    +			maxWidth = style.maxWidth;
    +
    +			// Put in the new values to get a computed value out
    +			style.minWidth = style.maxWidth = style.width = ret;
    +			ret = computed.width;
    +
    +			// Revert the changed values
    +			style.width = width;
    +			style.minWidth = minWidth;
    +			style.maxWidth = maxWidth;
    +		}
    +	}
    +
    +	return ret !== undefined ?
    +
    +		// Support: IE <=9 - 11 only
    +		// IE returns zIndex value as an integer.
    +		ret + "" :
    +		ret;
    +}
    +
    +
    +function addGetHookIf( conditionFn, hookFn ) {
    +
    +	// Define the hook, we'll check on the first run if it's really needed.
    +	return {
    +		get: function() {
    +			if ( conditionFn() ) {
    +
    +				// Hook not needed (or it's not possible to use it due
    +				// to missing dependency), remove it.
    +				delete this.get;
    +				return;
    +			}
    +
    +			// Hook needed; redefine it so that the support test is not executed again.
    +			return ( this.get = hookFn ).apply( this, arguments );
    +		}
    +	};
    +}
    +
    +
    +var
    +
    +	// Swappable if display is none or starts with table
    +	// except "table", "table-cell", or "table-caption"
    +	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
    +	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
    +	rcustomProp = /^--/,
    +	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
    +	cssNormalTransform = {
    +		letterSpacing: "0",
    +		fontWeight: "400"
    +	},
    +
    +	cssPrefixes = [ "Webkit", "Moz", "ms" ],
    +	emptyStyle = document.createElement( "div" ).style;
    +
    +// Return a css property mapped to a potentially vendor prefixed property
    +function vendorPropName( name ) {
    +
    +	// Shortcut for names that are not vendor prefixed
    +	if ( name in emptyStyle ) {
    +		return name;
    +	}
    +
    +	// Check for vendor prefixed names
    +	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
    +		i = cssPrefixes.length;
    +
    +	while ( i-- ) {
    +		name = cssPrefixes[ i ] + capName;
    +		if ( name in emptyStyle ) {
    +			return name;
    +		}
    +	}
    +}
    +
    +// Return a property mapped along what jQuery.cssProps suggests or to
    +// a vendor prefixed property.
    +function finalPropName( name ) {
    +	var ret = jQuery.cssProps[ name ];
    +	if ( !ret ) {
    +		ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
    +	}
    +	return ret;
    +}
    +
    +function setPositiveNumber( elem, value, subtract ) {
    +
    +	// Any relative (+/-) values have already been
    +	// normalized at this point
    +	var matches = rcssNum.exec( value );
    +	return matches ?
    +
    +		// Guard against undefined "subtract", e.g., when used as in cssHooks
    +		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
    +		value;
    +}
    +
    +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
    +	var i = dimension === "width" ? 1 : 0,
    +		extra = 0,
    +		delta = 0;
    +
    +	// Adjustment may not be necessary
    +	if ( box === ( isBorderBox ? "border" : "content" ) ) {
    +		return 0;
    +	}
    +
    +	for ( ; i < 4; i += 2 ) {
    +
    +		// Both box models exclude margin
    +		if ( box === "margin" ) {
    +			delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
    +		}
    +
    +		// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
    +		if ( !isBorderBox ) {
    +
    +			// Add padding
    +			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
    +
    +			// For "border" or "margin", add border
    +			if ( box !== "padding" ) {
    +				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
    +
    +			// But still keep track of it otherwise
    +			} else {
    +				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
    +			}
    +
    +		// If we get here with a border-box (content + padding + border), we're seeking "content" or
    +		// "padding" or "margin"
    +		} else {
    +
    +			// For "content", subtract padding
    +			if ( box === "content" ) {
    +				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
    +			}
    +
    +			// For "content" or "padding", subtract border
    +			if ( box !== "margin" ) {
    +				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
    +			}
    +		}
    +	}
    +
    +	// Account for positive content-box scroll gutter when requested by providing computedVal
    +	if ( !isBorderBox && computedVal >= 0 ) {
    +
    +		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
    +		// Assuming integer scroll gutter, subtract the rest and round down
    +		delta += Math.max( 0, Math.ceil(
    +			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
    +			computedVal -
    +			delta -
    +			extra -
    +			0.5
    +		) );
    +	}
    +
    +	return delta;
    +}
    +
    +function getWidthOrHeight( elem, dimension, extra ) {
    +
    +	// Start with computed style
    +	var styles = getStyles( elem ),
    +		val = curCSS( elem, dimension, styles ),
    +		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
    +		valueIsBorderBox = isBorderBox;
    +
    +	// Support: Firefox <=54
    +	// Return a confounding non-pixel value or feign ignorance, as appropriate.
    +	if ( rnumnonpx.test( val ) ) {
    +		if ( !extra ) {
    +			return val;
    +		}
    +		val = "auto";
    +	}
    +
    +	// Check for style in case a browser which returns unreliable values
    +	// for getComputedStyle silently falls back to the reliable elem.style
    +	valueIsBorderBox = valueIsBorderBox &&
    +		( support.boxSizingReliable() || val === elem.style[ dimension ] );
    +
    +	// Fall back to offsetWidth/offsetHeight when value is "auto"
    +	// This happens for inline elements with no explicit setting (gh-3571)
    +	// Support: Android <=4.1 - 4.3 only
    +	// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
    +	if ( val === "auto" ||
    +		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) {
    +
    +		val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ];
    +
    +		// offsetWidth/offsetHeight provide border-box values
    +		valueIsBorderBox = true;
    +	}
    +
    +	// Normalize "" and auto
    +	val = parseFloat( val ) || 0;
    +
    +	// Adjust for the element's box model
    +	return ( val +
    +		boxModelAdjustment(
    +			elem,
    +			dimension,
    +			extra || ( isBorderBox ? "border" : "content" ),
    +			valueIsBorderBox,
    +			styles,
    +
    +			// Provide the current computed size to request scroll gutter calculation (gh-3589)
    +			val
    +		)
    +	) + "px";
    +}
    +
    +jQuery.extend( {
    +
    +	// Add in style property hooks for overriding the default
    +	// behavior of getting and setting a style property
    +	cssHooks: {
    +		opacity: {
    +			get: function( elem, computed ) {
    +				if ( computed ) {
    +
    +					// We should always get a number back from opacity
    +					var ret = curCSS( elem, "opacity" );
    +					return ret === "" ? "1" : ret;
    +				}
    +			}
    +		}
    +	},
    +
    +	// Don't automatically add "px" to these possibly-unitless properties
    +	cssNumber: {
    +		"animationIterationCount": true,
    +		"columnCount": true,
    +		"fillOpacity": true,
    +		"flexGrow": true,
    +		"flexShrink": true,
    +		"fontWeight": true,
    +		"lineHeight": true,
    +		"opacity": true,
    +		"order": true,
    +		"orphans": true,
    +		"widows": true,
    +		"zIndex": true,
    +		"zoom": true
    +	},
    +
    +	// Add in properties whose names you wish to fix before
    +	// setting or getting the value
    +	cssProps: {},
    +
    +	// Get and set the style property on a DOM Node
    +	style: function( elem, name, value, extra ) {
    +
    +		// Don't set styles on text and comment nodes
    +		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
    +			return;
    +		}
    +
    +		// Make sure that we're working with the right name
    +		var ret, type, hooks,
    +			origName = camelCase( name ),
    +			isCustomProp = rcustomProp.test( name ),
    +			style = elem.style;
    +
    +		// Make sure that we're working with the right name. We don't
    +		// want to query the value if it is a CSS custom property
    +		// since they are user-defined.
    +		if ( !isCustomProp ) {
    +			name = finalPropName( origName );
    +		}
    +
    +		// Gets hook for the prefixed version, then unprefixed version
    +		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
    +
    +		// Check if we're setting a value
    +		if ( value !== undefined ) {
    +			type = typeof value;
    +
    +			// Convert "+=" or "-=" to relative numbers (#7345)
    +			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
    +				value = adjustCSS( elem, name, ret );
    +
    +				// Fixes bug #9237
    +				type = "number";
    +			}
    +
    +			// Make sure that null and NaN values aren't set (#7116)
    +			if ( value == null || value !== value ) {
    +				return;
    +			}
    +
    +			// If a number was passed in, add the unit (except for certain CSS properties)
    +			if ( type === "number" ) {
    +				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
    +			}
    +
    +			// background-* props affect original clone's values
    +			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
    +				style[ name ] = "inherit";
    +			}
    +
    +			// If a hook was provided, use that value, otherwise just set the specified value
    +			if ( !hooks || !( "set" in hooks ) ||
    +				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
    +
    +				if ( isCustomProp ) {
    +					style.setProperty( name, value );
    +				} else {
    +					style[ name ] = value;
    +				}
    +			}
    +
    +		} else {
    +
    +			// If a hook was provided get the non-computed value from there
    +			if ( hooks && "get" in hooks &&
    +				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
    +
    +				return ret;
    +			}
    +
    +			// Otherwise just get the value from the style object
    +			return style[ name ];
    +		}
    +	},
    +
    +	css: function( elem, name, extra, styles ) {
    +		var val, num, hooks,
    +			origName = camelCase( name ),
    +			isCustomProp = rcustomProp.test( name );
    +
    +		// Make sure that we're working with the right name. We don't
    +		// want to modify the value if it is a CSS custom property
    +		// since they are user-defined.
    +		if ( !isCustomProp ) {
    +			name = finalPropName( origName );
    +		}
    +
    +		// Try prefixed name followed by the unprefixed name
    +		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
    +
    +		// If a hook was provided get the computed value from there
    +		if ( hooks && "get" in hooks ) {
    +			val = hooks.get( elem, true, extra );
    +		}
    +
    +		// Otherwise, if a way to get the computed value exists, use that
    +		if ( val === undefined ) {
    +			val = curCSS( elem, name, styles );
    +		}
    +
    +		// Convert "normal" to computed value
    +		if ( val === "normal" && name in cssNormalTransform ) {
    +			val = cssNormalTransform[ name ];
    +		}
    +
    +		// Make numeric if forced or a qualifier was provided and val looks numeric
    +		if ( extra === "" || extra ) {
    +			num = parseFloat( val );
    +			return extra === true || isFinite( num ) ? num || 0 : val;
    +		}
    +
    +		return val;
    +	}
    +} );
    +
    +jQuery.each( [ "height", "width" ], function( i, dimension ) {
    +	jQuery.cssHooks[ dimension ] = {
    +		get: function( elem, computed, extra ) {
    +			if ( computed ) {
    +
    +				// Certain elements can have dimension info if we invisibly show them
    +				// but it must have a current display style that would benefit
    +				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
    +
    +					// Support: Safari 8+
    +					// Table columns in Safari have non-zero offsetWidth & zero
    +					// getBoundingClientRect().width unless display is changed.
    +					// Support: IE <=11 only
    +					// Running getBoundingClientRect on a disconnected node
    +					// in IE throws an error.
    +					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
    +						swap( elem, cssShow, function() {
    +							return getWidthOrHeight( elem, dimension, extra );
    +						} ) :
    +						getWidthOrHeight( elem, dimension, extra );
    +			}
    +		},
    +
    +		set: function( elem, value, extra ) {
    +			var matches,
    +				styles = getStyles( elem ),
    +				isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
    +				subtract = extra && boxModelAdjustment(
    +					elem,
    +					dimension,
    +					extra,
    +					isBorderBox,
    +					styles
    +				);
    +
    +			// Account for unreliable border-box dimensions by comparing offset* to computed and
    +			// faking a content-box to get border and padding (gh-3699)
    +			if ( isBorderBox && support.scrollboxSize() === styles.position ) {
    +				subtract -= Math.ceil(
    +					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
    +					parseFloat( styles[ dimension ] ) -
    +					boxModelAdjustment( elem, dimension, "border", false, styles ) -
    +					0.5
    +				);
    +			}
    +
    +			// Convert to pixels if value adjustment is needed
    +			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
    +				( matches[ 3 ] || "px" ) !== "px" ) {
    +
    +				elem.style[ dimension ] = value;
    +				value = jQuery.css( elem, dimension );
    +			}
    +
    +			return setPositiveNumber( elem, value, subtract );
    +		}
    +	};
    +} );
    +
    +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
    +	function( elem, computed ) {
    +		if ( computed ) {
    +			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
    +				elem.getBoundingClientRect().left -
    +					swap( elem, { marginLeft: 0 }, function() {
    +						return elem.getBoundingClientRect().left;
    +					} )
    +				) + "px";
    +		}
    +	}
    +);
    +
    +// These hooks are used by animate to expand properties
    +jQuery.each( {
    +	margin: "",
    +	padding: "",
    +	border: "Width"
    +}, function( prefix, suffix ) {
    +	jQuery.cssHooks[ prefix + suffix ] = {
    +		expand: function( value ) {
    +			var i = 0,
    +				expanded = {},
    +
    +				// Assumes a single number if not a string
    +				parts = typeof value === "string" ? value.split( " " ) : [ value ];
    +
    +			for ( ; i < 4; i++ ) {
    +				expanded[ prefix + cssExpand[ i ] + suffix ] =
    +					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
    +			}
    +
    +			return expanded;
    +		}
    +	};
    +
    +	if ( prefix !== "margin" ) {
    +		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
    +	}
    +} );
    +
    +jQuery.fn.extend( {
    +	css: function( name, value ) {
    +		return access( this, function( elem, name, value ) {
    +			var styles, len,
    +				map = {},
    +				i = 0;
    +
    +			if ( Array.isArray( name ) ) {
    +				styles = getStyles( elem );
    +				len = name.length;
    +
    +				for ( ; i < len; i++ ) {
    +					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
    +				}
    +
    +				return map;
    +			}
    +
    +			return value !== undefined ?
    +				jQuery.style( elem, name, value ) :
    +				jQuery.css( elem, name );
    +		}, name, value, arguments.length > 1 );
    +	}
    +} );
    +
    +
    +function Tween( elem, options, prop, end, easing ) {
    +	return new Tween.prototype.init( elem, options, prop, end, easing );
    +}
    +jQuery.Tween = Tween;
    +
    +Tween.prototype = {
    +	constructor: Tween,
    +	init: function( elem, options, prop, end, easing, unit ) {
    +		this.elem = elem;
    +		this.prop = prop;
    +		this.easing = easing || jQuery.easing._default;
    +		this.options = options;
    +		this.start = this.now = this.cur();
    +		this.end = end;
    +		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
    +	},
    +	cur: function() {
    +		var hooks = Tween.propHooks[ this.prop ];
    +
    +		return hooks && hooks.get ?
    +			hooks.get( this ) :
    +			Tween.propHooks._default.get( this );
    +	},
    +	run: function( percent ) {
    +		var eased,
    +			hooks = Tween.propHooks[ this.prop ];
    +
    +		if ( this.options.duration ) {
    +			this.pos = eased = jQuery.easing[ this.easing ](
    +				percent, this.options.duration * percent, 0, 1, this.options.duration
    +			);
    +		} else {
    +			this.pos = eased = percent;
    +		}
    +		this.now = ( this.end - this.start ) * eased + this.start;
    +
    +		if ( this.options.step ) {
    +			this.options.step.call( this.elem, this.now, this );
    +		}
    +
    +		if ( hooks && hooks.set ) {
    +			hooks.set( this );
    +		} else {
    +			Tween.propHooks._default.set( this );
    +		}
    +		return this;
    +	}
    +};
    +
    +Tween.prototype.init.prototype = Tween.prototype;
    +
    +Tween.propHooks = {
    +	_default: {
    +		get: function( tween ) {
    +			var result;
    +
    +			// Use a property on the element directly when it is not a DOM element,
    +			// or when there is no matching style property that exists.
    +			if ( tween.elem.nodeType !== 1 ||
    +				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
    +				return tween.elem[ tween.prop ];
    +			}
    +
    +			// Passing an empty string as a 3rd parameter to .css will automatically
    +			// attempt a parseFloat and fallback to a string if the parse fails.
    +			// Simple values such as "10px" are parsed to Float;
    +			// complex values such as "rotate(1rad)" are returned as-is.
    +			result = jQuery.css( tween.elem, tween.prop, "" );
    +
    +			// Empty strings, null, undefined and "auto" are converted to 0.
    +			return !result || result === "auto" ? 0 : result;
    +		},
    +		set: function( tween ) {
    +
    +			// Use step hook for back compat.
    +			// Use cssHook if its there.
    +			// Use .style if available and use plain properties where available.
    +			if ( jQuery.fx.step[ tween.prop ] ) {
    +				jQuery.fx.step[ tween.prop ]( tween );
    +			} else if ( tween.elem.nodeType === 1 &&
    +				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
    +					jQuery.cssHooks[ tween.prop ] ) ) {
    +				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
    +			} else {
    +				tween.elem[ tween.prop ] = tween.now;
    +			}
    +		}
    +	}
    +};
    +
    +// Support: IE <=9 only
    +// Panic based approach to setting things on disconnected nodes
    +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
    +	set: function( tween ) {
    +		if ( tween.elem.nodeType && tween.elem.parentNode ) {
    +			tween.elem[ tween.prop ] = tween.now;
    +		}
    +	}
    +};
    +
    +jQuery.easing = {
    +	linear: function( p ) {
    +		return p;
    +	},
    +	swing: function( p ) {
    +		return 0.5 - Math.cos( p * Math.PI ) / 2;
    +	},
    +	_default: "swing"
    +};
    +
    +jQuery.fx = Tween.prototype.init;
    +
    +// Back compat <1.8 extension point
    +jQuery.fx.step = {};
    +
    +
    +
    +
    +var
    +	fxNow, inProgress,
    +	rfxtypes = /^(?:toggle|show|hide)$/,
    +	rrun = /queueHooks$/;
    +
    +function schedule() {
    +	if ( inProgress ) {
    +		if ( document.hidden === false && window.requestAnimationFrame ) {
    +			window.requestAnimationFrame( schedule );
    +		} else {
    +			window.setTimeout( schedule, jQuery.fx.interval );
    +		}
    +
    +		jQuery.fx.tick();
    +	}
    +}
    +
    +// Animations created synchronously will run synchronously
    +function createFxNow() {
    +	window.setTimeout( function() {
    +		fxNow = undefined;
    +	} );
    +	return ( fxNow = Date.now() );
    +}
    +
    +// Generate parameters to create a standard animation
    +function genFx( type, includeWidth ) {
    +	var which,
    +		i = 0,
    +		attrs = { height: type };
    +
    +	// If we include width, step value is 1 to do all cssExpand values,
    +	// otherwise step value is 2 to skip over Left and Right
    +	includeWidth = includeWidth ? 1 : 0;
    +	for ( ; i < 4; i += 2 - includeWidth ) {
    +		which = cssExpand[ i ];
    +		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
    +	}
    +
    +	if ( includeWidth ) {
    +		attrs.opacity = attrs.width = type;
    +	}
    +
    +	return attrs;
    +}
    +
    +function createTween( value, prop, animation ) {
    +	var tween,
    +		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
    +		index = 0,
    +		length = collection.length;
    +	for ( ; index < length; index++ ) {
    +		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
    +
    +			// We're done with this property
    +			return tween;
    +		}
    +	}
    +}
    +
    +function defaultPrefilter( elem, props, opts ) {
    +	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
    +		isBox = "width" in props || "height" in props,
    +		anim = this,
    +		orig = {},
    +		style = elem.style,
    +		hidden = elem.nodeType && isHiddenWithinTree( elem ),
    +		dataShow = dataPriv.get( elem, "fxshow" );
    +
    +	// Queue-skipping animations hijack the fx hooks
    +	if ( !opts.queue ) {
    +		hooks = jQuery._queueHooks( elem, "fx" );
    +		if ( hooks.unqueued == null ) {
    +			hooks.unqueued = 0;
    +			oldfire = hooks.empty.fire;
    +			hooks.empty.fire = function() {
    +				if ( !hooks.unqueued ) {
    +					oldfire();
    +				}
    +			};
    +		}
    +		hooks.unqueued++;
    +
    +		anim.always( function() {
    +
    +			// Ensure the complete handler is called before this completes
    +			anim.always( function() {
    +				hooks.unqueued--;
    +				if ( !jQuery.queue( elem, "fx" ).length ) {
    +					hooks.empty.fire();
    +				}
    +			} );
    +		} );
    +	}
    +
    +	// Detect show/hide animations
    +	for ( prop in props ) {
    +		value = props[ prop ];
    +		if ( rfxtypes.test( value ) ) {
    +			delete props[ prop ];
    +			toggle = toggle || value === "toggle";
    +			if ( value === ( hidden ? "hide" : "show" ) ) {
    +
    +				// Pretend to be hidden if this is a "show" and
    +				// there is still data from a stopped show/hide
    +				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
    +					hidden = true;
    +
    +				// Ignore all other no-op show/hide data
    +				} else {
    +					continue;
    +				}
    +			}
    +			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
    +		}
    +	}
    +
    +	// Bail out if this is a no-op like .hide().hide()
    +	propTween = !jQuery.isEmptyObject( props );
    +	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
    +		return;
    +	}
    +
    +	// Restrict "overflow" and "display" styles during box animations
    +	if ( isBox && elem.nodeType === 1 ) {
    +
    +		// Support: IE <=9 - 11, Edge 12 - 15
    +		// Record all 3 overflow attributes because IE does not infer the shorthand
    +		// from identically-valued overflowX and overflowY and Edge just mirrors
    +		// the overflowX value there.
    +		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
    +
    +		// Identify a display type, preferring old show/hide data over the CSS cascade
    +		restoreDisplay = dataShow && dataShow.display;
    +		if ( restoreDisplay == null ) {
    +			restoreDisplay = dataPriv.get( elem, "display" );
    +		}
    +		display = jQuery.css( elem, "display" );
    +		if ( display === "none" ) {
    +			if ( restoreDisplay ) {
    +				display = restoreDisplay;
    +			} else {
    +
    +				// Get nonempty value(s) by temporarily forcing visibility
    +				showHide( [ elem ], true );
    +				restoreDisplay = elem.style.display || restoreDisplay;
    +				display = jQuery.css( elem, "display" );
    +				showHide( [ elem ] );
    +			}
    +		}
    +
    +		// Animate inline elements as inline-block
    +		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
    +			if ( jQuery.css( elem, "float" ) === "none" ) {
    +
    +				// Restore the original display value at the end of pure show/hide animations
    +				if ( !propTween ) {
    +					anim.done( function() {
    +						style.display = restoreDisplay;
    +					} );
    +					if ( restoreDisplay == null ) {
    +						display = style.display;
    +						restoreDisplay = display === "none" ? "" : display;
    +					}
    +				}
    +				style.display = "inline-block";
    +			}
    +		}
    +	}
    +
    +	if ( opts.overflow ) {
    +		style.overflow = "hidden";
    +		anim.always( function() {
    +			style.overflow = opts.overflow[ 0 ];
    +			style.overflowX = opts.overflow[ 1 ];
    +			style.overflowY = opts.overflow[ 2 ];
    +		} );
    +	}
    +
    +	// Implement show/hide animations
    +	propTween = false;
    +	for ( prop in orig ) {
    +
    +		// General show/hide setup for this element animation
    +		if ( !propTween ) {
    +			if ( dataShow ) {
    +				if ( "hidden" in dataShow ) {
    +					hidden = dataShow.hidden;
    +				}
    +			} else {
    +				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
    +			}
    +
    +			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
    +			if ( toggle ) {
    +				dataShow.hidden = !hidden;
    +			}
    +
    +			// Show elements before animating them
    +			if ( hidden ) {
    +				showHide( [ elem ], true );
    +			}
    +
    +			/* eslint-disable no-loop-func */
    +
    +			anim.done( function() {
    +
    +			/* eslint-enable no-loop-func */
    +
    +				// The final step of a "hide" animation is actually hiding the element
    +				if ( !hidden ) {
    +					showHide( [ elem ] );
    +				}
    +				dataPriv.remove( elem, "fxshow" );
    +				for ( prop in orig ) {
    +					jQuery.style( elem, prop, orig[ prop ] );
    +				}
    +			} );
    +		}
    +
    +		// Per-property setup
    +		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
    +		if ( !( prop in dataShow ) ) {
    +			dataShow[ prop ] = propTween.start;
    +			if ( hidden ) {
    +				propTween.end = propTween.start;
    +				propTween.start = 0;
    +			}
    +		}
    +	}
    +}
    +
    +function propFilter( props, specialEasing ) {
    +	var index, name, easing, value, hooks;
    +
    +	// camelCase, specialEasing and expand cssHook pass
    +	for ( index in props ) {
    +		name = camelCase( index );
    +		easing = specialEasing[ name ];
    +		value = props[ index ];
    +		if ( Array.isArray( value ) ) {
    +			easing = value[ 1 ];
    +			value = props[ index ] = value[ 0 ];
    +		}
    +
    +		if ( index !== name ) {
    +			props[ name ] = value;
    +			delete props[ index ];
    +		}
    +
    +		hooks = jQuery.cssHooks[ name ];
    +		if ( hooks && "expand" in hooks ) {
    +			value = hooks.expand( value );
    +			delete props[ name ];
    +
    +			// Not quite $.extend, this won't overwrite existing keys.
    +			// Reusing 'index' because we have the correct "name"
    +			for ( index in value ) {
    +				if ( !( index in props ) ) {
    +					props[ index ] = value[ index ];
    +					specialEasing[ index ] = easing;
    +				}
    +			}
    +		} else {
    +			specialEasing[ name ] = easing;
    +		}
    +	}
    +}
    +
    +function Animation( elem, properties, options ) {
    +	var result,
    +		stopped,
    +		index = 0,
    +		length = Animation.prefilters.length,
    +		deferred = jQuery.Deferred().always( function() {
    +
    +			// Don't match elem in the :animated selector
    +			delete tick.elem;
    +		} ),
    +		tick = function() {
    +			if ( stopped ) {
    +				return false;
    +			}
    +			var currentTime = fxNow || createFxNow(),
    +				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
    +
    +				// Support: Android 2.3 only
    +				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
    +				temp = remaining / animation.duration || 0,
    +				percent = 1 - temp,
    +				index = 0,
    +				length = animation.tweens.length;
    +
    +			for ( ; index < length; index++ ) {
    +				animation.tweens[ index ].run( percent );
    +			}
    +
    +			deferred.notifyWith( elem, [ animation, percent, remaining ] );
    +
    +			// If there's more to do, yield
    +			if ( percent < 1 && length ) {
    +				return remaining;
    +			}
    +
    +			// If this was an empty animation, synthesize a final progress notification
    +			if ( !length ) {
    +				deferred.notifyWith( elem, [ animation, 1, 0 ] );
    +			}
    +
    +			// Resolve the animation and report its conclusion
    +			deferred.resolveWith( elem, [ animation ] );
    +			return false;
    +		},
    +		animation = deferred.promise( {
    +			elem: elem,
    +			props: jQuery.extend( {}, properties ),
    +			opts: jQuery.extend( true, {
    +				specialEasing: {},
    +				easing: jQuery.easing._default
    +			}, options ),
    +			originalProperties: properties,
    +			originalOptions: options,
    +			startTime: fxNow || createFxNow(),
    +			duration: options.duration,
    +			tweens: [],
    +			createTween: function( prop, end ) {
    +				var tween = jQuery.Tween( elem, animation.opts, prop, end,
    +						animation.opts.specialEasing[ prop ] || animation.opts.easing );
    +				animation.tweens.push( tween );
    +				return tween;
    +			},
    +			stop: function( gotoEnd ) {
    +				var index = 0,
    +
    +					// If we are going to the end, we want to run all the tweens
    +					// otherwise we skip this part
    +					length = gotoEnd ? animation.tweens.length : 0;
    +				if ( stopped ) {
    +					return this;
    +				}
    +				stopped = true;
    +				for ( ; index < length; index++ ) {
    +					animation.tweens[ index ].run( 1 );
    +				}
    +
    +				// Resolve when we played the last frame; otherwise, reject
    +				if ( gotoEnd ) {
    +					deferred.notifyWith( elem, [ animation, 1, 0 ] );
    +					deferred.resolveWith( elem, [ animation, gotoEnd ] );
    +				} else {
    +					deferred.rejectWith( elem, [ animation, gotoEnd ] );
    +				}
    +				return this;
    +			}
    +		} ),
    +		props = animation.props;
    +
    +	propFilter( props, animation.opts.specialEasing );
    +
    +	for ( ; index < length; index++ ) {
    +		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
    +		if ( result ) {
    +			if ( isFunction( result.stop ) ) {
    +				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
    +					result.stop.bind( result );
    +			}
    +			return result;
    +		}
    +	}
    +
    +	jQuery.map( props, createTween, animation );
    +
    +	if ( isFunction( animation.opts.start ) ) {
    +		animation.opts.start.call( elem, animation );
    +	}
    +
    +	// Attach callbacks from options
    +	animation
    +		.progress( animation.opts.progress )
    +		.done( animation.opts.done, animation.opts.complete )
    +		.fail( animation.opts.fail )
    +		.always( animation.opts.always );
    +
    +	jQuery.fx.timer(
    +		jQuery.extend( tick, {
    +			elem: elem,
    +			anim: animation,
    +			queue: animation.opts.queue
    +		} )
    +	);
    +
    +	return animation;
    +}
    +
    +jQuery.Animation = jQuery.extend( Animation, {
    +
    +	tweeners: {
    +		"*": [ function( prop, value ) {
    +			var tween = this.createTween( prop, value );
    +			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
    +			return tween;
    +		} ]
    +	},
    +
    +	tweener: function( props, callback ) {
    +		if ( isFunction( props ) ) {
    +			callback = props;
    +			props = [ "*" ];
    +		} else {
    +			props = props.match( rnothtmlwhite );
    +		}
    +
    +		var prop,
    +			index = 0,
    +			length = props.length;
    +
    +		for ( ; index < length; index++ ) {
    +			prop = props[ index ];
    +			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
    +			Animation.tweeners[ prop ].unshift( callback );
    +		}
    +	},
    +
    +	prefilters: [ defaultPrefilter ],
    +
    +	prefilter: function( callback, prepend ) {
    +		if ( prepend ) {
    +			Animation.prefilters.unshift( callback );
    +		} else {
    +			Animation.prefilters.push( callback );
    +		}
    +	}
    +} );
    +
    +jQuery.speed = function( speed, easing, fn ) {
    +	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
    +		complete: fn || !fn && easing ||
    +			isFunction( speed ) && speed,
    +		duration: speed,
    +		easing: fn && easing || easing && !isFunction( easing ) && easing
    +	};
    +
    +	// Go to the end state if fx are off
    +	if ( jQuery.fx.off ) {
    +		opt.duration = 0;
    +
    +	} else {
    +		if ( typeof opt.duration !== "number" ) {
    +			if ( opt.duration in jQuery.fx.speeds ) {
    +				opt.duration = jQuery.fx.speeds[ opt.duration ];
    +
    +			} else {
    +				opt.duration = jQuery.fx.speeds._default;
    +			}
    +		}
    +	}
    +
    +	// Normalize opt.queue - true/undefined/null -> "fx"
    +	if ( opt.queue == null || opt.queue === true ) {
    +		opt.queue = "fx";
    +	}
    +
    +	// Queueing
    +	opt.old = opt.complete;
    +
    +	opt.complete = function() {
    +		if ( isFunction( opt.old ) ) {
    +			opt.old.call( this );
    +		}
    +
    +		if ( opt.queue ) {
    +			jQuery.dequeue( this, opt.queue );
    +		}
    +	};
    +
    +	return opt;
    +};
    +
    +jQuery.fn.extend( {
    +	fadeTo: function( speed, to, easing, callback ) {
    +
    +		// Show any hidden elements after setting opacity to 0
    +		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
    +
    +			// Animate to the value specified
    +			.end().animate( { opacity: to }, speed, easing, callback );
    +	},
    +	animate: function( prop, speed, easing, callback ) {
    +		var empty = jQuery.isEmptyObject( prop ),
    +			optall = jQuery.speed( speed, easing, callback ),
    +			doAnimation = function() {
    +
    +				// Operate on a copy of prop so per-property easing won't be lost
    +				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
    +
    +				// Empty animations, or finishing resolves immediately
    +				if ( empty || dataPriv.get( this, "finish" ) ) {
    +					anim.stop( true );
    +				}
    +			};
    +			doAnimation.finish = doAnimation;
    +
    +		return empty || optall.queue === false ?
    +			this.each( doAnimation ) :
    +			this.queue( optall.queue, doAnimation );
    +	},
    +	stop: function( type, clearQueue, gotoEnd ) {
    +		var stopQueue = function( hooks ) {
    +			var stop = hooks.stop;
    +			delete hooks.stop;
    +			stop( gotoEnd );
    +		};
    +
    +		if ( typeof type !== "string" ) {
    +			gotoEnd = clearQueue;
    +			clearQueue = type;
    +			type = undefined;
    +		}
    +		if ( clearQueue && type !== false ) {
    +			this.queue( type || "fx", [] );
    +		}
    +
    +		return this.each( function() {
    +			var dequeue = true,
    +				index = type != null && type + "queueHooks",
    +				timers = jQuery.timers,
    +				data = dataPriv.get( this );
    +
    +			if ( index ) {
    +				if ( data[ index ] && data[ index ].stop ) {
    +					stopQueue( data[ index ] );
    +				}
    +			} else {
    +				for ( index in data ) {
    +					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
    +						stopQueue( data[ index ] );
    +					}
    +				}
    +			}
    +
    +			for ( index = timers.length; index--; ) {
    +				if ( timers[ index ].elem === this &&
    +					( type == null || timers[ index ].queue === type ) ) {
    +
    +					timers[ index ].anim.stop( gotoEnd );
    +					dequeue = false;
    +					timers.splice( index, 1 );
    +				}
    +			}
    +
    +			// Start the next in the queue if the last step wasn't forced.
    +			// Timers currently will call their complete callbacks, which
    +			// will dequeue but only if they were gotoEnd.
    +			if ( dequeue || !gotoEnd ) {
    +				jQuery.dequeue( this, type );
    +			}
    +		} );
    +	},
    +	finish: function( type ) {
    +		if ( type !== false ) {
    +			type = type || "fx";
    +		}
    +		return this.each( function() {
    +			var index,
    +				data = dataPriv.get( this ),
    +				queue = data[ type + "queue" ],
    +				hooks = data[ type + "queueHooks" ],
    +				timers = jQuery.timers,
    +				length = queue ? queue.length : 0;
    +
    +			// Enable finishing flag on private data
    +			data.finish = true;
    +
    +			// Empty the queue first
    +			jQuery.queue( this, type, [] );
    +
    +			if ( hooks && hooks.stop ) {
    +				hooks.stop.call( this, true );
    +			}
    +
    +			// Look for any active animations, and finish them
    +			for ( index = timers.length; index--; ) {
    +				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
    +					timers[ index ].anim.stop( true );
    +					timers.splice( index, 1 );
    +				}
    +			}
    +
    +			// Look for any animations in the old queue and finish them
    +			for ( index = 0; index < length; index++ ) {
    +				if ( queue[ index ] && queue[ index ].finish ) {
    +					queue[ index ].finish.call( this );
    +				}
    +			}
    +
    +			// Turn off finishing flag
    +			delete data.finish;
    +		} );
    +	}
    +} );
    +
    +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
    +	var cssFn = jQuery.fn[ name ];
    +	jQuery.fn[ name ] = function( speed, easing, callback ) {
    +		return speed == null || typeof speed === "boolean" ?
    +			cssFn.apply( this, arguments ) :
    +			this.animate( genFx( name, true ), speed, easing, callback );
    +	};
    +} );
    +
    +// Generate shortcuts for custom animations
    +jQuery.each( {
    +	slideDown: genFx( "show" ),
    +	slideUp: genFx( "hide" ),
    +	slideToggle: genFx( "toggle" ),
    +	fadeIn: { opacity: "show" },
    +	fadeOut: { opacity: "hide" },
    +	fadeToggle: { opacity: "toggle" }
    +}, function( name, props ) {
    +	jQuery.fn[ name ] = function( speed, easing, callback ) {
    +		return this.animate( props, speed, easing, callback );
    +	};
    +} );
    +
    +jQuery.timers = [];
    +jQuery.fx.tick = function() {
    +	var timer,
    +		i = 0,
    +		timers = jQuery.timers;
    +
    +	fxNow = Date.now();
    +
    +	for ( ; i < timers.length; i++ ) {
    +		timer = timers[ i ];
    +
    +		// Run the timer and safely remove it when done (allowing for external removal)
    +		if ( !timer() && timers[ i ] === timer ) {
    +			timers.splice( i--, 1 );
    +		}
    +	}
    +
    +	if ( !timers.length ) {
    +		jQuery.fx.stop();
    +	}
    +	fxNow = undefined;
    +};
    +
    +jQuery.fx.timer = function( timer ) {
    +	jQuery.timers.push( timer );
    +	jQuery.fx.start();
    +};
    +
    +jQuery.fx.interval = 13;
    +jQuery.fx.start = function() {
    +	if ( inProgress ) {
    +		return;
    +	}
    +
    +	inProgress = true;
    +	schedule();
    +};
    +
    +jQuery.fx.stop = function() {
    +	inProgress = null;
    +};
    +
    +jQuery.fx.speeds = {
    +	slow: 600,
    +	fast: 200,
    +
    +	// Default speed
    +	_default: 400
    +};
    +
    +
    +// Based off of the plugin by Clint Helfers, with permission.
    +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
    +jQuery.fn.delay = function( time, type ) {
    +	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
    +	type = type || "fx";
    +
    +	return this.queue( type, function( next, hooks ) {
    +		var timeout = window.setTimeout( next, time );
    +		hooks.stop = function() {
    +			window.clearTimeout( timeout );
    +		};
    +	} );
    +};
    +
    +
    +( function() {
    +	var input = document.createElement( "input" ),
    +		select = document.createElement( "select" ),
    +		opt = select.appendChild( document.createElement( "option" ) );
    +
    +	input.type = "checkbox";
    +
    +	// Support: Android <=4.3 only
    +	// Default value for a checkbox should be "on"
    +	support.checkOn = input.value !== "";
    +
    +	// Support: IE <=11 only
    +	// Must access selectedIndex to make default options select
    +	support.optSelected = opt.selected;
    +
    +	// Support: IE <=11 only
    +	// An input loses its value after becoming a radio
    +	input = document.createElement( "input" );
    +	input.value = "t";
    +	input.type = "radio";
    +	support.radioValue = input.value === "t";
    +} )();
    +
    +
    +var boolHook,
    +	attrHandle = jQuery.expr.attrHandle;
    +
    +jQuery.fn.extend( {
    +	attr: function( name, value ) {
    +		return access( this, jQuery.attr, name, value, arguments.length > 1 );
    +	},
    +
    +	removeAttr: function( name ) {
    +		return this.each( function() {
    +			jQuery.removeAttr( this, name );
    +		} );
    +	}
    +} );
    +
    +jQuery.extend( {
    +	attr: function( elem, name, value ) {
    +		var ret, hooks,
    +			nType = elem.nodeType;
    +
    +		// Don't get/set attributes on text, comment and attribute nodes
    +		if ( nType === 3 || nType === 8 || nType === 2 ) {
    +			return;
    +		}
    +
    +		// Fallback to prop when attributes are not supported
    +		if ( typeof elem.getAttribute === "undefined" ) {
    +			return jQuery.prop( elem, name, value );
    +		}
    +
    +		// Attribute hooks are determined by the lowercase version
    +		// Grab necessary hook if one is defined
    +		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
    +			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
    +				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
    +		}
    +
    +		if ( value !== undefined ) {
    +			if ( value === null ) {
    +				jQuery.removeAttr( elem, name );
    +				return;
    +			}
    +
    +			if ( hooks && "set" in hooks &&
    +				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
    +				return ret;
    +			}
    +
    +			elem.setAttribute( name, value + "" );
    +			return value;
    +		}
    +
    +		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
    +			return ret;
    +		}
    +
    +		ret = jQuery.find.attr( elem, name );
    +
    +		// Non-existent attributes return null, we normalize to undefined
    +		return ret == null ? undefined : ret;
    +	},
    +
    +	attrHooks: {
    +		type: {
    +			set: function( elem, value ) {
    +				if ( !support.radioValue && value === "radio" &&
    +					nodeName( elem, "input" ) ) {
    +					var val = elem.value;
    +					elem.setAttribute( "type", value );
    +					if ( val ) {
    +						elem.value = val;
    +					}
    +					return value;
    +				}
    +			}
    +		}
    +	},
    +
    +	removeAttr: function( elem, value ) {
    +		var name,
    +			i = 0,
    +
    +			// Attribute names can contain non-HTML whitespace characters
    +			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
    +			attrNames = value && value.match( rnothtmlwhite );
    +
    +		if ( attrNames && elem.nodeType === 1 ) {
    +			while ( ( name = attrNames[ i++ ] ) ) {
    +				elem.removeAttribute( name );
    +			}
    +		}
    +	}
    +} );
    +
    +// Hooks for boolean attributes
    +boolHook = {
    +	set: function( elem, value, name ) {
    +		if ( value === false ) {
    +
    +			// Remove boolean attributes when set to false
    +			jQuery.removeAttr( elem, name );
    +		} else {
    +			elem.setAttribute( name, name );
    +		}
    +		return name;
    +	}
    +};
    +
    +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
    +	var getter = attrHandle[ name ] || jQuery.find.attr;
    +
    +	attrHandle[ name ] = function( elem, name, isXML ) {
    +		var ret, handle,
    +			lowercaseName = name.toLowerCase();
    +
    +		if ( !isXML ) {
    +
    +			// Avoid an infinite loop by temporarily removing this function from the getter
    +			handle = attrHandle[ lowercaseName ];
    +			attrHandle[ lowercaseName ] = ret;
    +			ret = getter( elem, name, isXML ) != null ?
    +				lowercaseName :
    +				null;
    +			attrHandle[ lowercaseName ] = handle;
    +		}
    +		return ret;
    +	};
    +} );
    +
    +
    +
    +
    +var rfocusable = /^(?:input|select|textarea|button)$/i,
    +	rclickable = /^(?:a|area)$/i;
    +
    +jQuery.fn.extend( {
    +	prop: function( name, value ) {
    +		return access( this, jQuery.prop, name, value, arguments.length > 1 );
    +	},
    +
    +	removeProp: function( name ) {
    +		return this.each( function() {
    +			delete this[ jQuery.propFix[ name ] || name ];
    +		} );
    +	}
    +} );
    +
    +jQuery.extend( {
    +	prop: function( elem, name, value ) {
    +		var ret, hooks,
    +			nType = elem.nodeType;
    +
    +		// Don't get/set properties on text, comment and attribute nodes
    +		if ( nType === 3 || nType === 8 || nType === 2 ) {
    +			return;
    +		}
    +
    +		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
    +
    +			// Fix name and attach hooks
    +			name = jQuery.propFix[ name ] || name;
    +			hooks = jQuery.propHooks[ name ];
    +		}
    +
    +		if ( value !== undefined ) {
    +			if ( hooks && "set" in hooks &&
    +				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
    +				return ret;
    +			}
    +
    +			return ( elem[ name ] = value );
    +		}
    +
    +		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
    +			return ret;
    +		}
    +
    +		return elem[ name ];
    +	},
    +
    +	propHooks: {
    +		tabIndex: {
    +			get: function( elem ) {
    +
    +				// Support: IE <=9 - 11 only
    +				// elem.tabIndex doesn't always return the
    +				// correct value when it hasn't been explicitly set
    +				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
    +				// Use proper attribute retrieval(#12072)
    +				var tabindex = jQuery.find.attr( elem, "tabindex" );
    +
    +				if ( tabindex ) {
    +					return parseInt( tabindex, 10 );
    +				}
    +
    +				if (
    +					rfocusable.test( elem.nodeName ) ||
    +					rclickable.test( elem.nodeName ) &&
    +					elem.href
    +				) {
    +					return 0;
    +				}
    +
    +				return -1;
    +			}
    +		}
    +	},
    +
    +	propFix: {
    +		"for": "htmlFor",
    +		"class": "className"
    +	}
    +} );
    +
    +// Support: IE <=11 only
    +// Accessing the selectedIndex property
    +// forces the browser to respect setting selected
    +// on the option
    +// The getter ensures a default option is selected
    +// when in an optgroup
    +// eslint rule "no-unused-expressions" is disabled for this code
    +// since it considers such accessions noop
    +if ( !support.optSelected ) {
    +	jQuery.propHooks.selected = {
    +		get: function( elem ) {
    +
    +			/* eslint no-unused-expressions: "off" */
    +
    +			var parent = elem.parentNode;
    +			if ( parent && parent.parentNode ) {
    +				parent.parentNode.selectedIndex;
    +			}
    +			return null;
    +		},
    +		set: function( elem ) {
    +
    +			/* eslint no-unused-expressions: "off" */
    +
    +			var parent = elem.parentNode;
    +			if ( parent ) {
    +				parent.selectedIndex;
    +
    +				if ( parent.parentNode ) {
    +					parent.parentNode.selectedIndex;
    +				}
    +			}
    +		}
    +	};
    +}
    +
    +jQuery.each( [
    +	"tabIndex",
    +	"readOnly",
    +	"maxLength",
    +	"cellSpacing",
    +	"cellPadding",
    +	"rowSpan",
    +	"colSpan",
    +	"useMap",
    +	"frameBorder",
    +	"contentEditable"
    +], function() {
    +	jQuery.propFix[ this.toLowerCase() ] = this;
    +} );
    +
    +
    +
    +
    +	// Strip and collapse whitespace according to HTML spec
    +	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
    +	function stripAndCollapse( value ) {
    +		var tokens = value.match( rnothtmlwhite ) || [];
    +		return tokens.join( " " );
    +	}
    +
    +
    +function getClass( elem ) {
    +	return elem.getAttribute && elem.getAttribute( "class" ) || "";
    +}
    +
    +function classesToArray( value ) {
    +	if ( Array.isArray( value ) ) {
    +		return value;
    +	}
    +	if ( typeof value === "string" ) {
    +		return value.match( rnothtmlwhite ) || [];
    +	}
    +	return [];
    +}
    +
    +jQuery.fn.extend( {
    +	addClass: function( value ) {
    +		var classes, elem, cur, curValue, clazz, j, finalValue,
    +			i = 0;
    +
    +		if ( isFunction( value ) ) {
    +			return this.each( function( j ) {
    +				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
    +			} );
    +		}
    +
    +		classes = classesToArray( value );
    +
    +		if ( classes.length ) {
    +			while ( ( elem = this[ i++ ] ) ) {
    +				curValue = getClass( elem );
    +				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
    +
    +				if ( cur ) {
    +					j = 0;
    +					while ( ( clazz = classes[ j++ ] ) ) {
    +						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
    +							cur += clazz + " ";
    +						}
    +					}
    +
    +					// Only assign if different to avoid unneeded rendering.
    +					finalValue = stripAndCollapse( cur );
    +					if ( curValue !== finalValue ) {
    +						elem.setAttribute( "class", finalValue );
    +					}
    +				}
    +			}
    +		}
    +
    +		return this;
    +	},
    +
    +	removeClass: function( value ) {
    +		var classes, elem, cur, curValue, clazz, j, finalValue,
    +			i = 0;
    +
    +		if ( isFunction( value ) ) {
    +			return this.each( function( j ) {
    +				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
    +			} );
    +		}
    +
    +		if ( !arguments.length ) {
    +			return this.attr( "class", "" );
    +		}
    +
    +		classes = classesToArray( value );
    +
    +		if ( classes.length ) {
    +			while ( ( elem = this[ i++ ] ) ) {
    +				curValue = getClass( elem );
    +
    +				// This expression is here for better compressibility (see addClass)
    +				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
    +
    +				if ( cur ) {
    +					j = 0;
    +					while ( ( clazz = classes[ j++ ] ) ) {
    +
    +						// Remove *all* instances
    +						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
    +							cur = cur.replace( " " + clazz + " ", " " );
    +						}
    +					}
    +
    +					// Only assign if different to avoid unneeded rendering.
    +					finalValue = stripAndCollapse( cur );
    +					if ( curValue !== finalValue ) {
    +						elem.setAttribute( "class", finalValue );
    +					}
    +				}
    +			}
    +		}
    +
    +		return this;
    +	},
    +
    +	toggleClass: function( value, stateVal ) {
    +		var type = typeof value,
    +			isValidValue = type === "string" || Array.isArray( value );
    +
    +		if ( typeof stateVal === "boolean" && isValidValue ) {
    +			return stateVal ? this.addClass( value ) : this.removeClass( value );
    +		}
    +
    +		if ( isFunction( value ) ) {
    +			return this.each( function( i ) {
    +				jQuery( this ).toggleClass(
    +					value.call( this, i, getClass( this ), stateVal ),
    +					stateVal
    +				);
    +			} );
    +		}
    +
    +		return this.each( function() {
    +			var className, i, self, classNames;
    +
    +			if ( isValidValue ) {
    +
    +				// Toggle individual class names
    +				i = 0;
    +				self = jQuery( this );
    +				classNames = classesToArray( value );
    +
    +				while ( ( className = classNames[ i++ ] ) ) {
    +
    +					// Check each className given, space separated list
    +					if ( self.hasClass( className ) ) {
    +						self.removeClass( className );
    +					} else {
    +						self.addClass( className );
    +					}
    +				}
    +
    +			// Toggle whole class name
    +			} else if ( value === undefined || type === "boolean" ) {
    +				className = getClass( this );
    +				if ( className ) {
    +
    +					// Store className if set
    +					dataPriv.set( this, "__className__", className );
    +				}
    +
    +				// If the element has a class name or if we're passed `false`,
    +				// then remove the whole classname (if there was one, the above saved it).
    +				// Otherwise bring back whatever was previously saved (if anything),
    +				// falling back to the empty string if nothing was stored.
    +				if ( this.setAttribute ) {
    +					this.setAttribute( "class",
    +						className || value === false ?
    +						"" :
    +						dataPriv.get( this, "__className__" ) || ""
    +					);
    +				}
    +			}
    +		} );
    +	},
    +
    +	hasClass: function( selector ) {
    +		var className, elem,
    +			i = 0;
    +
    +		className = " " + selector + " ";
    +		while ( ( elem = this[ i++ ] ) ) {
    +			if ( elem.nodeType === 1 &&
    +				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
    +					return true;
    +			}
    +		}
    +
    +		return false;
    +	}
    +} );
    +
    +
    +
    +
    +var rreturn = /\r/g;
    +
    +jQuery.fn.extend( {
    +	val: function( value ) {
    +		var hooks, ret, valueIsFunction,
    +			elem = this[ 0 ];
    +
    +		if ( !arguments.length ) {
    +			if ( elem ) {
    +				hooks = jQuery.valHooks[ elem.type ] ||
    +					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
    +
    +				if ( hooks &&
    +					"get" in hooks &&
    +					( ret = hooks.get( elem, "value" ) ) !== undefined
    +				) {
    +					return ret;
    +				}
    +
    +				ret = elem.value;
    +
    +				// Handle most common string cases
    +				if ( typeof ret === "string" ) {
    +					return ret.replace( rreturn, "" );
    +				}
    +
    +				// Handle cases where value is null/undef or number
    +				return ret == null ? "" : ret;
    +			}
    +
    +			return;
    +		}
    +
    +		valueIsFunction = isFunction( value );
    +
    +		return this.each( function( i ) {
    +			var val;
    +
    +			if ( this.nodeType !== 1 ) {
    +				return;
    +			}
    +
    +			if ( valueIsFunction ) {
    +				val = value.call( this, i, jQuery( this ).val() );
    +			} else {
    +				val = value;
    +			}
    +
    +			// Treat null/undefined as ""; convert numbers to string
    +			if ( val == null ) {
    +				val = "";
    +
    +			} else if ( typeof val === "number" ) {
    +				val += "";
    +
    +			} else if ( Array.isArray( val ) ) {
    +				val = jQuery.map( val, function( value ) {
    +					return value == null ? "" : value + "";
    +				} );
    +			}
    +
    +			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
    +
    +			// If set returns undefined, fall back to normal setting
    +			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
    +				this.value = val;
    +			}
    +		} );
    +	}
    +} );
    +
    +jQuery.extend( {
    +	valHooks: {
    +		option: {
    +			get: function( elem ) {
    +
    +				var val = jQuery.find.attr( elem, "value" );
    +				return val != null ?
    +					val :
    +
    +					// Support: IE <=10 - 11 only
    +					// option.text throws exceptions (#14686, #14858)
    +					// Strip and collapse whitespace
    +					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
    +					stripAndCollapse( jQuery.text( elem ) );
    +			}
    +		},
    +		select: {
    +			get: function( elem ) {
    +				var value, option, i,
    +					options = elem.options,
    +					index = elem.selectedIndex,
    +					one = elem.type === "select-one",
    +					values = one ? null : [],
    +					max = one ? index + 1 : options.length;
    +
    +				if ( index < 0 ) {
    +					i = max;
    +
    +				} else {
    +					i = one ? index : 0;
    +				}
    +
    +				// Loop through all the selected options
    +				for ( ; i < max; i++ ) {
    +					option = options[ i ];
    +
    +					// Support: IE <=9 only
    +					// IE8-9 doesn't update selected after form reset (#2551)
    +					if ( ( option.selected || i === index ) &&
    +
    +							// Don't return options that are disabled or in a disabled optgroup
    +							!option.disabled &&
    +							( !option.parentNode.disabled ||
    +								!nodeName( option.parentNode, "optgroup" ) ) ) {
    +
    +						// Get the specific value for the option
    +						value = jQuery( option ).val();
    +
    +						// We don't need an array for one selects
    +						if ( one ) {
    +							return value;
    +						}
    +
    +						// Multi-Selects return an array
    +						values.push( value );
    +					}
    +				}
    +
    +				return values;
    +			},
    +
    +			set: function( elem, value ) {
    +				var optionSet, option,
    +					options = elem.options,
    +					values = jQuery.makeArray( value ),
    +					i = options.length;
    +
    +				while ( i-- ) {
    +					option = options[ i ];
    +
    +					/* eslint-disable no-cond-assign */
    +
    +					if ( option.selected =
    +						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
    +					) {
    +						optionSet = true;
    +					}
    +
    +					/* eslint-enable no-cond-assign */
    +				}
    +
    +				// Force browsers to behave consistently when non-matching value is set
    +				if ( !optionSet ) {
    +					elem.selectedIndex = -1;
    +				}
    +				return values;
    +			}
    +		}
    +	}
    +} );
    +
    +// Radios and checkboxes getter/setter
    +jQuery.each( [ "radio", "checkbox" ], function() {
    +	jQuery.valHooks[ this ] = {
    +		set: function( elem, value ) {
    +			if ( Array.isArray( value ) ) {
    +				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
    +			}
    +		}
    +	};
    +	if ( !support.checkOn ) {
    +		jQuery.valHooks[ this ].get = function( elem ) {
    +			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
    +		};
    +	}
    +} );
    +
    +
    +
    +
    +// Return jQuery for attributes-only inclusion
    +
    +
    +support.focusin = "onfocusin" in window;
    +
    +
    +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
    +	stopPropagationCallback = function( e ) {
    +		e.stopPropagation();
    +	};
    +
    +jQuery.extend( jQuery.event, {
    +
    +	trigger: function( event, data, elem, onlyHandlers ) {
    +
    +		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
    +			eventPath = [ elem || document ],
    +			type = hasOwn.call( event, "type" ) ? event.type : event,
    +			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
    +
    +		cur = lastElement = 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( "." ) > -1 ) {
    +
    +			// 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.rnamespace = 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 && !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() ) {
    +			lastElement = cur;
    +			event.type = i > 1 ?
    +				bubbleType :
    +				special.bindType || type;
    +
    +			// jQuery handler
    +			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
    +				dataPriv.get( cur, "handle" );
    +			if ( handle ) {
    +				handle.apply( cur, data );
    +			}
    +
    +			// Native handler
    +			handle = ontype && cur[ ontype ];
    +			if ( handle && handle.apply && 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 ) &&
    +				acceptData( elem ) ) {
    +
    +				// Call a native DOM method on the target with the same name as the event.
    +				// Don't do default actions on window, that's where global variables be (#6170)
    +				if ( ontype && isFunction( elem[ type ] ) && !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;
    +
    +					if ( event.isPropagationStopped() ) {
    +						lastElement.addEventListener( type, stopPropagationCallback );
    +					}
    +
    +					elem[ type ]();
    +
    +					if ( event.isPropagationStopped() ) {
    +						lastElement.removeEventListener( type, stopPropagationCallback );
    +					}
    +
    +					jQuery.event.triggered = undefined;
    +
    +					if ( tmp ) {
    +						elem[ ontype ] = tmp;
    +					}
    +				}
    +			}
    +		}
    +
    +		return event.result;
    +	},
    +
    +	// Piggyback on a donor event to simulate a different one
    +	// Used only for `focus(in | out)` events
    +	simulate: function( type, elem, event ) {
    +		var e = jQuery.extend(
    +			new jQuery.Event(),
    +			event,
    +			{
    +				type: type,
    +				isSimulated: true
    +			}
    +		);
    +
    +		jQuery.event.trigger( e, null, elem );
    +	}
    +
    +} );
    +
    +jQuery.fn.extend( {
    +
    +	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 );
    +		}
    +	}
    +} );
    +
    +
    +// Support: Firefox <=44
    +// Firefox doesn't have focus(in | out) events
    +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
    +//
    +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
    +// focus(in | out) events fire after focus & blur events,
    +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
    +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
    +if ( !support.focusin ) {
    +	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 ) );
    +		};
    +
    +		jQuery.event.special[ fix ] = {
    +			setup: function() {
    +				var doc = this.ownerDocument || this,
    +					attaches = dataPriv.access( doc, fix );
    +
    +				if ( !attaches ) {
    +					doc.addEventListener( orig, handler, true );
    +				}
    +				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
    +			},
    +			teardown: function() {
    +				var doc = this.ownerDocument || this,
    +					attaches = dataPriv.access( doc, fix ) - 1;
    +
    +				if ( !attaches ) {
    +					doc.removeEventListener( orig, handler, true );
    +					dataPriv.remove( doc, fix );
    +
    +				} else {
    +					dataPriv.access( doc, fix, attaches );
    +				}
    +			}
    +		};
    +	} );
    +}
    +var location = window.location;
    +
    +var nonce = Date.now();
    +
    +var rquery = ( /\?/ );
    +
    +
    +
    +// Cross-browser xml parsing
    +jQuery.parseXML = function( data ) {
    +	var xml;
    +	if ( !data || typeof data !== "string" ) {
    +		return null;
    +	}
    +
    +	// Support: IE 9 - 11 only
    +	// IE throws on parseFromString with invalid input.
    +	try {
    +		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
    +	} catch ( e ) {
    +		xml = undefined;
    +	}
    +
    +	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
    +		jQuery.error( "Invalid XML: " + data );
    +	}
    +	return xml;
    +};
    +
    +
    +var
    +	rbracket = /\[\]$/,
    +	rCRLF = /\r?\n/g,
    +	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
    +	rsubmittable = /^(?:input|select|textarea|keygen)/i;
    +
    +function buildParams( prefix, obj, traditional, add ) {
    +	var name;
    +
    +	if ( Array.isArray( obj ) ) {
    +
    +		// Serialize array item.
    +		jQuery.each( obj, function( i, v ) {
    +			if ( traditional || rbracket.test( prefix ) ) {
    +
    +				// Treat each array item as a scalar.
    +				add( prefix, v );
    +
    +			} else {
    +
    +				// Item is non-scalar (array or object), encode its numeric index.
    +				buildParams(
    +					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
    +					v,
    +					traditional,
    +					add
    +				);
    +			}
    +		} );
    +
    +	} else if ( !traditional && toType( obj ) === "object" ) {
    +
    +		// Serialize object item.
    +		for ( name in obj ) {
    +			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
    +		}
    +
    +	} else {
    +
    +		// Serialize scalar item.
    +		add( prefix, obj );
    +	}
    +}
    +
    +// Serialize an array of form elements or a set of
    +// key/values into a query string
    +jQuery.param = function( a, traditional ) {
    +	var prefix,
    +		s = [],
    +		add = function( key, valueOrFunction ) {
    +
    +			// If value is a function, invoke it and use its return value
    +			var value = isFunction( valueOrFunction ) ?
    +				valueOrFunction() :
    +				valueOrFunction;
    +
    +			s[ s.length ] = encodeURIComponent( key ) + "=" +
    +				encodeURIComponent( value == null ? "" : value );
    +		};
    +
    +	// If an array was passed in, assume that it is an array of form elements.
    +	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
    +
    +		// Serialize the form elements
    +		jQuery.each( a, function() {
    +			add( this.name, this.value );
    +		} );
    +
    +	} else {
    +
    +		// If traditional, encode the "old" way (the way 1.3.2 or older
    +		// did it), otherwise encode params recursively.
    +		for ( prefix in a ) {
    +			buildParams( prefix, a[ prefix ], traditional, add );
    +		}
    +	}
    +
    +	// Return the resulting serialization
    +	return s.join( "&" );
    +};
    +
    +jQuery.fn.extend( {
    +	serialize: function() {
    +		return jQuery.param( this.serializeArray() );
    +	},
    +	serializeArray: function() {
    +		return this.map( function() {
    +
    +			// Can add propHook for "elements" to filter or add form elements
    +			var elements = jQuery.prop( this, "elements" );
    +			return elements ? jQuery.makeArray( elements ) : this;
    +		} )
    +		.filter( function() {
    +			var type = this.type;
    +
    +			// Use .is( ":disabled" ) so that fieldset[disabled] works
    +			return this.name && !jQuery( this ).is( ":disabled" ) &&
    +				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
    +				( this.checked || !rcheckableType.test( type ) );
    +		} )
    +		.map( function( i, elem ) {
    +			var val = jQuery( this ).val();
    +
    +			if ( val == null ) {
    +				return null;
    +			}
    +
    +			if ( Array.isArray( val ) ) {
    +				return jQuery.map( val, function( val ) {
    +					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
    +				} );
    +			}
    +
    +			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
    +		} ).get();
    +	}
    +} );
    +
    +
    +var
    +	r20 = /%20/g,
    +	rhash = /#.*$/,
    +	rantiCache = /([?&])_=[^&]*/,
    +	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
    +
    +	// #7653, #8125, #8152: local protocol detection
    +	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
    +	rnoContent = /^(?:GET|HEAD)$/,
    +	rprotocol = /^\/\//,
    +
    +	/* Prefilters
    +	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
    +	 * 2) These are called:
    +	 *    - BEFORE asking for a transport
    +	 *    - AFTER param serialization (s.data is a string if s.processData is true)
    +	 * 3) key is the dataType
    +	 * 4) the catchall symbol "*" can be used
    +	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
    +	 */
    +	prefilters = {},
    +
    +	/* Transports bindings
    +	 * 1) key is the dataType
    +	 * 2) the catchall symbol "*" can be used
    +	 * 3) selection will start with transport dataType and THEN go to "*" if needed
    +	 */
    +	transports = {},
    +
    +	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
    +	allTypes = "*/".concat( "*" ),
    +
    +	// Anchor tag for parsing the document origin
    +	originAnchor = document.createElement( "a" );
    +	originAnchor.href = location.href;
    +
    +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
    +function addToPrefiltersOrTransports( structure ) {
    +
    +	// dataTypeExpression is optional and defaults to "*"
    +	return function( dataTypeExpression, func ) {
    +
    +		if ( typeof dataTypeExpression !== "string" ) {
    +			func = dataTypeExpression;
    +			dataTypeExpression = "*";
    +		}
    +
    +		var dataType,
    +			i = 0,
    +			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
    +
    +		if ( isFunction( func ) ) {
    +
    +			// For each dataType in the dataTypeExpression
    +			while ( ( dataType = dataTypes[ i++ ] ) ) {
    +
    +				// Prepend if requested
    +				if ( dataType[ 0 ] === "+" ) {
    +					dataType = dataType.slice( 1 ) || "*";
    +					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
    +
    +				// Otherwise append
    +				} else {
    +					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
    +				}
    +			}
    +		}
    +	};
    +}
    +
    +// Base inspection function for prefilters and transports
    +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
    +
    +	var inspected = {},
    +		seekingTransport = ( structure === transports );
    +
    +	function inspect( dataType ) {
    +		var selected;
    +		inspected[ dataType ] = true;
    +		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
    +			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
    +			if ( typeof dataTypeOrTransport === "string" &&
    +				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
    +
    +				options.dataTypes.unshift( dataTypeOrTransport );
    +				inspect( dataTypeOrTransport );
    +				return false;
    +			} else if ( seekingTransport ) {
    +				return !( selected = dataTypeOrTransport );
    +			}
    +		} );
    +		return selected;
    +	}
    +
    +	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
    +}
    +
    +// A special extend for ajax options
    +// that takes "flat" options (not to be deep extended)
    +// Fixes #9887
    +function ajaxExtend( target, src ) {
    +	var key, deep,
    +		flatOptions = jQuery.ajaxSettings.flatOptions || {};
    +
    +	for ( key in src ) {
    +		if ( src[ key ] !== undefined ) {
    +			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
    +		}
    +	}
    +	if ( deep ) {
    +		jQuery.extend( true, target, deep );
    +	}
    +
    +	return target;
    +}
    +
    +/* Handles responses to an ajax request:
    + * - finds the right dataType (mediates between content-type and expected dataType)
    + * - returns the corresponding response
    + */
    +function ajaxHandleResponses( s, jqXHR, responses ) {
    +
    +	var ct, type, finalDataType, firstDataType,
    +		contents = s.contents,
    +		dataTypes = s.dataTypes;
    +
    +	// Remove auto dataType and get content-type in the process
    +	while ( dataTypes[ 0 ] === "*" ) {
    +		dataTypes.shift();
    +		if ( ct === undefined ) {
    +			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
    +		}
    +	}
    +
    +	// Check if we're dealing with a known content-type
    +	if ( ct ) {
    +		for ( type in contents ) {
    +			if ( contents[ type ] && contents[ type ].test( ct ) ) {
    +				dataTypes.unshift( type );
    +				break;
    +			}
    +		}
    +	}
    +
    +	// Check to see if we have a response for the expected dataType
    +	if ( dataTypes[ 0 ] in responses ) {
    +		finalDataType = dataTypes[ 0 ];
    +	} else {
    +
    +		// Try convertible dataTypes
    +		for ( type in responses ) {
    +			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
    +				finalDataType = type;
    +				break;
    +			}
    +			if ( !firstDataType ) {
    +				firstDataType = type;
    +			}
    +		}
    +
    +		// Or just use first one
    +		finalDataType = finalDataType || firstDataType;
    +	}
    +
    +	// If we found a dataType
    +	// We add the dataType to the list if needed
    +	// and return the corresponding response
    +	if ( finalDataType ) {
    +		if ( finalDataType !== dataTypes[ 0 ] ) {
    +			dataTypes.unshift( finalDataType );
    +		}
    +		return responses[ finalDataType ];
    +	}
    +}
    +
    +/* Chain conversions given the request and the original response
    + * Also sets the responseXXX fields on the jqXHR instance
    + */
    +function ajaxConvert( s, response, jqXHR, isSuccess ) {
    +	var conv2, current, conv, tmp, prev,
    +		converters = {},
    +
    +		// Work with a copy of dataTypes in case we need to modify it for conversion
    +		dataTypes = s.dataTypes.slice();
    +
    +	// Create converters map with lowercased keys
    +	if ( dataTypes[ 1 ] ) {
    +		for ( conv in s.converters ) {
    +			converters[ conv.toLowerCase() ] = s.converters[ conv ];
    +		}
    +	}
    +
    +	current = dataTypes.shift();
    +
    +	// Convert to each sequential dataType
    +	while ( current ) {
    +
    +		if ( s.responseFields[ current ] ) {
    +			jqXHR[ s.responseFields[ current ] ] = response;
    +		}
    +
    +		// Apply the dataFilter if provided
    +		if ( !prev && isSuccess && s.dataFilter ) {
    +			response = s.dataFilter( response, s.dataType );
    +		}
    +
    +		prev = current;
    +		current = dataTypes.shift();
    +
    +		if ( current ) {
    +
    +			// There's only work to do if current dataType is non-auto
    +			if ( current === "*" ) {
    +
    +				current = prev;
    +
    +			// Convert response if prev dataType is non-auto and differs from current
    +			} else if ( prev !== "*" && prev !== current ) {
    +
    +				// Seek a direct converter
    +				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
    +
    +				// If none found, seek a pair
    +				if ( !conv ) {
    +					for ( conv2 in converters ) {
    +
    +						// If conv2 outputs current
    +						tmp = conv2.split( " " );
    +						if ( tmp[ 1 ] === current ) {
    +
    +							// If prev can be converted to accepted input
    +							conv = converters[ prev + " " + tmp[ 0 ] ] ||
    +								converters[ "* " + tmp[ 0 ] ];
    +							if ( conv ) {
    +
    +								// Condense equivalence converters
    +								if ( conv === true ) {
    +									conv = converters[ conv2 ];
    +
    +								// Otherwise, insert the intermediate dataType
    +								} else if ( converters[ conv2 ] !== true ) {
    +									current = tmp[ 0 ];
    +									dataTypes.unshift( tmp[ 1 ] );
    +								}
    +								break;
    +							}
    +						}
    +					}
    +				}
    +
    +				// Apply converter (if not an equivalence)
    +				if ( conv !== true ) {
    +
    +					// Unless errors are allowed to bubble, catch and return them
    +					if ( conv && s.throws ) {
    +						response = conv( response );
    +					} else {
    +						try {
    +							response = conv( response );
    +						} catch ( e ) {
    +							return {
    +								state: "parsererror",
    +								error: conv ? e : "No conversion from " + prev + " to " + current
    +							};
    +						}
    +					}
    +				}
    +			}
    +		}
    +	}
    +
    +	return { state: "success", data: response };
    +}
    +
    +jQuery.extend( {
    +
    +	// Counter for holding the number of active queries
    +	active: 0,
    +
    +	// Last-Modified header cache for next request
    +	lastModified: {},
    +	etag: {},
    +
    +	ajaxSettings: {
    +		url: location.href,
    +		type: "GET",
    +		isLocal: rlocalProtocol.test( location.protocol ),
    +		global: true,
    +		processData: true,
    +		async: true,
    +		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
    +
    +		/*
    +		timeout: 0,
    +		data: null,
    +		dataType: null,
    +		username: null,
    +		password: null,
    +		cache: null,
    +		throws: false,
    +		traditional: false,
    +		headers: {},
    +		*/
    +
    +		accepts: {
    +			"*": allTypes,
    +			text: "text/plain",
    +			html: "text/html",
    +			xml: "application/xml, text/xml",
    +			json: "application/json, text/javascript"
    +		},
    +
    +		contents: {
    +			xml: /\bxml\b/,
    +			html: /\bhtml/,
    +			json: /\bjson\b/
    +		},
    +
    +		responseFields: {
    +			xml: "responseXML",
    +			text: "responseText",
    +			json: "responseJSON"
    +		},
    +
    +		// Data converters
    +		// Keys separate source (or catchall "*") and destination types with a single space
    +		converters: {
    +
    +			// Convert anything to text
    +			"* text": String,
    +
    +			// Text to html (true = no transformation)
    +			"text html": true,
    +
    +			// Evaluate text as a json expression
    +			"text json": JSON.parse,
    +
    +			// Parse text as xml
    +			"text xml": jQuery.parseXML
    +		},
    +
    +		// For options that shouldn't be deep extended:
    +		// you can add your own custom options here if
    +		// and when you create one that shouldn't be
    +		// deep extended (see ajaxExtend)
    +		flatOptions: {
    +			url: true,
    +			context: true
    +		}
    +	},
    +
    +	// Creates a full fledged settings object into target
    +	// with both ajaxSettings and settings fields.
    +	// If target is omitted, writes into ajaxSettings.
    +	ajaxSetup: function( target, settings ) {
    +		return settings ?
    +
    +			// Building a settings object
    +			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
    +
    +			// Extending ajaxSettings
    +			ajaxExtend( jQuery.ajaxSettings, target );
    +	},
    +
    +	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
    +	ajaxTransport: addToPrefiltersOrTransports( transports ),
    +
    +	// Main method
    +	ajax: function( url, options ) {
    +
    +		// If url is an object, simulate pre-1.5 signature
    +		if ( typeof url === "object" ) {
    +			options = url;
    +			url = undefined;
    +		}
    +
    +		// Force options to be an object
    +		options = options || {};
    +
    +		var transport,
    +
    +			// URL without anti-cache param
    +			cacheURL,
    +
    +			// Response headers
    +			responseHeadersString,
    +			responseHeaders,
    +
    +			// timeout handle
    +			timeoutTimer,
    +
    +			// Url cleanup var
    +			urlAnchor,
    +
    +			// Request state (becomes false upon send and true upon completion)
    +			completed,
    +
    +			// To know if global events are to be dispatched
    +			fireGlobals,
    +
    +			// Loop variable
    +			i,
    +
    +			// uncached part of the url
    +			uncached,
    +
    +			// Create the final options object
    +			s = jQuery.ajaxSetup( {}, options ),
    +
    +			// Callbacks context
    +			callbackContext = s.context || s,
    +
    +			// Context for global events is callbackContext if it is a DOM node or jQuery collection
    +			globalEventContext = s.context &&
    +				( callbackContext.nodeType || callbackContext.jquery ) ?
    +					jQuery( callbackContext ) :
    +					jQuery.event,
    +
    +			// Deferreds
    +			deferred = jQuery.Deferred(),
    +			completeDeferred = jQuery.Callbacks( "once memory" ),
    +
    +			// Status-dependent callbacks
    +			statusCode = s.statusCode || {},
    +
    +			// Headers (they are sent all at once)
    +			requestHeaders = {},
    +			requestHeadersNames = {},
    +
    +			// Default abort message
    +			strAbort = "canceled",
    +
    +			// Fake xhr
    +			jqXHR = {
    +				readyState: 0,
    +
    +				// Builds headers hashtable if needed
    +				getResponseHeader: function( key ) {
    +					var match;
    +					if ( completed ) {
    +						if ( !responseHeaders ) {
    +							responseHeaders = {};
    +							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
    +								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
    +							}
    +						}
    +						match = responseHeaders[ key.toLowerCase() ];
    +					}
    +					return match == null ? null : match;
    +				},
    +
    +				// Raw string
    +				getAllResponseHeaders: function() {
    +					return completed ? responseHeadersString : null;
    +				},
    +
    +				// Caches the header
    +				setRequestHeader: function( name, value ) {
    +					if ( completed == null ) {
    +						name = requestHeadersNames[ name.toLowerCase() ] =
    +							requestHeadersNames[ name.toLowerCase() ] || name;
    +						requestHeaders[ name ] = value;
    +					}
    +					return this;
    +				},
    +
    +				// Overrides response content-type header
    +				overrideMimeType: function( type ) {
    +					if ( completed == null ) {
    +						s.mimeType = type;
    +					}
    +					return this;
    +				},
    +
    +				// Status-dependent callbacks
    +				statusCode: function( map ) {
    +					var code;
    +					if ( map ) {
    +						if ( completed ) {
    +
    +							// Execute the appropriate callbacks
    +							jqXHR.always( map[ jqXHR.status ] );
    +						} else {
    +
    +							// Lazy-add the new callbacks in a way that preserves old ones
    +							for ( code in map ) {
    +								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
    +							}
    +						}
    +					}
    +					return this;
    +				},
    +
    +				// Cancel the request
    +				abort: function( statusText ) {
    +					var finalText = statusText || strAbort;
    +					if ( transport ) {
    +						transport.abort( finalText );
    +					}
    +					done( 0, finalText );
    +					return this;
    +				}
    +			};
    +
    +		// Attach deferreds
    +		deferred.promise( jqXHR );
    +
    +		// Add protocol if not provided (prefilters might expect it)
    +		// Handle falsy url in the settings object (#10093: consistency with old signature)
    +		// We also use the url parameter if available
    +		s.url = ( ( url || s.url || location.href ) + "" )
    +			.replace( rprotocol, location.protocol + "//" );
    +
    +		// Alias method option to type as per ticket #12004
    +		s.type = options.method || options.type || s.method || s.type;
    +
    +		// Extract dataTypes list
    +		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
    +
    +		// A cross-domain request is in order when the origin doesn't match the current origin.
    +		if ( s.crossDomain == null ) {
    +			urlAnchor = document.createElement( "a" );
    +
    +			// Support: IE <=8 - 11, Edge 12 - 15
    +			// IE throws exception on accessing the href property if url is malformed,
    +			// e.g. http://example.com:80x/
    +			try {
    +				urlAnchor.href = s.url;
    +
    +				// Support: IE <=8 - 11 only
    +				// Anchor's host property isn't correctly set when s.url is relative
    +				urlAnchor.href = urlAnchor.href;
    +				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
    +					urlAnchor.protocol + "//" + urlAnchor.host;
    +			} catch ( e ) {
    +
    +				// If there is an error parsing the URL, assume it is crossDomain,
    +				// it can be rejected by the transport if it is invalid
    +				s.crossDomain = true;
    +			}
    +		}
    +
    +		// Convert data if not already a string
    +		if ( s.data && s.processData && typeof s.data !== "string" ) {
    +			s.data = jQuery.param( s.data, s.traditional );
    +		}
    +
    +		// Apply prefilters
    +		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
    +
    +		// If request was aborted inside a prefilter, stop there
    +		if ( completed ) {
    +			return jqXHR;
    +		}
    +
    +		// We can fire global events as of now if asked to
    +		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
    +		fireGlobals = jQuery.event && s.global;
    +
    +		// Watch for a new set of requests
    +		if ( fireGlobals && jQuery.active++ === 0 ) {
    +			jQuery.event.trigger( "ajaxStart" );
    +		}
    +
    +		// Uppercase the type
    +		s.type = s.type.toUpperCase();
    +
    +		// Determine if request has content
    +		s.hasContent = !rnoContent.test( s.type );
    +
    +		// Save the URL in case we're toying with the If-Modified-Since
    +		// and/or If-None-Match header later on
    +		// Remove hash to simplify url manipulation
    +		cacheURL = s.url.replace( rhash, "" );
    +
    +		// More options handling for requests with no content
    +		if ( !s.hasContent ) {
    +
    +			// Remember the hash so we can put it back
    +			uncached = s.url.slice( cacheURL.length );
    +
    +			// If data is available and should be processed, append data to url
    +			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
    +				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
    +
    +				// #9682: remove data so that it's not used in an eventual retry
    +				delete s.data;
    +			}
    +
    +			// Add or update anti-cache param if needed
    +			if ( s.cache === false ) {
    +				cacheURL = cacheURL.replace( rantiCache, "$1" );
    +				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
    +			}
    +
    +			// Put hash and anti-cache on the URL that will be requested (gh-1732)
    +			s.url = cacheURL + uncached;
    +
    +		// Change '%20' to '+' if this is encoded form body content (gh-2658)
    +		} else if ( s.data && s.processData &&
    +			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
    +			s.data = s.data.replace( r20, "+" );
    +		}
    +
    +		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
    +		if ( s.ifModified ) {
    +			if ( jQuery.lastModified[ cacheURL ] ) {
    +				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
    +			}
    +			if ( jQuery.etag[ cacheURL ] ) {
    +				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
    +			}
    +		}
    +
    +		// Set the correct header, if data is being sent
    +		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
    +			jqXHR.setRequestHeader( "Content-Type", s.contentType );
    +		}
    +
    +		// Set the Accepts header for the server, depending on the dataType
    +		jqXHR.setRequestHeader(
    +			"Accept",
    +			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
    +				s.accepts[ s.dataTypes[ 0 ] ] +
    +					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
    +				s.accepts[ "*" ]
    +		);
    +
    +		// Check for headers option
    +		for ( i in s.headers ) {
    +			jqXHR.setRequestHeader( i, s.headers[ i ] );
    +		}
    +
    +		// Allow custom headers/mimetypes and early abort
    +		if ( s.beforeSend &&
    +			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
    +
    +			// Abort if not done already and return
    +			return jqXHR.abort();
    +		}
    +
    +		// Aborting is no longer a cancellation
    +		strAbort = "abort";
    +
    +		// Install callbacks on deferreds
    +		completeDeferred.add( s.complete );
    +		jqXHR.done( s.success );
    +		jqXHR.fail( s.error );
    +
    +		// Get transport
    +		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
    +
    +		// If no transport, we auto-abort
    +		if ( !transport ) {
    +			done( -1, "No Transport" );
    +		} else {
    +			jqXHR.readyState = 1;
    +
    +			// Send global event
    +			if ( fireGlobals ) {
    +				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
    +			}
    +
    +			// If request was aborted inside ajaxSend, stop there
    +			if ( completed ) {
    +				return jqXHR;
    +			}
    +
    +			// Timeout
    +			if ( s.async && s.timeout > 0 ) {
    +				timeoutTimer = window.setTimeout( function() {
    +					jqXHR.abort( "timeout" );
    +				}, s.timeout );
    +			}
    +
    +			try {
    +				completed = false;
    +				transport.send( requestHeaders, done );
    +			} catch ( e ) {
    +
    +				// Rethrow post-completion exceptions
    +				if ( completed ) {
    +					throw e;
    +				}
    +
    +				// Propagate others as results
    +				done( -1, e );
    +			}
    +		}
    +
    +		// Callback for when everything is done
    +		function done( status, nativeStatusText, responses, headers ) {
    +			var isSuccess, success, error, response, modified,
    +				statusText = nativeStatusText;
    +
    +			// Ignore repeat invocations
    +			if ( completed ) {
    +				return;
    +			}
    +
    +			completed = true;
    +
    +			// Clear timeout if it exists
    +			if ( timeoutTimer ) {
    +				window.clearTimeout( timeoutTimer );
    +			}
    +
    +			// Dereference transport for early garbage collection
    +			// (no matter how long the jqXHR object will be used)
    +			transport = undefined;
    +
    +			// Cache response headers
    +			responseHeadersString = headers || "";
    +
    +			// Set readyState
    +			jqXHR.readyState = status > 0 ? 4 : 0;
    +
    +			// Determine if successful
    +			isSuccess = status >= 200 && status < 300 || status === 304;
    +
    +			// Get response data
    +			if ( responses ) {
    +				response = ajaxHandleResponses( s, jqXHR, responses );
    +			}
    +
    +			// Convert no matter what (that way responseXXX fields are always set)
    +			response = ajaxConvert( s, response, jqXHR, isSuccess );
    +
    +			// If successful, handle type chaining
    +			if ( isSuccess ) {
    +
    +				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
    +				if ( s.ifModified ) {
    +					modified = jqXHR.getResponseHeader( "Last-Modified" );
    +					if ( modified ) {
    +						jQuery.lastModified[ cacheURL ] = modified;
    +					}
    +					modified = jqXHR.getResponseHeader( "etag" );
    +					if ( modified ) {
    +						jQuery.etag[ cacheURL ] = modified;
    +					}
    +				}
    +
    +				// if no content
    +				if ( status === 204 || s.type === "HEAD" ) {
    +					statusText = "nocontent";
    +
    +				// if not modified
    +				} else if ( status === 304 ) {
    +					statusText = "notmodified";
    +
    +				// If we have data, let's convert it
    +				} else {
    +					statusText = response.state;
    +					success = response.data;
    +					error = response.error;
    +					isSuccess = !error;
    +				}
    +			} else {
    +
    +				// Extract error from statusText and normalize for non-aborts
    +				error = statusText;
    +				if ( status || !statusText ) {
    +					statusText = "error";
    +					if ( status < 0 ) {
    +						status = 0;
    +					}
    +				}
    +			}
    +
    +			// Set data for the fake xhr object
    +			jqXHR.status = status;
    +			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
    +
    +			// Success/Error
    +			if ( isSuccess ) {
    +				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
    +			} else {
    +				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
    +			}
    +
    +			// Status-dependent callbacks
    +			jqXHR.statusCode( statusCode );
    +			statusCode = undefined;
    +
    +			if ( fireGlobals ) {
    +				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
    +					[ jqXHR, s, isSuccess ? success : error ] );
    +			}
    +
    +			// Complete
    +			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
    +
    +			if ( fireGlobals ) {
    +				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
    +
    +				// Handle the global AJAX counter
    +				if ( !( --jQuery.active ) ) {
    +					jQuery.event.trigger( "ajaxStop" );
    +				}
    +			}
    +		}
    +
    +		return jqXHR;
    +	},
    +
    +	getJSON: function( url, data, callback ) {
    +		return jQuery.get( url, data, callback, "json" );
    +	},
    +
    +	getScript: function( url, callback ) {
    +		return jQuery.get( url, undefined, callback, "script" );
    +	}
    +} );
    +
    +jQuery.each( [ "get", "post" ], function( i, method ) {
    +	jQuery[ method ] = function( url, data, callback, type ) {
    +
    +		// Shift arguments if data argument was omitted
    +		if ( isFunction( data ) ) {
    +			type = type || callback;
    +			callback = data;
    +			data = undefined;
    +		}
    +
    +		// The url can be an options object (which then must have .url)
    +		return jQuery.ajax( jQuery.extend( {
    +			url: url,
    +			type: method,
    +			dataType: type,
    +			data: data,
    +			success: callback
    +		}, jQuery.isPlainObject( url ) && url ) );
    +	};
    +} );
    +
    +
    +jQuery._evalUrl = function( url ) {
    +	return jQuery.ajax( {
    +		url: url,
    +
    +		// Make this explicit, since user can override this through ajaxSetup (#11264)
    +		type: "GET",
    +		dataType: "script",
    +		cache: true,
    +		async: false,
    +		global: false,
    +		"throws": true
    +	} );
    +};
    +
    +
    +jQuery.fn.extend( {
    +	wrapAll: function( html ) {
    +		var wrap;
    +
    +		if ( this[ 0 ] ) {
    +			if ( isFunction( html ) ) {
    +				html = html.call( this[ 0 ] );
    +			}
    +
    +			// The elements to wrap the target around
    +			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
    +
    +			if ( this[ 0 ].parentNode ) {
    +				wrap.insertBefore( this[ 0 ] );
    +			}
    +
    +			wrap.map( function() {
    +				var elem = this;
    +
    +				while ( elem.firstElementChild ) {
    +					elem = elem.firstElementChild;
    +				}
    +
    +				return elem;
    +			} ).append( this );
    +		}
    +
    +		return this;
    +	},
    +
    +	wrapInner: function( html ) {
    +		if ( isFunction( html ) ) {
    +			return this.each( function( i ) {
    +				jQuery( this ).wrapInner( html.call( this, i ) );
    +			} );
    +		}
    +
    +		return this.each( function() {
    +			var self = jQuery( this ),
    +				contents = self.contents();
    +
    +			if ( contents.length ) {
    +				contents.wrapAll( html );
    +
    +			} else {
    +				self.append( html );
    +			}
    +		} );
    +	},
    +
    +	wrap: function( html ) {
    +		var htmlIsFunction = isFunction( html );
    +
    +		return this.each( function( i ) {
    +			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
    +		} );
    +	},
    +
    +	unwrap: function( selector ) {
    +		this.parent( selector ).not( "body" ).each( function() {
    +			jQuery( this ).replaceWith( this.childNodes );
    +		} );
    +		return this;
    +	}
    +} );
    +
    +
    +jQuery.expr.pseudos.hidden = function( elem ) {
    +	return !jQuery.expr.pseudos.visible( elem );
    +};
    +jQuery.expr.pseudos.visible = function( elem ) {
    +	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
    +};
    +
    +
    +
    +
    +jQuery.ajaxSettings.xhr = function() {
    +	try {
    +		return new window.XMLHttpRequest();
    +	} catch ( e ) {}
    +};
    +
    +var xhrSuccessStatus = {
    +
    +		// File protocol always yields status code 0, assume 200
    +		0: 200,
    +
    +		// Support: IE <=9 only
    +		// #1450: sometimes IE returns 1223 when it should be 204
    +		1223: 204
    +	},
    +	xhrSupported = jQuery.ajaxSettings.xhr();
    +
    +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
    +support.ajax = xhrSupported = !!xhrSupported;
    +
    +jQuery.ajaxTransport( function( options ) {
    +	var callback, errorCallback;
    +
    +	// Cross domain only allowed if supported through XMLHttpRequest
    +	if ( support.cors || xhrSupported && !options.crossDomain ) {
    +		return {
    +			send: function( headers, complete ) {
    +				var i,
    +					xhr = options.xhr();
    +
    +				xhr.open(
    +					options.type,
    +					options.url,
    +					options.async,
    +					options.username,
    +					options.password
    +				);
    +
    +				// Apply custom fields if provided
    +				if ( options.xhrFields ) {
    +					for ( i in options.xhrFields ) {
    +						xhr[ i ] = options.xhrFields[ i ];
    +					}
    +				}
    +
    +				// Override mime type if needed
    +				if ( options.mimeType && xhr.overrideMimeType ) {
    +					xhr.overrideMimeType( options.mimeType );
    +				}
    +
    +				// X-Requested-With header
    +				// For cross-domain requests, seeing as conditions for a preflight are
    +				// akin to a jigsaw puzzle, we simply never set it to be sure.
    +				// (it can always be set on a per-request basis or even using ajaxSetup)
    +				// For same-domain requests, won't change header if already provided.
    +				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
    +					headers[ "X-Requested-With" ] = "XMLHttpRequest";
    +				}
    +
    +				// Set headers
    +				for ( i in headers ) {
    +					xhr.setRequestHeader( i, headers[ i ] );
    +				}
    +
    +				// Callback
    +				callback = function( type ) {
    +					return function() {
    +						if ( callback ) {
    +							callback = errorCallback = xhr.onload =
    +								xhr.onerror = xhr.onabort = xhr.ontimeout =
    +									xhr.onreadystatechange = null;
    +
    +							if ( type === "abort" ) {
    +								xhr.abort();
    +							} else if ( type === "error" ) {
    +
    +								// Support: IE <=9 only
    +								// On a manual native abort, IE9 throws
    +								// errors on any property access that is not readyState
    +								if ( typeof xhr.status !== "number" ) {
    +									complete( 0, "error" );
    +								} else {
    +									complete(
    +
    +										// File: protocol always yields status 0; see #8605, #14207
    +										xhr.status,
    +										xhr.statusText
    +									);
    +								}
    +							} else {
    +								complete(
    +									xhrSuccessStatus[ xhr.status ] || xhr.status,
    +									xhr.statusText,
    +
    +									// Support: IE <=9 only
    +									// IE9 has no XHR2 but throws on binary (trac-11426)
    +									// For XHR2 non-text, let the caller handle it (gh-2498)
    +									( xhr.responseType || "text" ) !== "text"  ||
    +									typeof xhr.responseText !== "string" ?
    +										{ binary: xhr.response } :
    +										{ text: xhr.responseText },
    +									xhr.getAllResponseHeaders()
    +								);
    +							}
    +						}
    +					};
    +				};
    +
    +				// Listen to events
    +				xhr.onload = callback();
    +				errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
    +
    +				// Support: IE 9 only
    +				// Use onreadystatechange to replace onabort
    +				// to handle uncaught aborts
    +				if ( xhr.onabort !== undefined ) {
    +					xhr.onabort = errorCallback;
    +				} else {
    +					xhr.onreadystatechange = function() {
    +
    +						// Check readyState before timeout as it changes
    +						if ( xhr.readyState === 4 ) {
    +
    +							// Allow onerror to be called first,
    +							// but that will not handle a native abort
    +							// Also, save errorCallback to a variable
    +							// as xhr.onerror cannot be accessed
    +							window.setTimeout( function() {
    +								if ( callback ) {
    +									errorCallback();
    +								}
    +							} );
    +						}
    +					};
    +				}
    +
    +				// Create the abort callback
    +				callback = callback( "abort" );
    +
    +				try {
    +
    +					// Do send the request (this may raise an exception)
    +					xhr.send( options.hasContent && options.data || null );
    +				} catch ( e ) {
    +
    +					// #14683: Only rethrow if this hasn't been notified as an error yet
    +					if ( callback ) {
    +						throw e;
    +					}
    +				}
    +			},
    +
    +			abort: function() {
    +				if ( callback ) {
    +					callback();
    +				}
    +			}
    +		};
    +	}
    +} );
    +
    +
    +
    +
    +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
    +jQuery.ajaxPrefilter( function( s ) {
    +	if ( s.crossDomain ) {
    +		s.contents.script = false;
    +	}
    +} );
    +
    +// Install script dataType
    +jQuery.ajaxSetup( {
    +	accepts: {
    +		script: "text/javascript, application/javascript, " +
    +			"application/ecmascript, application/x-ecmascript"
    +	},
    +	contents: {
    +		script: /\b(?:java|ecma)script\b/
    +	},
    +	converters: {
    +		"text script": function( text ) {
    +			jQuery.globalEval( text );
    +			return text;
    +		}
    +	}
    +} );
    +
    +// Handle cache's special case and crossDomain
    +jQuery.ajaxPrefilter( "script", function( s ) {
    +	if ( s.cache === undefined ) {
    +		s.cache = false;
    +	}
    +	if ( s.crossDomain ) {
    +		s.type = "GET";
    +	}
    +} );
    +
    +// Bind script tag hack transport
    +jQuery.ajaxTransport( "script", function( s ) {
    +
    +	// This transport only deals with cross domain requests
    +	if ( s.crossDomain ) {
    +		var script, callback;
    +		return {
    +			send: function( _, complete ) {
    +				script = jQuery( "<script>" ).prop( {
    +					charset: s.scriptCharset,
    +					src: s.url
    +				} ).on(
    +					"load error",
    +					callback = function( evt ) {
    +						script.remove();
    +						callback = null;
    +						if ( evt ) {
    +							complete( evt.type === "error" ? 404 : 200, evt.type );
    +						}
    +					}
    +				);
    +
    +				// Use native DOM manipulation to avoid our domManip AJAX trickery
    +				document.head.appendChild( script[ 0 ] );
    +			},
    +			abort: function() {
    +				if ( callback ) {
    +					callback();
    +				}
    +			}
    +		};
    +	}
    +} );
    +
    +
    +
    +
    +var oldCallbacks = [],
    +	rjsonp = /(=)\?(?=&|$)|\?\?/;
    +
    +// Default jsonp settings
    +jQuery.ajaxSetup( {
    +	jsonp: "callback",
    +	jsonpCallback: function() {
    +		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
    +		this[ callback ] = true;
    +		return callback;
    +	}
    +} );
    +
    +// Detect, normalize options and install callbacks for jsonp requests
    +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
    +
    +	var callbackName, overwritten, responseContainer,
    +		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
    +			"url" :
    +			typeof s.data === "string" &&
    +				( s.contentType || "" )
    +					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
    +				rjsonp.test( s.data ) && "data"
    +		);
    +
    +	// Handle iff the expected data type is "jsonp" or we have a parameter to set
    +	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
    +
    +		// Get callback name, remembering preexisting value associated with it
    +		callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
    +			s.jsonpCallback() :
    +			s.jsonpCallback;
    +
    +		// Insert callback into url or form data
    +		if ( jsonProp ) {
    +			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
    +		} else if ( s.jsonp !== false ) {
    +			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
    +		}
    +
    +		// Use data converter to retrieve json after script execution
    +		s.converters[ "script json" ] = function() {
    +			if ( !responseContainer ) {
    +				jQuery.error( callbackName + " was not called" );
    +			}
    +			return responseContainer[ 0 ];
    +		};
    +
    +		// Force json dataType
    +		s.dataTypes[ 0 ] = "json";
    +
    +		// Install callback
    +		overwritten = window[ callbackName ];
    +		window[ callbackName ] = function() {
    +			responseContainer = arguments;
    +		};
    +
    +		// Clean-up function (fires after converters)
    +		jqXHR.always( function() {
    +
    +			// If previous value didn't exist - remove it
    +			if ( overwritten === undefined ) {
    +				jQuery( window ).removeProp( callbackName );
    +
    +			// Otherwise restore preexisting value
    +			} else {
    +				window[ callbackName ] = overwritten;
    +			}
    +
    +			// Save back as free
    +			if ( s[ callbackName ] ) {
    +
    +				// Make sure that re-using the options doesn't screw things around
    +				s.jsonpCallback = originalSettings.jsonpCallback;
    +
    +				// Save the callback name for future use
    +				oldCallbacks.push( callbackName );
    +			}
    +
    +			// Call if it was a function and we have a response
    +			if ( responseContainer && isFunction( overwritten ) ) {
    +				overwritten( responseContainer[ 0 ] );
    +			}
    +
    +			responseContainer = overwritten = undefined;
    +		} );
    +
    +		// Delegate to script
    +		return "script";
    +	}
    +} );
    +
    +
    +
    +
    +// Support: Safari 8 only
    +// In Safari 8 documents created via document.implementation.createHTMLDocument
    +// collapse sibling forms: the second one becomes a child of the first one.
    +// Because of that, this security measure has to be disabled in Safari 8.
    +// https://bugs.webkit.org/show_bug.cgi?id=137337
    +support.createHTMLDocument = ( function() {
    +	var body = document.implementation.createHTMLDocument( "" ).body;
    +	body.innerHTML = "<form></form><form></form>";
    +	return body.childNodes.length === 2;
    +} )();
    +
    +
    +// Argument "data" should be string of html
    +// context (optional): If specified, the fragment will be created in this context,
    +// defaults to document
    +// keepScripts (optional): If true, will include scripts passed in the html string
    +jQuery.parseHTML = function( data, context, keepScripts ) {
    +	if ( typeof data !== "string" ) {
    +		return [];
    +	}
    +	if ( typeof context === "boolean" ) {
    +		keepScripts = context;
    +		context = false;
    +	}
    +
    +	var base, parsed, scripts;
    +
    +	if ( !context ) {
    +
    +		// Stop scripts or inline event handlers from being executed immediately
    +		// by using document.implementation
    +		if ( support.createHTMLDocument ) {
    +			context = document.implementation.createHTMLDocument( "" );
    +
    +			// Set the base href for the created document
    +			// so any parsed elements with URLs
    +			// are based on the document's URL (gh-2965)
    +			base = context.createElement( "base" );
    +			base.href = document.location.href;
    +			context.head.appendChild( base );
    +		} else {
    +			context = document;
    +		}
    +	}
    +
    +	parsed = rsingleTag.exec( data );
    +	scripts = !keepScripts && [];
    +
    +	// Single tag
    +	if ( parsed ) {
    +		return [ context.createElement( parsed[ 1 ] ) ];
    +	}
    +
    +	parsed = buildFragment( [ data ], context, scripts );
    +
    +	if ( scripts && scripts.length ) {
    +		jQuery( scripts ).remove();
    +	}
    +
    +	return jQuery.merge( [], parsed.childNodes );
    +};
    +
    +
    +/**
    + * Load a url into a page
    + */
    +jQuery.fn.load = function( url, params, callback ) {
    +	var selector, type, response,
    +		self = this,
    +		off = url.indexOf( " " );
    +
    +	if ( off > -1 ) {
    +		selector = stripAndCollapse( url.slice( off ) );
    +		url = url.slice( 0, off );
    +	}
    +
    +	// If it's a function
    +	if ( isFunction( params ) ) {
    +
    +		// We assume that it's the callback
    +		callback = params;
    +		params = undefined;
    +
    +	// Otherwise, build a param string
    +	} else if ( params && typeof params === "object" ) {
    +		type = "POST";
    +	}
    +
    +	// If we have elements to modify, make the request
    +	if ( self.length > 0 ) {
    +		jQuery.ajax( {
    +			url: url,
    +
    +			// If "type" variable is undefined, then "GET" method will be used.
    +			// Make value of this field explicit since
    +			// user can override it through ajaxSetup method
    +			type: type || "GET",
    +			dataType: "html",
    +			data: params
    +		} ).done( function( responseText ) {
    +
    +			// Save response for use in complete callback
    +			response = arguments;
    +
    +			self.html( selector ?
    +
    +				// If a selector was specified, locate the right elements in a dummy div
    +				// Exclude scripts to avoid IE 'Permission Denied' errors
    +				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
    +
    +				// Otherwise use the full result
    +				responseText );
    +
    +		// If the request succeeds, this function gets "data", "status", "jqXHR"
    +		// but they are ignored because response was set above.
    +		// If it fails, this function gets "jqXHR", "status", "error"
    +		} ).always( callback && function( jqXHR, status ) {
    +			self.each( function() {
    +				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
    +			} );
    +		} );
    +	}
    +
    +	return this;
    +};
    +
    +
    +
    +
    +// Attach a bunch of functions for handling common AJAX events
    +jQuery.each( [
    +	"ajaxStart",
    +	"ajaxStop",
    +	"ajaxComplete",
    +	"ajaxError",
    +	"ajaxSuccess",
    +	"ajaxSend"
    +], function( i, type ) {
    +	jQuery.fn[ type ] = function( fn ) {
    +		return this.on( type, fn );
    +	};
    +} );
    +
    +
    +
    +
    +jQuery.expr.pseudos.animated = function( elem ) {
    +	return jQuery.grep( jQuery.timers, function( fn ) {
    +		return elem === fn.elem;
    +	} ).length;
    +};
    +
    +
    +
    +
    +jQuery.offset = {
    +	setOffset: function( elem, options, i ) {
    +		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
    +			position = jQuery.css( elem, "position" ),
    +			curElem = jQuery( elem ),
    +			props = {};
    +
    +		// Set position first, in-case top/left are set even on static elem
    +		if ( position === "static" ) {
    +			elem.style.position = "relative";
    +		}
    +
    +		curOffset = curElem.offset();
    +		curCSSTop = jQuery.css( elem, "top" );
    +		curCSSLeft = jQuery.css( elem, "left" );
    +		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
    +			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
    +
    +		// Need to be able to calculate position if either
    +		// top or left is auto and position is either absolute or fixed
    +		if ( calculatePosition ) {
    +			curPosition = curElem.position();
    +			curTop = curPosition.top;
    +			curLeft = curPosition.left;
    +
    +		} else {
    +			curTop = parseFloat( curCSSTop ) || 0;
    +			curLeft = parseFloat( curCSSLeft ) || 0;
    +		}
    +
    +		if ( isFunction( options ) ) {
    +
    +			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
    +			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
    +		}
    +
    +		if ( options.top != null ) {
    +			props.top = ( options.top - curOffset.top ) + curTop;
    +		}
    +		if ( options.left != null ) {
    +			props.left = ( options.left - curOffset.left ) + curLeft;
    +		}
    +
    +		if ( "using" in options ) {
    +			options.using.call( elem, props );
    +
    +		} else {
    +			curElem.css( props );
    +		}
    +	}
    +};
    +
    +jQuery.fn.extend( {
    +
    +	// offset() relates an element's border box to the document origin
    +	offset: function( options ) {
    +
    +		// Preserve chaining for setter
    +		if ( arguments.length ) {
    +			return options === undefined ?
    +				this :
    +				this.each( function( i ) {
    +					jQuery.offset.setOffset( this, options, i );
    +				} );
    +		}
    +
    +		var rect, win,
    +			elem = this[ 0 ];
    +
    +		if ( !elem ) {
    +			return;
    +		}
    +
    +		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
    +		// Support: IE <=11 only
    +		// Running getBoundingClientRect on a
    +		// disconnected node in IE throws an error
    +		if ( !elem.getClientRects().length ) {
    +			return { top: 0, left: 0 };
    +		}
    +
    +		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
    +		rect = elem.getBoundingClientRect();
    +		win = elem.ownerDocument.defaultView;
    +		return {
    +			top: rect.top + win.pageYOffset,
    +			left: rect.left + win.pageXOffset
    +		};
    +	},
    +
    +	// position() relates an element's margin box to its offset parent's padding box
    +	// This corresponds to the behavior of CSS absolute positioning
    +	position: function() {
    +		if ( !this[ 0 ] ) {
    +			return;
    +		}
    +
    +		var offsetParent, offset, doc,
    +			elem = this[ 0 ],
    +			parentOffset = { top: 0, left: 0 };
    +
    +		// position:fixed elements are offset from the viewport, which itself always has zero offset
    +		if ( jQuery.css( elem, "position" ) === "fixed" ) {
    +
    +			// Assume position:fixed implies availability of getBoundingClientRect
    +			offset = elem.getBoundingClientRect();
    +
    +		} else {
    +			offset = this.offset();
    +
    +			// Account for the *real* offset parent, which can be the document or its root element
    +			// when a statically positioned element is identified
    +			doc = elem.ownerDocument;
    +			offsetParent = elem.offsetParent || doc.documentElement;
    +			while ( offsetParent &&
    +				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
    +				jQuery.css( offsetParent, "position" ) === "static" ) {
    +
    +				offsetParent = offsetParent.parentNode;
    +			}
    +			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
    +
    +				// Incorporate borders into its offset, since they are outside its content origin
    +				parentOffset = jQuery( offsetParent ).offset();
    +				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
    +				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
    +			}
    +		}
    +
    +		// Subtract parent offsets and element margins
    +		return {
    +			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
    +			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
    +		};
    +	},
    +
    +	// This method will return documentElement in the following cases:
    +	// 1) For the element inside the iframe without offsetParent, this method will return
    +	//    documentElement of the parent window
    +	// 2) For the hidden or detached element
    +	// 3) For body or html element, i.e. in case of the html node - it will return itself
    +	//
    +	// but those exceptions were never presented as a real life use-cases
    +	// and might be considered as more preferable results.
    +	//
    +	// This logic, however, is not guaranteed and can change at any point in the future
    +	offsetParent: function() {
    +		return this.map( function() {
    +			var offsetParent = this.offsetParent;
    +
    +			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
    +				offsetParent = offsetParent.offsetParent;
    +			}
    +
    +			return offsetParent || documentElement;
    +		} );
    +	}
    +} );
    +
    +// Create scrollLeft and scrollTop methods
    +jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
    +	var top = "pageYOffset" === prop;
    +
    +	jQuery.fn[ method ] = function( val ) {
    +		return access( this, function( elem, method, val ) {
    +
    +			// Coalesce documents and windows
    +			var win;
    +			if ( isWindow( elem ) ) {
    +				win = elem;
    +			} else if ( elem.nodeType === 9 ) {
    +				win = elem.defaultView;
    +			}
    +
    +			if ( val === undefined ) {
    +				return win ? win[ prop ] : elem[ method ];
    +			}
    +
    +			if ( win ) {
    +				win.scrollTo(
    +					!top ? val : win.pageXOffset,
    +					top ? val : win.pageYOffset
    +				);
    +
    +			} else {
    +				elem[ method ] = val;
    +			}
    +		}, method, val, arguments.length );
    +	};
    +} );
    +
    +// Support: Safari <=7 - 9.1, Chrome <=37 - 49
    +// Add the top/left cssHooks using jQuery.fn.position
    +// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
    +// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
    +// getComputedStyle returns percent when specified for top/left/bottom/right;
    +// rather than make the css module depend on the offset module, just check for it here
    +jQuery.each( [ "top", "left" ], function( i, prop ) {
    +	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
    +		function( elem, computed ) {
    +			if ( computed ) {
    +				computed = curCSS( elem, prop );
    +
    +				// If curCSS returns percentage, fallback to offset
    +				return rnumnonpx.test( computed ) ?
    +					jQuery( elem ).position()[ prop ] + "px" :
    +					computed;
    +			}
    +		}
    +	);
    +} );
    +
    +
    +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
    +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
    +	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
    +		function( defaultExtra, funcName ) {
    +
    +		// Margin is only for outerHeight, outerWidth
    +		jQuery.fn[ funcName ] = function( margin, value ) {
    +			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
    +				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
    +
    +			return access( this, function( elem, type, value ) {
    +				var doc;
    +
    +				if ( isWindow( elem ) ) {
    +
    +					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
    +					return funcName.indexOf( "outer" ) === 0 ?
    +						elem[ "inner" + name ] :
    +						elem.document.documentElement[ "client" + name ];
    +				}
    +
    +				// Get document width or height
    +				if ( elem.nodeType === 9 ) {
    +					doc = elem.documentElement;
    +
    +					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
    +					// whichever is greatest
    +					return Math.max(
    +						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
    +						elem.body[ "offset" + name ], doc[ "offset" + name ],
    +						doc[ "client" + name ]
    +					);
    +				}
    +
    +				return value === undefined ?
    +
    +					// Get width or height on the element, requesting but not forcing parseFloat
    +					jQuery.css( elem, type, extra ) :
    +
    +					// Set width or height on the element
    +					jQuery.style( elem, type, value, extra );
    +			}, type, chainable ? margin : undefined, chainable );
    +		};
    +	} );
    +} );
    +
    +
    +jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
    +	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
    +	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
    +	function( i, name ) {
    +
    +	// Handle event binding
    +	jQuery.fn[ name ] = function( data, fn ) {
    +		return arguments.length > 0 ?
    +			this.on( name, null, data, fn ) :
    +			this.trigger( name );
    +	};
    +} );
    +
    +jQuery.fn.extend( {
    +	hover: function( fnOver, fnOut ) {
    +		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
    +	}
    +} );
    +
    +
    +
    +
    +jQuery.fn.extend( {
    +
    +	bind: function( types, data, fn ) {
    +		return this.on( types, null, data, fn );
    +	},
    +	unbind: function( types, fn ) {
    +		return this.off( types, null, fn );
    +	},
    +
    +	delegate: function( selector, types, data, fn ) {
    +		return this.on( types, selector, data, fn );
    +	},
    +	undelegate: function( selector, types, fn ) {
    +
    +		// ( namespace ) or ( selector, types [, fn] )
    +		return arguments.length === 1 ?
    +			this.off( selector, "**" ) :
    +			this.off( types, selector || "**", fn );
    +	}
    +} );
    +
    +// Bind a function to a context, optionally partially applying any
    +// arguments.
    +// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
    +// However, it is not slated for removal any time soon
    +jQuery.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 ( !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;
    +};
    +
    +jQuery.holdReady = function( hold ) {
    +	if ( hold ) {
    +		jQuery.readyWait++;
    +	} else {
    +		jQuery.ready( true );
    +	}
    +};
    +jQuery.isArray = Array.isArray;
    +jQuery.parseJSON = JSON.parse;
    +jQuery.nodeName = nodeName;
    +jQuery.isFunction = isFunction;
    +jQuery.isWindow = isWindow;
    +jQuery.camelCase = camelCase;
    +jQuery.type = toType;
    +
    +jQuery.now = Date.now;
    +
    +jQuery.isNumeric = function( obj ) {
    +
    +	// As of jQuery 3.0, isNumeric is limited to
    +	// strings and numbers (primitives or objects)
    +	// that can be coerced to finite numbers (gh-2662)
    +	var type = jQuery.type( obj );
    +	return ( type === "number" || type === "string" ) &&
    +
    +		// parseFloat NaNs numeric-cast false positives ("")
    +		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
    +		// subtraction forces infinities to NaN
    +		!isNaN( obj - parseFloat( obj ) );
    +};
    +
    +
    +
    +
    +// Register as a named AMD module, since jQuery can be concatenated with other
    +// files that may use define, but not via a proper concatenation script that
    +// understands anonymous AMD modules. A named AMD is safest and most robust
    +// way to register. Lowercase jquery is used because AMD module names are
    +// derived from file names, and jQuery is normally delivered in a lowercase
    +// file name. Do this after creating the global so that if an AMD module wants
    +// to call noConflict to hide this version of jQuery, it will work.
    +
    +// Note that for maximum portability, libraries that are not jQuery should
    +// declare themselves as anonymous modules, and avoid setting a global if an
    +// AMD loader is present. jQuery is a special case. For more information, see
    +// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
    +
    +if ( typeof define === "function" && define.amd ) {
    +	define( "jquery", [], function() {
    +		return jQuery;
    +	} );
    +}
    +
    +
    +
    +
    +var
    +
    +	// Map over jQuery in case of overwrite
    +	_jQuery = window.jQuery,
    +
    +	// Map over the $ in case of overwrite
    +	_$ = window.$;
    +
    +jQuery.noConflict = function( deep ) {
    +	if ( window.$ === jQuery ) {
    +		window.$ = _$;
    +	}
    +
    +	if ( deep && window.jQuery === jQuery ) {
    +		window.jQuery = _jQuery;
    +	}
    +
    +	return jQuery;
    +};
    +
    +// Expose jQuery and $ identifiers, even in AMD
    +// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
    +// and CommonJS for browser emulators (#13566)
    +if ( !noGlobal ) {
    +	window.jQuery = window.$ = jQuery;
    +}
    +
    +
    +
    +
    +return jQuery;
    +} );