From ffb0db7c6bfac7e5d26bd460fb15431f5cd6d788 Mon Sep 17 00:00:00 2001 From: freddygv Date: Wed, 10 Apr 2019 14:37:50 -0600 Subject: [PATCH 1/6] Remove old ui dir --- ui/GNUmakefile | 12 - ui/Gemfile | 7 - ui/Gemfile.lock | 32 - ui/README.md | 80 - ui/index.html | 803 ------- ui/javascripts/app/controllers.js | 534 ----- ui/javascripts/app/helpers.js | 181 -- ui/javascripts/app/mixins.js | 0 ui/javascripts/app/models.js | 314 --- ui/javascripts/app/router.js | 59 - ui/javascripts/app/routes.js | 462 ---- ui/javascripts/app/views.js | 81 - ui/javascripts/fixtures.js | 317 --- ui/javascripts/libs/base64.min.js | 1 - ui/javascripts/libs/classie.js | 80 - ui/javascripts/libs/classie.min.js | 0 ui/javascripts/libs/ember-debug.min.js | 679 ------ ui/javascripts/libs/ember-validations.min.js | 2 - ui/javascripts/libs/ember.min.js | 27 - ui/javascripts/libs/handlebars-1.3.0.min.js | 83 - ui/javascripts/libs/jquery-1.10.2.min.js | 26 - ui/javascripts/libs/list-view.min.js | 5 - ui/javascripts/libs/notificationFx.js | 146 -- ui/scripts/compile.rb | 37 - ui/scripts/dist.sh | 37 - ui/static/android-chrome-192x192.png | Bin 18250 -> 0 bytes ui/static/android-chrome-512x512.png | Bin 58433 -> 0 bytes ui/static/apple-touch-icon-114x114.png | Bin 15576 -> 0 bytes ui/static/apple-touch-icon-120x120.png | Bin 16251 -> 0 bytes ui/static/apple-touch-icon-144x144.png | Bin 20027 -> 0 bytes ui/static/apple-touch-icon-152x152.png | Bin 23769 -> 0 bytes ui/static/apple-touch-icon-57x57.png | Bin 5158 -> 0 bytes ui/static/apple-touch-icon-60x60.png | Bin 5522 -> 0 bytes ui/static/apple-touch-icon-72x72.png | Bin 7289 -> 0 bytes ui/static/apple-touch-icon-76x76.png | Bin 8031 -> 0 bytes ui/static/apple-touch-icon.png | Bin 8285 -> 0 bytes ui/static/base.css.map | 7 - ui/static/bootstrap.min.css | 7 - ui/static/consul-logo.png | Bin 58433 -> 0 bytes ui/static/favicon-128.png | Bin 11154 -> 0 bytes ui/static/favicon-16x16.png | Bin 821 -> 0 bytes ui/static/favicon-196x196.png | Bin 37174 -> 0 bytes ui/static/favicon-32x32.png | Bin 2075 -> 0 bytes ui/static/favicon-96x96.png | Bin 10171 -> 0 bytes ui/static/favicon.ico | Bin 34494 -> 0 bytes ui/static/favicon.png | Bin 821 -> 0 bytes ui/static/loading-cylon-pink.svg | 11 - ui/static/mstile-144x144.png | Bin 20027 -> 0 bytes ui/static/mstile-150x150.png | Bin 64646 -> 0 bytes ui/static/mstile-310x150.png | Bin 112362 -> 0 bytes ui/static/mstile-310x310.png | Bin 201893 -> 0 bytes ui/static/mstile-70x70.png | Bin 11154 -> 0 bytes ui/static/safari-pinned-tab.svg | 61 - ui/static/tada.png | Bin 1767 -> 0 bytes ui/style-guide.html | 320 --- ui/styles/_buttons.scss | 123 - ui/styles/_forms.scss | 56 - ui/styles/_lists.scss | 126 - ui/styles/_mixins.scss | 7 - ui/styles/_nav.scss | 47 - ui/styles/_notifications.scss | 267 --- ui/styles/_panels.scss | 131 -- ui/styles/_type.scss | 71 - ui/styles/_v2-notification.scss | 94 - ui/styles/_variables.scss | 28 - ui/styles/base.scss | 189 -- ui/tests/runner.css | 14 - ui/tests/runner.js | 13 - ui/tests/tests.js | 113 - ui/tests/vendor/qunit-1.12.0.css | 244 -- ui/tests/vendor/qunit-1.12.0.js | 2212 ------------------ 71 files changed, 8146 deletions(-) delete mode 100644 ui/GNUmakefile delete mode 100644 ui/Gemfile delete mode 100644 ui/Gemfile.lock delete mode 100644 ui/README.md delete mode 100644 ui/index.html delete mode 100644 ui/javascripts/app/controllers.js delete mode 100644 ui/javascripts/app/helpers.js delete mode 100644 ui/javascripts/app/mixins.js delete mode 100644 ui/javascripts/app/models.js delete mode 100644 ui/javascripts/app/router.js delete mode 100644 ui/javascripts/app/routes.js delete mode 100644 ui/javascripts/app/views.js delete mode 100644 ui/javascripts/fixtures.js delete mode 100644 ui/javascripts/libs/base64.min.js delete mode 100755 ui/javascripts/libs/classie.js delete mode 100644 ui/javascripts/libs/classie.min.js delete mode 100644 ui/javascripts/libs/ember-debug.min.js delete mode 100644 ui/javascripts/libs/ember-validations.min.js delete mode 100644 ui/javascripts/libs/ember.min.js delete mode 100644 ui/javascripts/libs/handlebars-1.3.0.min.js delete mode 100644 ui/javascripts/libs/jquery-1.10.2.min.js delete mode 100644 ui/javascripts/libs/list-view.min.js delete mode 100644 ui/javascripts/libs/notificationFx.js delete mode 100644 ui/scripts/compile.rb delete mode 100755 ui/scripts/dist.sh delete mode 100644 ui/static/android-chrome-192x192.png delete mode 100644 ui/static/android-chrome-512x512.png delete mode 100644 ui/static/apple-touch-icon-114x114.png delete mode 100644 ui/static/apple-touch-icon-120x120.png delete mode 100644 ui/static/apple-touch-icon-144x144.png delete mode 100644 ui/static/apple-touch-icon-152x152.png delete mode 100644 ui/static/apple-touch-icon-57x57.png delete mode 100644 ui/static/apple-touch-icon-60x60.png delete mode 100644 ui/static/apple-touch-icon-72x72.png delete mode 100644 ui/static/apple-touch-icon-76x76.png delete mode 100644 ui/static/apple-touch-icon.png delete mode 100644 ui/static/base.css.map delete mode 100644 ui/static/bootstrap.min.css delete mode 100644 ui/static/consul-logo.png delete mode 100644 ui/static/favicon-128.png delete mode 100644 ui/static/favicon-16x16.png delete mode 100644 ui/static/favicon-196x196.png delete mode 100644 ui/static/favicon-32x32.png delete mode 100644 ui/static/favicon-96x96.png delete mode 100644 ui/static/favicon.ico delete mode 100644 ui/static/favicon.png delete mode 100644 ui/static/loading-cylon-pink.svg delete mode 100644 ui/static/mstile-144x144.png delete mode 100644 ui/static/mstile-150x150.png delete mode 100644 ui/static/mstile-310x150.png delete mode 100644 ui/static/mstile-310x310.png delete mode 100644 ui/static/mstile-70x70.png delete mode 100644 ui/static/safari-pinned-tab.svg delete mode 100644 ui/static/tada.png delete mode 100644 ui/style-guide.html delete mode 100644 ui/styles/_buttons.scss delete mode 100644 ui/styles/_forms.scss delete mode 100644 ui/styles/_lists.scss delete mode 100644 ui/styles/_mixins.scss delete mode 100644 ui/styles/_nav.scss delete mode 100644 ui/styles/_notifications.scss delete mode 100644 ui/styles/_panels.scss delete mode 100644 ui/styles/_type.scss delete mode 100644 ui/styles/_v2-notification.scss delete mode 100644 ui/styles/_variables.scss delete mode 100644 ui/styles/base.scss delete mode 100755 ui/tests/runner.css delete mode 100755 ui/tests/runner.js delete mode 100755 ui/tests/tests.js delete mode 100755 ui/tests/vendor/qunit-1.12.0.css delete mode 100755 ui/tests/vendor/qunit-1.12.0.js diff --git a/ui/GNUmakefile b/ui/GNUmakefile deleted file mode 100644 index 7bccbd75615e..000000000000 --- a/ui/GNUmakefile +++ /dev/null @@ -1,12 +0,0 @@ -ROOT:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) - -server: - python -m SimpleHTTPServer - -watch: - sass styles:static --watch - -dist: - @sh -c "'$(ROOT)/scripts/dist.sh'" - -.PHONY: server watch dist diff --git a/ui/Gemfile b/ui/Gemfile deleted file mode 100644 index ce0147581d34..000000000000 --- a/ui/Gemfile +++ /dev/null @@ -1,7 +0,0 @@ -# A sample Gemfile -source "https://rubygems.org" - -gem "ffi", "~> 1.9.24" -gem "uglifier" -gem "sass" -gem "therubyracer" diff --git a/ui/Gemfile.lock b/ui/Gemfile.lock deleted file mode 100644 index 42d5a015a3c6..000000000000 --- a/ui/Gemfile.lock +++ /dev/null @@ -1,32 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - execjs (2.7.0) - ffi (1.9.25) - libv8 (3.16.14.19) - rb-fsevent (0.10.3) - rb-inotify (0.9.10) - ffi (>= 0.5.0, < 2) - ref (2.0.0) - sass (3.5.6) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - therubyracer (0.12.3) - libv8 (~> 3.16.14.15) - ref - uglifier (4.1.9) - execjs (>= 0.3.0, < 3) - -PLATFORMS - ruby - -DEPENDENCIES - ffi (~> 1.9.24) - sass - therubyracer - uglifier - -BUNDLED WITH - 1.16.1 diff --git a/ui/README.md b/ui/README.md deleted file mode 100644 index 23b2c9047964..000000000000 --- a/ui/README.md +++ /dev/null @@ -1,80 +0,0 @@ -## Consul Web UI - -This directory contains the Consul Web UI. Consul contains a built-in -HTTP server that serves this directory, but any common HTTP server -is capable of serving it. - -It uses JavaScript and [Ember](http://emberjs.com) to communicate with -the [Consul API](https://www.consul.io/api/index.html). The basic -features it provides are: - -- Service view. A list of your registered services, their -health and the nodes they run on. -- Node view. A list of your registered nodes, the services running -on each and the health of the node. -- Key/value view and update - -It's aware of multiple datacenters, so you can get a quick global -overview before drilling into specific data-centers for detailed -views. - -The UI uses some internal undocumented HTTP APIs to optimize -performance and usability. - -### Development - -Improvements and bug fixes are welcome and encouraged for the Web UI. - -You'll need sass to compile CSS stylesheets. Install that with -bundler: - - cd ui/ - bundle - -Reloading compilation for development: - - make watch - -Consul ships with an HTTP server for the API and UI. By default, when -you run the agent, it is off. However, if you pass a `-ui-dir` flag -with a path to this directory, you'll be able to access the UI via the -Consul HTTP server address, which defaults to `localhost:8500/ui`. - -An example of this command, from inside the `ui/` directory, would be: - - consul agent -bootstrap -server -data-dir /tmp/ -ui-dir . - -Basic tests can be run by adding the `?test` query parameter to the -application. - -When developing Consul, it's recommended that you use the included -development configuration. - - consul agent -config-file=development_config.json - -### Releasing - -`make dist` - -The `../pkg/web_ui` folder will contain the files you should use for deployment. - -### Acknowledgments - -Cog icon by useiconic.com from the [Noun Project](https://thenounproject.com/term/setting/45865/) - -### Compiling the UI into the Go binary - -The UI is compiled and shipped with the Consul go binary. The generated bindata -file lives in the `command/agent/bindata_assetfs.go` file and is checked into -source control. This is useful so that not every Consul developer needs to set -up bundler etc. To re-generate the file, first follow the compilation steps -above to build the UI assets into the `pkg/web_ui` folder. With that done, from the -root of the Consul repo, run: - -``` -$ make static-assets -``` - -The file will now be refreshed with the current UI data. You can now rebuild the -Consul binary normally with `make bin` or `make dev`, and see the updated UI -after re-launching Consul. diff --git a/ui/index.html b/ui/index.html deleted file mode 100644 index 3aa423d5c181..000000000000 --- a/ui/index.html +++ /dev/null @@ -1,803 +0,0 @@ - - - - - - - Consul by HashiCorp - - - - - - - - - - - - -
-
-
-
-
-
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ui/javascripts/app/controllers.js b/ui/javascripts/app/controllers.js deleted file mode 100644 index 6e3f369f900e..000000000000 --- a/ui/javascripts/app/controllers.js +++ /dev/null @@ -1,534 +0,0 @@ -App.ApplicationController = Ember.ObjectController.extend({ - updateCurrentPath: function() { - App.set('currentPath', this.get('currentPath')); - }.observes('currentPath') -}); - -App.DcController = Ember.Controller.extend({ - needs: ["application"], - // Whether or not the dropdown menu can be seen - isDropdownVisible: false, - isNotificationVisible: true, - - datacenter: Ember.computed.alias('content'), - - // Returns the total number of failing checks. - // - // We treat any non-passing checks as failing - // - totalChecksFailing: function() { - return this.get('nodes').reduce(function(sum, node) { - return sum + node.get('failingChecks'); - }, 0); - }.property('nodes'), - - totalChecksPassing: function() { - return this.get('nodes').reduce(function(sum, node) { - return sum + node.get('passingChecks'); - }, 0); - }.property('nodes'), - - // - // Returns the human formatted message for the button state - // - checkMessage: function() { - var failingChecks = this.get('totalChecksFailing'); - var passingChecks = this.get('totalChecksPassing'); - - if (this.get('hasFailingChecks') === true) { - return failingChecks + ' failing'; - } else { - return passingChecks + ' passing'; - } - - }.property('nodes'), - - // - // - // - checkStatus: function() { - if (this.get('hasFailingChecks') === true) { - return "failing"; - } else { - return "passing"; - } - - }.property('nodes'), - - // - // Boolean if the datacenter has any failing checks. - // - hasFailingChecks: Ember.computed.gt('totalChecksFailing', 0), - - init: function() { - if(App.get('settings.v1-notification-hidden', true)) { - this.set('isNotificationVisible', false); - } - }, - actions: { - // Hide and show the dropdown menu - toggle: function(item){ - this.toggleProperty('isDropdownVisible'); - }, - hideNotification: function(e) { - App.set('settings.v1-notification-hidden', true); - this.set('isNotificationVisible', false); - }, - // Just hide the dropdown menu - hideDrop: function(item){ - this.set('isDropdownVisible', false); - } - } -}); - -KvBaseController = Ember.ObjectController.extend({ - getParentKeyRoute: function() { - if (this.get('isRoot')) { - return this.get('rootKey'); - } - return this.get('parentKey'); - }, - - transitionToNearestParent: function(parent) { - var controller = this; - var rootKey = controller.get('rootKey'); - var dc = controller.get('dc').get('datacenter'); - var token = App.get('settings.token'); - - Ember.$.ajax({ - url: (formatUrl(consulHost + '/v1/kv/' + parent + '?keys', dc, token)), - type: 'GET' - }).then(function(data) { - controller.transitionToRoute('kv.show', parent); - }).fail(function(response) { - if (response.status === 404) { - controller.transitionToRoute('kv.show', rootKey); - } - }); - - controller.set('isLoading', false); - } -}); - -App.KvShowController = KvBaseController.extend(Ember.Validations.Mixin, { - needs: ["dc"], - dc: Ember.computed.alias("controllers.dc"), - isLoading: false, - - actions: { - // Creates the key from the newKey model - // set on the route. - createKey: function() { - this.set('isLoading', true); - - var controller = this; - var newKey = controller.get('newKey'); - var parentKey = controller.get('parentKey'); - var grandParentKey = controller.get('grandParentKey'); - var dc = controller.get('dc').get('datacenter'); - var token = App.get('settings.token'); - - // If we don't have a previous model to base - // on our parent, or we're not at the root level, - // add the prefix - if (parentKey !== undefined && parentKey !== "/") { - newKey.set('Key', (parentKey + newKey.get('Key'))); - } - - // Put the Key and the Value retrieved from the form - Ember.$.ajax({ - url: (formatUrl(consulHost + "/v1/kv/" + newKey.get('Key'), dc, token)), - type: 'PUT', - data: newKey.get('Value') - }).then(function(response) { - // transition to the right place - if (newKey.get('isFolder') === true) { - controller.transitionToRoute('kv.show', newKey.get('Key')); - } else { - controller.transitionToRoute('kv.edit', newKey.get('Key')); - } - controller.set('isLoading', false); - }).fail(function(response) { - // Render the error message on the form if the request failed - controller.set('errorMessage', 'Received error while processing: ' + response.statusText); - }); - }, - - deleteFolder: function() { - - this.set('isLoading', true); - var controller = this; - var dc = controller.get('dc').get('datacenter'); - var grandParent = controller.get('grandParentKey'); - var token = App.get('settings.token'); - - if (window.confirm("Are you sure you want to delete this folder?")) { - // Delete the folder - Ember.$.ajax({ - url: (formatUrl(consulHost + "/v1/kv/" + controller.get('parentKey') + '?recurse', dc, token)), - type: 'DELETE' - }).then(function(response) { - controller.transitionToNearestParent(grandParent); - }).fail(function(response) { - // Render the error message on the form if the request failed - controller.set('errorMessage', 'Received error while processing: ' + response.statusText); - }); - } - } - } -}); - -App.KvEditController = KvBaseController.extend({ - isLoading: false, - needs: ["dc"], - dc: Ember.computed.alias("controllers.dc"), - - actions: { - // Updates the key set as the model on the route. - updateKey: function() { - this.set('isLoading', true); - - var dc = this.get('dc').get('datacenter'); - var key = this.get("model"); - var controller = this; - var token = App.get('settings.token'); - - // Put the key and the decoded (plain text) value - // from the form. - Ember.$.ajax({ - url: (formatUrl(consulHost + "/v1/kv/" + key.get('Key'), dc, token)), - type: 'PUT', - data: key.get('valueDecoded') - }).then(function(response) { - // If success, just reset the loading state. - controller.set('isLoading', false); - }).fail(function(response) { - // Render the error message on the form if the request failed - controller.set('errorMessage', 'Received error while processing: ' + response.statusText); - }); - }, - - cancelEdit: function() { - this.set('isLoading', true); - this.transitionToRoute('kv.show', this.getParentKeyRoute()); - this.set('isLoading', false); - }, - - deleteKey: function() { - this.set('isLoading', true); - - var controller = this; - var dc = controller.get('dc').get('datacenter'); - var key = controller.get("model"); - var parent = controller.getParentKeyRoute(); - var token = App.get('settings.token'); - - // Delete the key - Ember.$.ajax({ - url: (formatUrl(consulHost + "/v1/kv/" + key.get('Key'), dc, token)), - type: 'DELETE' - }).then(function(data) { - controller.transitionToNearestParent(parent); - }).fail(function(response) { - // Render the error message on the form if the request failed - controller.set('errorMessage', 'Received error while processing: ' + response.statusText); - }); - } - } - -}); - -ItemBaseController = Ember.ArrayController.extend({ - needs: ["dc", "application"], - queryParams: ["filter", "status", "condensed"], - dc: Ember.computed.alias("controllers.dc"), - condensed: true, - hasExpanded: true, - filterText: "Filter by name", - filter: "", // default - status: "any status", // default - statuses: ["any status", "passing", "failing"], - - isShowingItem: function() { - var currentPath = this.get('controllers.application.currentPath'); - return (currentPath === "dc.nodes.show" || currentPath === "dc.services.show"); - }.property('controllers.application.currentPath'), - - filteredContent: function() { - var filter = this.get('filter'); - var status = this.get('status'); - - var items = this.get('items').filter(function(item){ - return item.get('filterKey').toLowerCase().match(filter.toLowerCase()); - }); - - switch (status) { - case "passing": - return items.filterBy('hasFailingChecks', false); - case "failing": - return items.filterBy('hasFailingChecks', true); - default: - return items; - } - - }.property('filter', 'status', 'items.@each'), - - actions: { - toggleCondensed: function() { - this.toggleProperty('condensed'); - } - } -}); - -App.NodesShowController = Ember.ObjectController.extend({ - needs: ["dc", "nodes"], - dc: Ember.computed.alias("controllers.dc"), - - actions: { - invalidateSession: function(sessionId) { - this.set('isLoading', true); - var controller = this; - var node = controller.get('model'); - var dc = controller.get('dc').get('datacenter'); - var token = App.get('settings.token'); - - if (window.confirm("Are you sure you want to invalidate this session?")) { - // Delete the session - Ember.$.ajax({ - url: (formatUrl(consulHost + "/v1/session/destroy/" + sessionId, dc, token)), - type: 'PUT' - }).then(function(response) { - return Ember.$.getJSON(formatUrl(consulHost + '/v1/session/node/' + node.Node, dc, token)).then(function(data) { - controller.set('sessions', data); - }); - }).fail(function(response) { - // Render the error message on the form if the request failed - controller.set('errorMessage', 'Received error while processing: ' + response.statusText); - }); - } - } - } -}); - -App.NodesController = ItemBaseController.extend({ - items: Ember.computed.alias("nodes"), -}); - -App.ServicesController = ItemBaseController.extend({ - items: Ember.computed.alias("services"), -}); - -App.AclsController = Ember.ArrayController.extend({ - needs: ["dc", "application"], - queryParams: ["filter"], - filterText: "Filter by name or ID", - searchBar: true, - newAclButton: true, - types: ["client", "management"], - - dc: Ember.computed.alias("controllers.dc"), - items: Ember.computed.alias("acls"), - - filter: "", - - isShowingItem: function() { - var currentPath = this.get('controllers.application.currentPath'); - return (currentPath === "dc.acls.show"); - }.property('controllers.application.currentPath'), - - filteredContent: function() { - var filter = this.get('filter'); - - var items = this.get('items').filter(function(item, index, enumerable){ - // First try to match on the name - var nameMatch = item.get('Name').toLowerCase().match(filter.toLowerCase()); - if (nameMatch !== null) { - return nameMatch; - } else { - return item.get('ID').toLowerCase().match(filter.toLowerCase()); - } - }); - - return items; - }.property('filter', 'items.@each'), - - actions: { - createAcl: function() { - this.set('isLoading', true); - - var controller = this; - var newAcl = controller.get('newAcl'); - var dc = controller.get('dc').get('datacenter'); - var token = App.get('settings.token'); - - // Create the ACL - Ember.$.ajax({ - url: formatUrl(consulHost + '/v1/acl/create', dc, token), - type: 'PUT', - data: JSON.stringify(newAcl) - }).then(function(response) { - // transition to the acl - controller.transitionToRoute('acls.show', response.ID); - - // Get the ACL again, including the newly created one - Ember.$.getJSON(formatUrl(consulHost + '/v1/acl/list', dc, token)).then(function(data) { - var objs = []; - data.map(function(obj){ - objs.push(App.Acl.create(obj)); - }); - controller.set('items', objs); - }); - - controller.set('isLoading', false); - }).fail(function(response) { - // Render the error message on the form if the request failed - notify('Received error while creating ACL: ' + response.statusText, 8000); - controller.set('isLoading', false); - }); - }, - } -}); - - -App.AclsShowController = Ember.ObjectController.extend({ - needs: ["dc", "acls"], - dc: Ember.computed.alias("controllers.dc"), - isLoading: false, - types: ["client", "management"], - - actions: { - set: function() { - this.set('isLoading', true); - var controller = this; - var acl = controller.get('model'); - var dc = controller.get('dc').get('datacenter'); - - if (window.confirm("Are you sure you want to use this token for your session?")) { - // Set - var token = App.set('settings.token', acl.ID); - controller.transitionToRoute('services'); - this.set('isLoading', false); - notify('Now using token: ' + acl.ID, 3000); - } - }, - - clone: function() { - this.set('isLoading', true); - var controller = this; - var acl = controller.get('model'); - var dc = controller.get('dc').get('datacenter'); - var token = App.get('settings.token'); - - // Set - controller.transitionToRoute('services'); - - Ember.$.ajax({ - url: formatUrl(consulHost + '/v1/acl/clone/'+ acl.ID, dc, token), - type: 'PUT' - }).then(function(response) { - controller.transitionToRoute('acls.show', response.ID); - controller.set('isLoading', false); - notify('Successfully cloned token', 4000); - }).fail(function(response) { - // Render the error message on the form if the request failed - controller.set('errorMessage', 'Received error while processing: ' + response.statusText); - controller.set('isLoading', false); - }); - - }, - - delete: function() { - this.set('isLoading', true); - var controller = this; - var acl = controller.get('model'); - var dc = controller.get('dc').get('datacenter'); - var token = App.get('settings.token'); - - if (window.confirm("Are you sure you want to delete this token?")) { - Ember.$.ajax({ - url: formatUrl(consulHost + '/v1/acl/destroy/'+ acl.ID, dc, token), - type: 'PUT' - }).then(function(response) { - Ember.$.getJSON(formatUrl(consulHost + '/v1/acl/list', dc, token)).then(function(data) { - objs = []; - data.map(function(obj){ - if (obj.ID === "anonymous") { - objs.unshift(App.Acl.create(obj)); - } else { - objs.push(App.Acl.create(obj)); - } - }); - controller.get('controllers.acls').set('acls', objs); - }).then(function() { - controller.transitionToRoute('acls'); - controller.set('isLoading', false); - notify('ACL deleted successfully', 3000); - }); - }).fail(function(response) { - // Render the error message on the form if the request failed - controller.set('errorMessage', 'Received error while processing: ' + response.statusText); - controller.set('isLoading', false); - }); - } - }, - - updateAcl: function() { - this.set('isLoading', true); - - var controller = this; - var acl = controller.get('model'); - var dc = controller.get('dc').get('datacenter'); - var token = App.get('settings.token'); - - // Update the ACL - Ember.$.ajax({ - url: formatUrl(consulHost + '/v1/acl/update', dc, token), - type: 'PUT', - data: JSON.stringify(acl) - }).then(function(response) { - // transition to the acl - controller.set('isLoading', false); - notify('ACL updated successfully', 3000); - }).fail(function(response) { - // Render the error message on the form if the request failed - notify('Received error while updating ACL: ' + response.statusText, 8000); - controller.set('isLoading', false); - }); - } - } -}); - -App.SettingsController = Ember.ObjectController.extend({ - actions: { - reset: function() { - this.set('isLoading', true); - var controller = this; - - if (window.confirm("Are your sure you want to reset your settings?")) { - localStorage.clear(); - controller.set('content', App.Settings.create()); - App.set('settings.token', ''); - notify('Settings reset', 3000); - this.set('isLoading', false); - } - }, - - close: function() { - this.transitionToRoute('index'); - } - } -}); - -App.ErrorController = Ember.ObjectController.extend({ - actions: { - resetToken: function() { - App.set('settings.token', ''); - this.transitionToRoute('settings'); - }, - - backHome: function() { - this.transitionToRoute('index'); - } - } -}); - diff --git a/ui/javascripts/app/helpers.js b/ui/javascripts/app/helpers.js deleted file mode 100644 index 95da9f876a85..000000000000 --- a/ui/javascripts/app/helpers.js +++ /dev/null @@ -1,181 +0,0 @@ -Ember.Handlebars.helper('panelBar', function(status) { - var highlightClass; - - if (status == "passing") { - highlightClass = "bg-green"; - } else { - highlightClass = "bg-orange"; - } - return new Handlebars.SafeString('
'); -}); - -Ember.Handlebars.helper('listBar', function(status) { - var highlightClass; - - if (status == "passing") { - highlightClass = "bg-green"; - } else { - highlightClass = "bg-orange"; - } - return new Handlebars.SafeString('
'); -}); - -Ember.Handlebars.helper('sessionName', function(session) { - var name; - - if (session.Name === "") { - name = '' + Handlebars.Utils.escapeExpression(session.ID) + ''; - } else { - name = '' + Handlebars.Utils.escapeExpression(session.Name) + '' + ' ' + Handlebars.Utils.escapeExpression(session.ID) + ''; - } - - return new Handlebars.SafeString(name); -}); - -Ember.Handlebars.helper('sessionMeta', function(session) { - var meta = '
' + Handlebars.Utils.escapeExpression(session.Behavior) + ' behavior
'; - - if (session.TTL !== "") { - meta = meta + '
, ' + Handlebars.Utils.escapeExpression(session.TTL) + ' TTL
'; - } - - return new Handlebars.SafeString(meta); -}); - -Ember.Handlebars.helper('aclName', function(name, id) { - if (name === "") { - return id; - } else { - return new Handlebars.SafeString(Handlebars.Utils.escapeExpression(name) + ' ' + Handlebars.Utils.escapeExpression(id) + ''); - } -}); - -Ember.Handlebars.helper('formatRules', function(rules) { - if (rules === "") { - return "No rules defined"; - } else { - return rules; - } -}); - -Ember.Handlebars.helper('limit', function(str, limit) { - if (str.length > limit) - return str.substring(0, limit) + '...'; - return str; -}); - -// We need to do this because of our global namespace properties. The -// service.Tags -Ember.Handlebars.helper('serviceTagMessage', function(tags) { - if (tags === null) { - return "No tags"; - } -}); - - -// Sends a new notification to the UI -function notify(message, ttl) { - if (window.notifications !== undefined && window.notifications.length > 0) { - $(window.notifications).each(function(i, v) { - v.dismiss(); - }); - } - var notification = new NotificationFx({ - message : '

'+ message + '

', - layout : 'growl', - effect : 'slide', - type : 'notice', - ttl: ttl, - }); - - // show the notification - notification.show(); - - // Add the notification to the queue to be closed - window.notifications = []; - window.notifications.push(notification); -} - -// Tomography - -// TODO: not sure how to how do to this more Ember.js-y -function tomographyMouseOver(el) { - var buf = el.getAttribute('data-node') + ' - ' + el.getAttribute('data-distance') + 'ms'; - var segment = el.getAttribute('data-segment'); - if (segment !== "") { - buf += ' (Segment: ' + segment + ')'; - } - document.getElementById('tomography-node-info').textContent = buf; - -} - -Ember.Handlebars.helper('tomographyGraph', function(tomography, size) { - - // This is ugly, but I'm working around bugs with Handlebars and templating - // parts of svgs. Basically things render correctly the first time, but when - // stuff is updated for subsequent go arounds the templated parts don't show. - // It appears (based on google searches) that the replaced elements aren't - // being interpreted as http://www.w3.org/2000/svg. Anyway, this works and - // if/when Handlebars fixes the underlying issues all of this can be cleaned - // up drastically. - - var max = -999999999; - tomography.distances.forEach(function (d, i) { - if (d.distance > max) { - max = d.distance; - } - }); - var insetSize = size / 2 - 8; - var buf = '' + -' ' + -' ' + -' ' + -' ' + -' ' + -' ' + -' ' + -' ' + -' ' + -' '; - var distances = tomography.distances; - var n = distances.length; - if (tomography.n > 360) { - // We have more nodes than we want to show, take a random sampling to keep - // the number around 360. - var sampling = 360 / tomography.n; - distances = distances.filter(function (_, i) { - return i == 0 || i == n - 1 || Math.random() < sampling - }); - // Re-set n to the filtered size - n = distances.length; - } - distances.forEach(function (d, i) { - buf += ' '; - }); - buf += '' + -' ' + -' ' + -' ' + -' ' + -' ' + -' ' + (max > 0 ? (parseInt(max * 25) / 100) : 0) + 'ms' + -' ' + -' ' + -' ' + -' ' + (max > 0 ? (parseInt(max * 50) / 100) : 0)+ 'ms' + -' ' + -' ' + -' ' + -' ' + (max > 0 ? (parseInt(max * 75) / 100) : 0) + 'ms' + -' ' + -' ' + -' ' + -' ' + (max > 0 ? (parseInt(max * 100) / 100) : 0) + 'ms' + -' ' + -' ' + -' ' + -' '; - - return new Handlebars.SafeString(buf); -}); diff --git a/ui/javascripts/app/mixins.js b/ui/javascripts/app/mixins.js deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/ui/javascripts/app/models.js b/ui/javascripts/app/models.js deleted file mode 100644 index e8521b9b37c8..000000000000 --- a/ui/javascripts/app/models.js +++ /dev/null @@ -1,314 +0,0 @@ -// -// A Consul service. -// -App.Service = Ember.Object.extend({ - // - // The number of failing checks within the service. - // - failingChecks: function() { - // If the service was returned from `/v1/internal/ui/services` - // then we have a aggregated value which we can just grab - if (this.get('ChecksCritical') !== undefined) { - return (this.get('ChecksCritical') + this.get('ChecksWarning')); - // Otherwise, we need to filter the child checks by both failing - // states - } else { - var checks = this.get('Checks'); - return (checks.filterBy('Status', 'critical').get('length') + - checks.filterBy('Status', 'warning').get('length')); - } - }.property('Checks'), - - // - // The number of passing checks within the service. - // - passingChecks: function() { - // If the service was returned from `/v1/internal/ui/services` - // then we have a aggregated value which we can just grab - if (this.get('ChecksPassing') !== undefined) { - return this.get('ChecksPassing'); - // Otherwise, we need to filter the child checks by both failing - // states - } else { - return this.get('Checks').filterBy('Status', 'passing').get('length'); - } - }.property('Checks'), - - // - // The formatted message returned for the user which represents the - // number of checks failing or passing. Returns `1 passing` or `2 failing` - // - checkMessage: function() { - if (this.get('hasFailingChecks') === false) { - return this.get('passingChecks') + ' passing'; - } else { - return this.get('failingChecks') + ' failing'; - } - }.property('Checks'), - - nodes: function() { - return (this.get('Nodes')); - }.property('Nodes'), - - // - // Boolean of whether or not there are failing checks in the service. - // This is used to set color backgrounds and so on. - // - hasFailingChecks: Ember.computed.gt('failingChecks', 0), - - // - // Key used for filtering through an array of this model, i.e s - // searching - // - filterKey: Ember.computed.alias('Name'), -}); - -// -// A Consul Node -// -App.Node = Ember.Object.extend({ - // - // The number of failing checks within the service. - // - failingChecks: function() { - return this.get('Checks').reduce(function(sum, check) { - var status = Ember.get(check, 'Status'); - // We view both warning and critical as failing - return (status === 'critical' || status === 'warning') ? - sum + 1 : - sum; - }, 0); - }.property('Checks'), - - // - // The number of passing checks within the service. - // - passingChecks: function() { - return this.get('Checks').filterBy('Status', 'passing').get('length'); - }.property('Checks'), - - // - // The formatted message returned for the user which represents the - // number of checks failing or passing. Returns `1 passing` or `2 failing` - // - checkMessage: function() { - if (this.get('hasFailingChecks') === false) { - return this.get('passingChecks') + ' passing'; - } else { - return this.get('failingChecks') + ' failing'; - } - }.property('Checks'), - - // - // Boolean of whether or not there are failing checks in the service. - // This is used to set color backgrounds and so on. - // - hasFailingChecks: Ember.computed.gt('failingChecks', 0), - - // - // The number of services on the node - // - numServices: Ember.computed.alias('Services.length'), - - services: Ember.computed.alias('Services'), - - filterKey: Ember.computed.alias('Node') -}); - - -// -// A key/value object -// -App.Key = Ember.Object.extend(Ember.Validations.Mixin, { - // Validates using the Ember.Validations library - validations: { - Key: { presence: true } - }, - - // Boolean if field should validate JSON - validateJson: false, - // Boolean if the key is valid - keyValid: Ember.computed.empty('errors.Key'), - // Boolean if the value is valid - valueValid: Ember.computed.empty('errors.Value'), - - // Escape any user-entered parts that aren't URL-safe, but put slashes back since - // they are common in keys, and the UI lets users make "folders" by simply adding - // them to keys. - Key: function(key, value) { - // setter - if (arguments.length > 1) { - clean = value - try { - clean = decodeURIComponent(clean); - } catch (e) { - // If they've got something that's not valid URL syntax then keep going; - // this means that at worst we might end up double escaping some things. - } - clean = encodeURIComponent(clean).replace(/%2F/g, "/") - this.set('cleanKey', clean); - return clean; - } - - // getter - return this.get('cleanKey') - }.property('Key'), - - // The key with the parent removed. - // This is only for display purposes, and used for - // showing the key name inside of a nested key. - keyWithoutParent: function() { - return (this.get('Key').replace(this.get('parentKey'), '')); - }.property('Key'), - - // Boolean if the key is a "folder" or not, i.e is a nested key - // that feels like a folder. Used for UI - isFolder: function() { - if (this.get('Key') === undefined) { - return false; - } - return (this.get('Key').slice(-1) === '/'); - }.property('Key'), - - // Boolean if the key is locked or now - isLocked: function() { - if (!this.get('Session')) { - return false; - } else { - return true; - } - }.property('Session'), - - // Determines what route to link to. If it's a folder, - // it will link to kv.show. Otherwise, kv.edit - linkToRoute: function() { - if (this.get('Key').slice(-1) === '/') { - return 'kv.show'; - } else { - return 'kv.edit'; - } - }.property('Key'), - - // The base64 decoded value of the key. - // if you set on this key, it will update - // the key.Value - valueDecoded: function(key, value) { - - // setter - if (arguments.length > 1) { - this.set('Value', value); - return value; - } - - // getter - - // If the value is null, we don't - // want to try and base64 decode it, so just return - if (this.get('Value') === null) { - return ""; - } - if (Base64.extendString) { - // you have to explicitly extend String.prototype - Base64.extendString(); - } - // base64 decode the value - return (this.get('Value').fromBase64()); - }.property('Value'), - - // Check if JSON is valid by attempting a native JSON parse - isValidJson: function() { - var value; - - try { - window.atob(this.get('Value')); - value = this.get('valueDecoded'); - } catch (e) { - value = this.get('Value'); - } - - try { - JSON.parse(value); - return true; - } catch (e) { - return false; - } - }.property('Value'), - - // An array of the key broken up by the / - keyParts: function() { - var key = this.get('Key'); - - // If the key is a folder, remove the last - // slash to split properly - if (key.slice(-1) == "/") { - key = key.substring(0, key.length - 1); - } - - return key.split('/'); - }.property('Key'), - - // The parent Key is the key one level above this.Key - // key: baz/bar/foobar/ - // grandParent: baz/bar/ - parentKey: function() { - var parts = this.get('keyParts').toArray(); - - // Remove the last item, essentially going up a level - // in hierarchy - parts.pop(); - - return parts.join("/") + "/"; - }.property('Key'), - - // The grandParent Key is the key two levels above this.Key - // key: baz/bar/foobar/ - // grandParent: baz/ - grandParentKey: function() { - var parts = this.get('keyParts').toArray(); - - // Remove the last two items, jumping two levels back - parts.pop(); - parts.pop(); - - return parts.join("/") + "/"; - }.property('Key') -}); - -// -// An ACL -// -App.Acl = Ember.Object.extend({ - isNotAnon: function() { - if (this.get('ID') === "anonymous"){ - return false; - } else { - return true; - } - }.property('ID') -}); - -// Wrap localstorage with an ember object -App.Settings = Ember.Object.extend({ - unknownProperty: function(key) { - return localStorage[key]; - }, - - setUnknownProperty: function(key, value) { - if(Ember.isNone(value)) { - delete localStorage[key]; - } else { - localStorage[key] = value; - } - this.notifyPropertyChange(key); - return value; - }, - - clear: function() { - this.beginPropertyChanges(); - for (var i=0, l=localStorage.length; i 0) { - parts.pop(); - parentKey = parts.join("/") + "/"; - } - - if (parts.length > 1) { - parts.pop(); - grandParentKey = parts.join("/") + "/"; - } - - return { - parent: parentKey, - grandParent: grandParentKey, - isRoot: parentKey === '/' - }; - }, - - removeDuplicateKeys: function(keys, matcher) { - // Loop over the keys - keys.forEach(function(item, index) { - if (item.get('Key') == matcher) { - // If we are in a nested folder and the folder - // name matches our position, remove it - keys.splice(index, 1); - } - }); - return keys; - }, - - actions: { - // Used to link to keys that are not objects, - // like parents and grandParents - linkToKey: function(key) { - if (key == "/") { - this.transitionTo('kv.show', ""); - } - else if (key.slice(-1) === '/' || key === this.rootKey) { - this.transitionTo('kv.show', key); - } else { - this.transitionTo('kv.edit', key); - } - } - } -}); - -// -// The route for choosing datacenters, typically the first route loaded. -// -App.IndexRoute = App.BaseRoute.extend({ - // Retrieve the list of datacenters - model: function(params) { - return Ember.$.getJSON(consulHost + '/v1/catalog/datacenters').then(function(data) { - return data; - }); - }, - - afterModel: function(model, transition) { - // If we only have one datacenter, jump - // straight to it and bypass the global - // view - if (model.get('length') === 1) { - this.transitionTo('services', model[0]); - } - } -}); - -// The parent route for all resources. This keeps the top bar -// functioning, as well as the per-dc requests. -App.DcRoute = App.BaseRoute.extend({ - model: function(params) { - var token = App.get('settings.token'); - - // Return a promise hash to retrieve the - // dcs and nodes used in the header - return Ember.RSVP.hash({ - dc: params.dc, - dcs: Ember.$.getJSON(consulHost + '/v1/catalog/datacenters'), - nodes: Ember.$.getJSON(formatUrl(consulHost + '/v1/internal/ui/nodes', params.dc, token)).then(function(data) { - var objs = []; - - // Merge the nodes into a list and create objects out of them - data.map(function(obj){ - objs.push(App.Node.create(obj)); - }); - - return objs; - }), - coordinates: Ember.$.getJSON(formatUrl(consulHost + '/v1/coordinate/nodes', params.dc, token)).then(function(data) { - return data; - }) - }); - }, - - setupController: function(controller, models) { - controller.set('content', models.dc); - controller.set('nodes', models.nodes); - controller.set('dcs', models.dcs); - controller.set('coordinates', models.coordinates); - controller.set('isDropdownVisible', false); - }, -}); - -App.KvIndexRoute = App.BaseRoute.extend({ - beforeModel: function() { - this.transitionTo('kv.show', this.rootKey); - } -}); - -App.KvShowRoute = App.BaseRoute.extend({ - model: function(params) { - var key = params.key; - var dc = this.modelFor('dc').dc; - var token = App.get('settings.token'); - - // Return a promise has with the ?keys for that namespace - // and the original key requested in params - return Ember.RSVP.hash({ - key: key, - keys: Ember.$.getJSON(formatUrl(consulHost + '/v1/kv/' + key + '?keys&seperator=/', dc, token)).then(function(data) { - var objs = []; - data.map(function(obj){ - objs.push(App.Key.create({Key: obj})); - }); - return objs; - }) - }); - }, - - setupController: function(controller, models) { - var key = models.key; - var parentKeys = this.getParentAndGrandparent(key); - models.keys = this.removeDuplicateKeys(models.keys, models.key); - - controller.set('content', models.keys); - controller.set('parentKey', parentKeys.parent); - controller.set('grandParentKey', parentKeys.grandParent); - controller.set('isRoot', parentKeys.isRoot); - controller.set('newKey', App.Key.create()); - controller.set('rootKey', this.rootKey); - } -}); - -App.KvEditRoute = App.BaseRoute.extend({ - model: function(params) { - var key = params.key; - var dc = this.modelFor('dc').dc; - var parentKeys = this.getParentAndGrandparent(key); - var token = App.get('settings.token'); - - // Return a promise hash to get the data for both columns - return Ember.RSVP.hash({ - dc: dc, - token: token, - key: Ember.$.getJSON(formatUrl(consulHost + '/v1/kv/' + key, dc, token)).then(function(data) { - // Convert the returned data to a Key - return App.Key.create().setProperties(data[0]); - }), - keys: keysPromise = Ember.$.getJSON(formatUrl(consulHost + '/v1/kv/' + parentKeys.parent + '?keys&seperator=/', dc, token)).then(function(data) { - var objs = []; - data.map(function(obj){ - objs.push(App.Key.create({Key: obj})); - }); - return objs; - }), - }); - }, - - // Load the session on the key, if there is one - afterModel: function(models) { - if (models.key.get('isLocked')) { - return Ember.$.getJSON(formatUrl(consulHost + '/v1/session/info/' + models.key.Session, models.dc, models.token)).then(function(data) { - models.session = data[0]; - return models; - }); - } else { - return models; - } - }, - - setupController: function(controller, models) { - var key = models.key; - var parentKeys = this.getParentAndGrandparent(key.get('Key')); - models.keys = this.removeDuplicateKeys(models.keys, parentKeys.parent); - - controller.set('content', models.key); - controller.set('parentKey', parentKeys.parent); - controller.set('grandParentKey', parentKeys.grandParent); - controller.set('isRoot', parentKeys.isRoot); - controller.set('siblings', models.keys); - controller.set('rootKey', this.rootKey); - controller.set('session', models.session); - } -}); - -App.ServicesRoute = App.BaseRoute.extend({ - model: function(params) { - var dc = this.modelFor('dc').dc; - var token = App.get('settings.token'); - - // Return a promise to retrieve all of the services - return Ember.$.getJSON(formatUrl(consulHost + '/v1/internal/ui/services', dc, token)).then(function(data) { - var objs = []; - data.map(function(obj){ - objs.push(App.Service.create(obj)); - }); - return objs; - }); - }, - setupController: function(controller, model) { - controller.set('services', model); - } -}); - - -App.ServicesShowRoute = App.BaseRoute.extend({ - model: function(params) { - var dc = this.modelFor('dc').dc; - var token = App.get('settings.token'); - - // Here we just use the built-in health endpoint, as it gives us everything - // we need. - return Ember.$.getJSON(formatUrl(consulHost + '/v1/health/service/' + params.name, dc, token)).then(function(data) { - var objs = []; - data.map(function(obj){ - objs.push(App.Node.create(obj)); - }); - return objs; - }); - }, - setupController: function(controller, model) { - var tags = []; - model.map(function(obj){ - if (obj.Service.Tags !== null) { - tags = tags.concat(obj.Service.Tags); - } - }); - - tags = tags.filter(function(n){ return n !== undefined; }); - tags = tags.uniq().join(', '); - - controller.set('content', model); - controller.set('tags', tags); - } -}); - -function distance(a, b) { - a = a.Coord; - b = b.Coord; - var sum = 0; - for (var i = 0; i < a.Vec.length; i++) { - var diff = a.Vec[i] - b.Vec[i]; - sum += diff * diff; - } - var rtt = Math.sqrt(sum) + a.Height + b.Height; - - var adjusted = rtt + a.Adjustment + b.Adjustment; - if (adjusted > 0.0) { - rtt = adjusted; - } - - return Math.round(rtt * 100000.0) / 100.0; -} - -App.NodesShowRoute = App.BaseRoute.extend({ - model: function(params) { - var dc = this.modelFor('dc'); - var token = App.get('settings.token'); - - var min = 999999999; - var max = -999999999; - var sum = 0; - var distances = []; - dc.coordinates.forEach(function (node) { - if (params.name == node.Node) { - var segment = node.Segment; - dc.coordinates.forEach(function (other) { - if (node.Node != other.Node && other.Segment == segment) { - var dist = distance(node, other); - distances.push({ node: other.Node, distance: dist, segment: segment }); - sum += dist; - if (dist < min) { - min = dist; - } - if (dist > max) { - max = dist; - } - } - }); - distances.sort(function (a, b) { - return a.distance - b.distance; - }); - } - }); - var n = distances.length; - var halfN = Math.floor(n / 2); - var median; - - if (n > 0) { - if (n % 2) { - // odd - median = distances[halfN].distance; - } else { - median = (distances[halfN - 1].distance + distances[halfN].distance) / 2; - } - } else { - median = 0; - min = 0; - max = 0; - } - - // Return a promise hash of the node - return Ember.RSVP.hash({ - dc: dc.dc, - token: token, - tomography: { - distances: distances, - n: distances.length, - min: parseInt(min * 100) / 100, - median: parseInt(median * 100) / 100, - max: parseInt(max * 100) / 100 - }, - node: Ember.$.getJSON(formatUrl(consulHost + '/v1/internal/ui/node/' + params.name, dc.dc, token)).then(function(data) { - return App.Node.create(data); - }) - }); - }, - - // Load the sessions for the node - afterModel: function(models) { - return Ember.$.getJSON(formatUrl(consulHost + '/v1/session/node/' + models.node.Node, models.dc, models.token)).then(function(data) { - models.sessions = data; - return models; - }); - }, - - setupController: function(controller, models) { - controller.set('content', models.node); - controller.set('sessions', models.sessions); - controller.set('tomography', models.tomography); - } -}); - -App.NodesRoute = App.BaseRoute.extend({ - model: function(params) { - var dc = this.modelFor('dc').dc; - var token = App.get('settings.token'); - - // Return a promise containing the nodes - return Ember.$.getJSON(formatUrl(consulHost + '/v1/internal/ui/nodes', dc, token)).then(function(data) { - var objs = []; - data.map(function(obj){ - objs.push(App.Node.create(obj)); - }); - return objs; - }); - }, - setupController: function(controller, model) { - controller.set('nodes', model); - } -}); - - -App.AclsRoute = App.BaseRoute.extend({ - model: function(params) { - var dc = this.modelFor('dc').dc; - var token = App.get('settings.token'); - // Return a promise containing the ACLS - return Ember.$.getJSON(formatUrl(consulHost + '/v1/acl/list', dc, token)).then(function(data) { - var objs = []; - data.map(function(obj){ - if (obj.ID === "anonymous") { - objs.unshift(App.Acl.create(obj)); - } else { - objs.push(App.Acl.create(obj)); - } - }); - return objs; - }); - }, - - actions: { - error: function(error, transition) { - // If consul returns 401, ACLs are disabled - if (error && error.status === 401) { - this.transitionTo('dc.aclsdisabled'); - // If consul returns 403, they key isn't authorized for that - // action. - } else if (error && error.status === 403) { - this.transitionTo('dc.unauthorized'); - } - return true; - } - }, - - setupController: function(controller, model) { - controller.set('acls', model); - controller.set('newAcl', App.Acl.create()); - } -}); - -App.AclsShowRoute = App.BaseRoute.extend({ - model: function(params) { - var dc = this.modelFor('dc').dc; - var token = App.get('settings.token'); - - // Return a promise hash of the ACLs - return Ember.RSVP.hash({ - dc: dc, - acl: Ember.$.getJSON(formatUrl(consulHost + '/v1/acl/info/'+ params.id, dc, token)).then(function(data) { - return App.Acl.create(data[0]); - }) - }); - }, - - setupController: function(controller, models) { - controller.set('content', models.acl); - } -}); - -App.SettingsRoute = App.BaseRoute.extend({ - model: function(params) { - return App.get('settings'); - } -}); - - -// Adds any global parameters we need to set to a url/path -function formatUrl(url, dc, token) { - if (token == null) { - token = ""; - } - if (url.indexOf("?") > 0) { - // If our url has existing params - url = url + "&dc=" + dc; - url = url + "&token=" + token; - } else { - // Our url doesn't have params - url = url + "?dc=" + dc; - url = url + "&token=" + token; - } - return url; -} diff --git a/ui/javascripts/app/views.js b/ui/javascripts/app/views.js deleted file mode 100644 index b111efccbf91..000000000000 --- a/ui/javascripts/app/views.js +++ /dev/null @@ -1,81 +0,0 @@ - -// -// DC -// - -App.DcView = Ember.View.extend({ - templateName: 'dc', - classNames: 'dropdowns', - - click: function(e){ - if ($(e.target).is('.dropdowns')){ - $('ul.dropdown-menu').hide(); - } - } -}); - - -App.ItemView = Ember.View.extend({ - templateName: 'item' -}); - -// -// Services -// -App.ServicesView = Ember.View.extend({ - templateName: 'services', -}); - -App.ServicesShowView = Ember.View.extend({ - templateName: 'service' -}); - -App.ServicesLoadingView = Ember.View.extend({ - templateName: 'item/loading' -}); - -// -// Nodes -// - -App.NodesView = Ember.View.extend({ - templateName: 'nodes' -}); - -App.NodesShowView = Ember.View.extend({ - templateName: 'node' -}); - -App.NodesLoadingView = Ember.View.extend({ - templateName: 'item/loading' -}); - - -// KV - -App.KvListView = Ember.View.extend({ - templateName: 'kv' -}); - -// Actions - -App.ActionBarView = Ember.View.extend({ - templateName: 'actionbar' -}); - -// ACLS - -App.AclView = Ember.View.extend({ - templateName: 'acls', -}); - -App.AclsShowView = Ember.View.extend({ - templateName: 'acl' -}); - - -// Settings - -App.SettingsView = Ember.View.extend({ - templateName: 'settings', -}); diff --git a/ui/javascripts/fixtures.js b/ui/javascripts/fixtures.js deleted file mode 100644 index 3c3f1b87eb03..000000000000 --- a/ui/javascripts/fixtures.js +++ /dev/null @@ -1,317 +0,0 @@ -// -// I intentionally am not using ember-data and the fixture -// adapter. I'm not confident the Consul UI API will be compatible -// without a bunch of wrangling, and it's really not enough updating -// of the models to justify the use of such a big component. getJSON -// *should* be enough. -// - -window.fixtures = {} - -// -// The array route, i.e /ui//services, should return _all_ services -// in the DC -// -fixtures.services = [ - { - "Name": "vagrant-cloud-http", - "Checks": [ - { - "Name": "serfHealth", - "Status": "passing" - }, - { - "Name": "fooHealth", - "Status": "critical" - }, - { - "Name": "bazHealth", - "Status": "passing" - } - ], - "Nodes": [ - "node-10-0-1-109", - "node-10-0-1-102" - ] - }, - { - "Name": "vagrant-share-mux", - "Checks": [ - { - "Name": "serfHealth", - "Status": "critical" - }, - { - "Name": "fooHealth", - "Status": "passing" - }, - { - "Name": "bazHealth", - "Status": "passing" - } - ], - "Nodes": [ - "node-10-0-1-109", - "node-10-0-1-102" - ] - }, -] - -// -// This one is slightly more complicated to allow more UI interaction. -// It represents the route /ui//services/ BUT it's what is -// BELOW the top-level key. -// -// So, what is actually returned should be similar to the /catalog/service/ -// endpoint. -fixtures.services_full = { - "vagrant-cloud-http": - // This array is what is actually expected from the API. - [ - { - "ServicePort": 80, - "ServiceTags": null, - "ServiceName": "vagrant-cloud-http", - "ServiceID": "vagrant-cloud-http", - "Address": "10.0.1.109", - "Node": "node-10-0-1-109", - "Checks": [ - { - "ServiceName": "", - "ServiceID": "", - "Notes": "", - "Status": "critical", - "Name": "Serf Health Status", - "CheckID": "serfHealth", - "Node": "node-10-0-1-109" - } - ] - }, - // A node - { - "ServicePort": 80, - "ServiceTags": null, - "ServiceName": "vagrant-cloud-http", - "ServiceID": "vagrant-cloud-http", - "Address": "10.0.1.102", - "Node": "node-10-0-1-102", - "Checks": [ - { - "ServiceName": "", - "ServiceID": "", - "Notes": "", - "Status": "passing", - "Name": "Serf Health Status", - "CheckID": "serfHealth", - "Node": "node-10-0-1-102" - } - ] - } - ], - "vagrant-share-mux": [ - // A node - { - "ServicePort": 80, - "ServiceTags": null, - "ServiceName": "vagrant-share-mux", - "ServiceID": "vagrant-share-mux", - "Address": "10.0.1.102", - "Node": "node-10-0-1-102", - "Checks": [ - { - "ServiceName": "vagrant-share-mux", - "ServiceID": "vagrant-share-mux", - "Notes": "", - "Output": "200 ok", - "Status": "passing", - "Name": "Foo Healthy", - "CheckID": "fooHealth", - "Node": "node-10-0-1-102" - } - ] - }, - // A node - { - "ServicePort": 80, - "ServiceTags": null, - "ServiceName": "vagrant-share-mux", - "ServiceID": "vagrant-share-mux", - "Address": "10.0.1.109", - "Node": "node-10-0-1-109", - "Checks": [ - { - "ServiceName": "", - "ServiceID": "", - "Notes": "", - "Output": "foobar baz", - "Status": "passing", - "Name": "Baz Status", - "CheckID": "bazHealth", - "Node": "node-10-0-1-109" - }, - { - "ServiceName": "", - "ServiceID": "", - "Notes": "", - "Output": "foobar baz", - "Status": "critical", - "Name": "Serf Health Status", - "CheckID": "serfHealth", - "Node": "node-10-0-1-109" - } - ] - } - ] -} - -// -// /ui//nodes -// all the nodes -// -fixtures.nodes = [ - { - "Address": "10.0.1.109", - "Name": "node-10-0-1-109", - "Services": [ - "vagrant-share-mux", - "vagrant-cloud-http" - ], - "Checks": [ - { - "Name": "serfHealth", - "Status": "critical" - }, - { - "Name": "bazHealth", - "Status": "passing" - } - ] - }, - { - "Address": "10.0.1.102", - "Name": "node-10-0-1-102", - "Services": [ - "vagrant-share-mux", - "vagrant-cloud-http" - ], - "Checks": [ - { - "Name": "fooHealth", - "Status": "passing" - } - ], - } -] - -// These are for retrieving individual nodes. Same story as services, -// the top level key is just for the demo. -fixtures.nodes_full = { - "node-10-0-1-109": - // This is what would be returned. - { - "Services": [ - { - "Port": 0, - "Tags": null, - "Service": "vagrant-share-mux", - "ID": "vagrant-share-mux" - }, - { - "Port": 80, - "Tags": null, - "Service": "vagrant-cloud-http", - "ID": "vagrant-cloud-http" - } - ], - "Node": { - "Address": "10.0.1.109", - "Node": "node-10-0-1-109" - }, - "Checks": [ - { - "ServiceName": "", - "ServiceID": "", - "Notes": "Checks the status of the serf agent", - "Status": "critical", - "Name": "Serf Health Status", - "CheckID": "serfHealth", - "Node": "node-10-0-1-109" - }, - { - "ServiceName": "", - "ServiceID": "", - "Notes": "", - "Output": "foobar baz", - "Status": "passing", - "Name": "Baz Status", - "CheckID": "bazHealth", - "Node": "node-10-0-1-109" - } - ] - }, - "node-10-0-1-102": { - "Services": [ - { - "Port": 0, - "Tags": null, - "Service": "vagrant-share-mux", - "ID": "vagrant-share-mux" - }, - { - "Port": 80, - "Tags": null, - "Service": "vagrant-cloud-http", - "ID": "vagrant-cloud-http" - } - ], - "Node": { - "Address": "10.0.1.102", - "Node": "node-10-0-1-102" - }, - "Checks": [ - { - "ServiceName": "", - "ServiceID": "", - "Notes": "Checks if the food is healthy", - "Output": "foobar baz", - "Status": "passing", - "Name": "Foo Healthy", - "CheckID": "fooStatus", - "Node": "node-10-0-1-102" - } - ] - } -} - -fixtures.dcs = ['nyc1', 'sf1', 'sg1'] - -fixtures.keys_full = { - "/": [ - 'foobar', - 'application', - 'web/' - ], - "application": { - 'key': 'application', - 'value': 'foobarz' - }, - "foobar": { - 'key': 'foobar', - 'value': 'baz' - }, - "web/foo/bar": { - 'key': 'web/foo/bar', - 'value': 'baz' - }, - "web/foo/baz": { - 'key': 'web/foo/baz', - 'value': 'test' - }, - "web/": [ - "web/foo/" - ], - "web/foo/": [ - "web/foo/bar", - "web/foo/baz" - ] -}; diff --git a/ui/javascripts/libs/base64.min.js b/ui/javascripts/libs/base64.min.js deleted file mode 100644 index b2f13773f7b2..000000000000 --- a/ui/javascripts/libs/base64.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(global){"use strict";var _Base64=global.Base64;var version="2.1.7";var buffer;if(typeof module!=="undefined"&&module.exports){buffer=require("buffer").Buffer}var b64chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64tab=function(bin){var t={};for(var i=0,l=bin.length;i>>6)+fromCharCode(128|cc&63):fromCharCode(224|cc>>>12&15)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}else{var cc=65536+(c.charCodeAt(0)-55296)*1024+(c.charCodeAt(1)-56320);return fromCharCode(240|cc>>>18&7)+fromCharCode(128|cc>>>12&63)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}};var re_utob=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;var utob=function(u){return u.replace(re_utob,cb_utob)};var cb_encode=function(ccc){var padlen=[0,2,1][ccc.length%3],ord=ccc.charCodeAt(0)<<16|(ccc.length>1?ccc.charCodeAt(1):0)<<8|(ccc.length>2?ccc.charCodeAt(2):0),chars=[b64chars.charAt(ord>>>18),b64chars.charAt(ord>>>12&63),padlen>=2?"=":b64chars.charAt(ord>>>6&63),padlen>=1?"=":b64chars.charAt(ord&63)];return chars.join("")};var btoa=global.btoa?function(b){return global.btoa(b)}:function(b){return b.replace(/[\s\S]{1,3}/g,cb_encode)};var _encode=buffer?function(u){return(u.constructor===buffer.constructor?u:new buffer(u)).toString("base64")}:function(u){return btoa(utob(u))};var encode=function(u,urisafe){return!urisafe?_encode(String(u)):_encode(String(u)).replace(/[+\/]/g,function(m0){return m0=="+"?"-":"_"}).replace(/=/g,"")};var encodeURI=function(u){return encode(u,true)};var re_btou=new RegExp(["[À-ß][€-¿]","[à-ï][€-¿]{2}","[ð-÷][€-¿]{3}"].join("|"),"g");var cb_btou=function(cccc){switch(cccc.length){case 4:var cp=(7&cccc.charCodeAt(0))<<18|(63&cccc.charCodeAt(1))<<12|(63&cccc.charCodeAt(2))<<6|63&cccc.charCodeAt(3),offset=cp-65536;return fromCharCode((offset>>>10)+55296)+fromCharCode((offset&1023)+56320);case 3:return fromCharCode((15&cccc.charCodeAt(0))<<12|(63&cccc.charCodeAt(1))<<6|63&cccc.charCodeAt(2));default:return fromCharCode((31&cccc.charCodeAt(0))<<6|63&cccc.charCodeAt(1))}};var btou=function(b){return b.replace(re_btou,cb_btou)};var cb_decode=function(cccc){var len=cccc.length,padlen=len%4,n=(len>0?b64tab[cccc.charAt(0)]<<18:0)|(len>1?b64tab[cccc.charAt(1)]<<12:0)|(len>2?b64tab[cccc.charAt(2)]<<6:0)|(len>3?b64tab[cccc.charAt(3)]:0),chars=[fromCharCode(n>>>16),fromCharCode(n>>>8&255),fromCharCode(n&255)];chars.length-=[0,0,2,1][padlen];return chars.join("")};var atob=global.atob?function(a){return global.atob(a)}:function(a){return a.replace(/[\s\S]{1,4}/g,cb_decode)};var _decode=buffer?function(a){return(a.constructor===buffer.constructor?a:new buffer(a,"base64")).toString()}:function(a){return btou(atob(a))};var decode=function(a){return _decode(String(a).replace(/[-_]/g,function(m0){return m0=="-"?"+":"/"}).replace(/[^A-Za-z0-9\+\/]/g,""))};var noConflict=function(){var Base64=global.Base64;global.Base64=_Base64;return Base64};global.Base64={VERSION:version,atob:atob,btoa:btoa,fromBase64:decode,toBase64:encode,utob:utob,encode:encode,encodeURI:encodeURI,btou:btou,decode:decode,noConflict:noConflict};if(typeof Object.defineProperty==="function"){var noEnum=function(v){return{value:v,enumerable:false,writable:true,configurable:true}};global.Base64.extendString=function(){Object.defineProperty(String.prototype,"fromBase64",noEnum(function(){return decode(this)}));Object.defineProperty(String.prototype,"toBase64",noEnum(function(urisafe){return encode(this,urisafe)}));Object.defineProperty(String.prototype,"toBase64URI",noEnum(function(){return encode(this,true)}))}}})(this);if(this["Meteor"]){Base64=global.Base64} \ No newline at end of file diff --git a/ui/javascripts/libs/classie.js b/ui/javascripts/libs/classie.js deleted file mode 100755 index a70914c4f351..000000000000 --- a/ui/javascripts/libs/classie.js +++ /dev/null @@ -1,80 +0,0 @@ -/*! - * classie - class helper functions - * from bonzo https://github.com/ded/bonzo - * - * classie.has( elem, 'my-class' ) -> true/false - * classie.add( elem, 'my-new-class' ) - * classie.remove( elem, 'my-unwanted-class' ) - * classie.toggle( elem, 'my-class' ) - */ - -/*jshint browser: true, strict: true, undef: true */ -/*global define: false */ - -( function( window ) { - -'use strict'; - -// class helper functions from bonzo https://github.com/ded/bonzo - -function classReg( className ) { - return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); -} - -// classList support for class management -// although to be fair, the api sucks because it won't accept multiple classes at once -var hasClass, addClass, removeClass; - -if ( 'classList' in document.documentElement ) { - hasClass = function( elem, c ) { - return elem.classList.contains( c ); - }; - addClass = function( elem, c ) { - elem.classList.add( c ); - }; - removeClass = function( elem, c ) { - elem.classList.remove( c ); - }; -} -else { - hasClass = function( elem, c ) { - return classReg( c ).test( elem.className ); - }; - addClass = function( elem, c ) { - if ( !hasClass( elem, c ) ) { - elem.className = elem.className + ' ' + c; - } - }; - removeClass = function( elem, c ) { - elem.className = elem.className.replace( classReg( c ), ' ' ); - }; -} - -function toggleClass( elem, c ) { - var fn = hasClass( elem, c ) ? removeClass : addClass; - fn( elem, c ); -} - -var classie = { - // full names - hasClass: hasClass, - addClass: addClass, - removeClass: removeClass, - toggleClass: toggleClass, - // short names - has: hasClass, - add: addClass, - remove: removeClass, - toggle: toggleClass -}; - -// transport -if ( typeof define === 'function' && define.amd ) { - // AMD - define( classie ); -} else { - // browser global - window.classie = classie; -} - -})( window ); diff --git a/ui/javascripts/libs/classie.min.js b/ui/javascripts/libs/classie.min.js deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/ui/javascripts/libs/ember-debug.min.js b/ui/javascripts/libs/ember-debug.min.js deleted file mode 100644 index 316db804bdc2..000000000000 --- a/ui/javascripts/libs/ember-debug.min.js +++ /dev/null @@ -1,679 +0,0 @@ -/*! - * @overview Ember - JavaScript Application Framework - * @copyright Copyright 2011-2014 Tilde Inc. and contributors - * Portions Copyright 2006-2011 Strobe Inc. - * Portions Copyright 2008-2011 Apple Inc. All rights reserved. - * @license Licensed under MIT license - * See https://raw.github.com/emberjs/ember.js/master/LICENSE - * @version 1.7.0-beta.1+canary.3d81867a - */ -(function(){var t,S,ia,ka,D;(function(){D=this.Ember=this.Ember||{};"undefined"===typeof D&&(D={});if("undefined"===typeof D.__loader){var a={},m={};t=function(m,f,l){a[m]={deps:f,callback:l}};ka=ia=S=function(n){function f(b){if("."!==b.charAt(0))return b;b=b.split("/");for(var c=n.split("/").slice(0,-1),a=0,d=b.length;a=q[c]?b=c+2:r=c;return e>=q[b]?b+2:b}a=a["default"];var p=m.DeferredActionQueues,u=[].slice,w=[].pop,s=a.each,q=a.isString,e=a.isFunction,r=a.isNumber,v=[],y=this,A=/\d+/;try{(void 0)()}catch(x){}f.prototype={queueNames:null,options:null,currentInstance:null,instanceStack:null,begin:function(){var e= -this.options,q=e&&e.onBegin,b=this.currentInstance;b&&this.instanceStack.push(b);this.currentInstance=new p(this.queueNames,e);q&&q(this.currentInstance,b)},end:function(){var e=this.options,e=e&&e.onEnd,q=this.currentInstance,b=null;try{q.flush()}finally{this.currentInstance=null,this.instanceStack.length&&(this.currentInstance=b=this.instanceStack.pop()),e&&e(q,b)}},run:function(e,b){var r=this.options.onError||this.options.onErrorTarget&&this.options.onErrorTarget[this.options.onErrorMethod];this.begin(); -b||(b=e,e=null);q(b)&&(b=e[b]);var c=u.call(arguments,2);if(r)try{return b.apply(e,c)}catch(g){r(g)}finally{this.end()}else try{return b.apply(e,c)}finally{this.end()}},defer:function(e,b,r){r||(r=b,b=null);q(r)&&(r=b[r]);var c=this.DEBUG?Error():void 0,g=3q.length)return!1;r=e(q[0],q[1],b);return-1b?(this._queue=a.slice(b),this.flush()):this._queue.length=0},cancel:function(a){var f=this._queue,l,k,d,h;d=0;for(h=f.length;d\s*\(([^\)]+)\)/gm,"{anonymous}($1)").split("\n"),g.shift()):g=g.stack.replace(/(?:\n@:0)?\s+$/m, -"").replace(/^\(/gm,"{anonymous}(").split("\n");h="\n "+g.slice(2).join("\n ");a+=h}k.warn("DEPRECATION: "+a)}};f.deprecateFunc=function(a,b){return function(){f.deprecate(a);return b.apply(this,arguments)}};f.runInDebug=function(a){a()};if(!f.testing){var d="undefined"!==typeof InstallTrigger,h=!!window.chrome&&!window.opera;"undefined"!==typeof window&&((d||h)&&window.addEventListener)&&window.addEventListener("load",function(){if(document.documentElement&&document.documentElement.dataset&& -!document.documentElement.dataset.emberExtension){var a;h?a="https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi":d&&(a="https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/");f.debug("For more advanced debugging, install the Ember Inspector from "+a)}},!1)}});t("ember-extension-support",["ember-metal/core","ember-extension-support/data_adapter","ember-extension-support/container_debug_adapter"],function(a,m,n){a=a["default"];n=n["default"];a.DataAdapter= -m["default"];a.ContainerDebugAdapter=n});t("ember-extension-support/container_debug_adapter","ember-metal/core ember-metal/utils ember-runtime/system/string ember-runtime/system/namespace ember-runtime/system/object exports".split(" "),function(a,m,n,f,l,k){var d=a["default"],h=m.typeOf,c=n.dasherize,b=n.classify,g=f["default"];a=l["default"].extend({container:null,resolver:null,canCatalogEntriesByType:function(b){return"model"===b||"template"===b?!1:!0},catalogEntriesByType:function(a){var f=d.A(g.NAMESPACES), -k=d.A(),s=RegExp(b(a)+"$");f.forEach(function(b){if(b!==d)for(var a in b)b.hasOwnProperty(a)&&s.test(a)&&"class"===h(b[a])&&k.push(c(a.replace(s,"")))});return k}});k["default"]=a});t("ember-extension-support/data_adapter","ember-metal/core ember-metal/property_get ember-metal/run_loop ember-runtime/system/string ember-runtime/system/namespace ember-runtime/system/object ember-runtime/system/native_array ember-application/system/application exports".split(" "),function(a,m,n,f,l,k,d,h,c){var b=a["default"], -g=m.get,p=n["default"],u=f.dasherize,w=l["default"],s=d.A,q=h["default"];c["default"]=k["default"].extend({init:function(){this._super();this.releaseMethods=s()},container:null,containerDebugAdapter:void 0,attributeLimit:3,releaseMethods:s(),getFilters:function(){return s()},watchModelTypes:function(b,a){var c=this.getModelTypes(),g=this,q=s(),c=c.map(function(b){var e=b.klass;b=g.wrapModelType(e,b.name);q.push(g.observeModelType(e,a));return b});b(c);var d=function(){q.forEach(function(b){b()}); -g.releaseMethods.removeObject(d)};this.releaseMethods.pushObject(d);return d},_nameToClass:function(b){"string"===typeof b&&(b=this.container.lookupFactory("model:"+b));return b},watchRecords:function(a,c,g,q){var d=this,p=s(),f=this.getRecords(a),h,k=function(b){g([b])};a=f.map(function(b){p.push(d.observeRecord(b,k));return d.wrapRecord(b)});var u={didChange:function(b,a,e,g){for(var s=a;sarguments.length);return h.helpers.view.call(this,b,a)}};h.helpers=f(d.helpers);h.Compiler=function(){};d.Compiler&&(h.Compiler.prototype=f(d.Compiler.prototype));h.Compiler.prototype.compiler=h.Compiler;h.JavaScriptCompiler=function(){};d.JavaScriptCompiler&&(h.JavaScriptCompiler.prototype=f(d.JavaScriptCompiler.prototype),h.JavaScriptCompiler.prototype.compiler=h.JavaScriptCompiler);h.JavaScriptCompiler.prototype.namespace="Ember.Handlebars";h.JavaScriptCompiler.prototype.initializeBuffer= -function(){return"''"};h.JavaScriptCompiler.prototype.appendToBuffer=function(b){return"data.buffer.push("+b+");"};var c=/helpers\.(.*?)\)/,b=/helpers\['(.*?)'/,g=/(.*blockHelperMissing\.call\(.*)(stack[0-9]+)(,.*)/;h.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation=function(a){var q=a[a.length-1],e=(c.exec(q)||b.exec(q))[1],q=g.exec(q);a[a.length-1]=q[1]+"'"+e+"'"+q[3]};var p=h.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation,u=h.JavaScriptCompiler.prototype.blockValue;h.JavaScriptCompiler.prototype.blockValue= -function(){u.apply(this,arguments);p(this.source)};var w=h.JavaScriptCompiler.prototype.ambiguousBlockValue;h.JavaScriptCompiler.prototype.ambiguousBlockValue=function(){w.apply(this,arguments);p(this.source)};h.Compiler.prototype.mustache=function(b){if(!b.params.length&&!b.hash){var a=new d.AST.IdNode([{part:"_triageMustache"}]);b.escaped||(b.hash=b.hash||new d.AST.HashNode([]),b.hash.pairs.push(["unescaped",new d.AST.StringNode("true")]));b=new d.AST.MustacheNode([a].concat([b.id]),b.hash,!b.escaped)}return d.Compiler.prototype.mustache.call(this, -b)};h.precompile=function(b,a){var e=d.parse(b),c={knownHelpers:{action:!0,unbound:!0,"bind-attr":!0,template:!0,view:!0,_triageMustache:!0},data:!0,stringParams:!0};a=void 0===a?!0:a;e=(new h.Compiler).compile(e,c);return(new h.JavaScriptCompiler).compile(e,c,void 0,a)};d.compile&&(h.compile=function(b){var a=d.parse(b);b={data:!0,stringParams:!0};a=(new h.Compiler).compile(a,b);b=(new h.JavaScriptCompiler).compile(a,b,void 0,!0);b=h.template(b);b.isMethod=!1;return b});m["default"]=h});t("ember-handlebars", -"ember-handlebars-compiler ember-metal/core ember-runtime/system/lazy_load ember-handlebars/loader ember-handlebars/ext ember-handlebars/string ember-handlebars/helpers/shared ember-handlebars/helpers/binding ember-handlebars/helpers/collection ember-handlebars/helpers/view ember-handlebars/helpers/unbound ember-handlebars/helpers/debug ember-handlebars/helpers/each ember-handlebars/helpers/template ember-handlebars/helpers/partial ember-handlebars/helpers/yield ember-handlebars/helpers/loc ember-handlebars/controls/checkbox ember-handlebars/controls/select ember-handlebars/controls/text_area ember-handlebars/controls/text_field ember-handlebars/controls/text_support ember-handlebars/controls ember-handlebars/component_lookup ember-handlebars/views/handlebars_bound_view ember-handlebars/views/metamorph_view exports".split(" "), -function(a,m,n,f,l,k,d,h,c,b,g,p,u,w,s,q,e,r,v,y,A,x,G,B,C,E,M){a=a["default"];m=m["default"];n=n.runLoadHooks;k=l.normalizePath;var L=l.template,H=l.makeBoundHelper,K=l.registerBoundHelper,Q=l.resolveHash,I=l.resolveParams,t=l.getEscaped,z=l.handlebarsGet,F=l.evaluateUnboundHelper,P=l.helperMissingHelper;l=l.blockHelperMissingHelper;d=d["default"];var O=h.bind,R=h._triageMustacheHelper,X=h.resolveHelper,U=h.bindHelper,Y=h.boundIfHelper,da=h.unboundIfHelper,ea=h.withHelper,V=h.ifHelper,J=h.unlessHelper, -Z=h.bindAttrHelper,D=h.bindAttrHelperDeprecated;h=h.bindClasses;c=c["default"];var W=b.ViewHelper;b=b.viewHelper;g=g["default"];var T=p.logHelper;p=p.debuggerHelper;var ca=u.EachView,$=u.GroupedEach;u=u.eachHelper;w=w["default"];s=s["default"];q=q["default"];e=e["default"];r=r["default"];var fa=v.Select,aa=v.SelectOption;v=v.SelectOptgroup;y=y["default"];A=A["default"];x=x["default"];var la=G.inputHelper;G=G.textareaHelper;B=B["default"];var ja=C._HandlebarsBoundView;C=C.SimpleHandlebarsView;var ra= -E._SimpleMetamorphView,ma=E._MetamorphView;E=E._Metamorph;a.bootstrap=f["default"];a.template=L;a.makeBoundHelper=H;a.registerBoundHelper=K;a.resolveHash=Q;a.resolveParams=I;a.resolveHelper=X;a.get=z;a.getEscaped=t;a.evaluateUnboundHelper=F;a.bind=O;a.bindClasses=h;a.EachView=ca;a.GroupedEach=$;a.resolvePaths=d;a.ViewHelper=W;a.normalizePath=k;m.Handlebars=a;m.ComponentLookup=B;m._SimpleHandlebarsView=C;m._HandlebarsBoundView=ja;m._SimpleMetamorphView=ra;m._MetamorphView=ma;m._Metamorph=E;m.TextSupport= -x;m.Checkbox=r;m.Select=fa;m.SelectOption=aa;m.SelectOptgroup=v;m.TextArea=y;m.TextField=A;m.TextSupport=x;a.registerHelper("helperMissing",P);a.registerHelper("blockHelperMissing",l);a.registerHelper("bind",U);a.registerHelper("boundIf",Y);a.registerHelper("_triageMustache",R);a.registerHelper("unboundIf",da);a.registerHelper("with",ea);a.registerHelper("if",V);a.registerHelper("unless",J);a.registerHelper("bind-attr",Z);a.registerHelper("bindAttr",D);a.registerHelper("collection",c);a.registerHelper("log", -T);a.registerHelper("debugger",p);a.registerHelper("each",u);a.registerHelper("loc",e);a.registerHelper("partial",s);a.registerHelper("template",w);a.registerHelper("yield",q);a.registerHelper("view",b);a.registerHelper("unbound",g);a.registerHelper("input",la);a.registerHelper("textarea",G);n("Ember.Handlebars",a);M["default"]=a});t("ember-handlebars/component_lookup",["ember-runtime/system/object","exports"],function(a,m){var n=a["default"].extend({lookupFactory:function(a,l){l=l||this.container; -var k="component:"+a,d="template:components/"+a,h=l&&l.has(d);h&&l.injection(k,"layout",d);d=l.lookupFactory(k);if(h||d)return d||(l.register(k,D.Component),d=l.lookupFactory(k)),d}});m["default"]=n});t("ember-handlebars/controls","ember-handlebars/controls/checkbox ember-handlebars/controls/text_field ember-handlebars/controls/text_area ember-metal/core ember-handlebars-compiler exports".split(" "),function(a,m,n,f,l,k){var d=a["default"],h=m["default"],c=n["default"],b=f["default"],g=l["default"].helpers; -k.inputHelper=function(a){b.assert("You can only pass attributes to the `input` helper, not arguments",2>arguments.length);var c=a.hash,f=c.type,s=c.on;delete c.type;delete c.on;if("checkbox"===f)return b.assert("{{input type='checkbox'}} does not support setting `value=someBooleanValue`; you must use `checked=someBooleanValue` instead.","ID"!==a.hashTypes.value),g.view.call(this,d,a);f&&(c.type=f);c.onEvent=s||"enter";return g.view.call(this,h,a)};k.textareaHelper=function(a){b.assert("You can only pass attributes to the `textarea` helper, not arguments", -2>arguments.length);return g.view.call(this,c,a)}});t("ember-handlebars/controls/checkbox",["ember-metal/property_get","ember-metal/property_set","ember-views/views/view","exports"],function(a,m,n,f){var l=a.get,k=m.set;a=n.View.extend({instrumentDisplay:'{{input type="checkbox"}}',classNames:["ember-checkbox"],tagName:"input",attributeBindings:"type checked indeterminate disabled tabindex name autofocus required form".split(" "),type:"checkbox",checked:!1,disabled:!1,indeterminate:!1,init:function(){this._super(); -this.on("change",this,this._updateElementValue)},didInsertElement:function(){this._super();l(this,"element").indeterminate=!!l(this,"indeterminate")},_updateElementValue:function(){k(this,"checked",this.$().prop("checked"))}});f["default"]=a});t("ember-handlebars/controls/select","ember-handlebars-compiler ember-metal/enumerable_utils ember-metal/property_get ember-metal/property_set ember-views/views/view ember-views/views/collection_view ember-metal/utils ember-metal/is_none ember-metal/computed ember-runtime/system/native_array ember-metal/mixin ember-metal/properties exports".split(" "), -function(a,m,n,f,l,k,d,h,c,b,g,p,u){var w=a["default"];a=m["default"];var s=n.get,q=f.set;n=l.View;k=k["default"];var e=d.isArray,r=h["default"],v=c.computed,y=b.A;d=g.observer;var A=p.defineProperty,x=a.indexOf,G=a.indexesOf,B=a.forEach,C=a.replace;p=n.extend({instrumentDisplay:"Ember.SelectOption",tagName:"option",attributeBindings:["value","selected"],defaultTemplate:function(b,a){a={data:a.data,hash:{}};w.helpers.bind.call(b,"view.label",a)},init:function(){this.labelPathDidChange();this.valuePathDidChange(); -this._super()},selected:v(function(){var b=s(this,"content"),a=s(this,"parentView.selection");return s(this,"parentView.multiple")?a&&-1= 1.0.0"];e=this.merge(e,D.Handlebars.helpers);g=g||{};var d=this.escapeExpression,p=this;((b=e["if"].call(a,"view.prompt", -{hash:{},hashTypes:{},hashContexts:{},inverse:p.noop,fn:p.program(1,function(b,a){var c;a.buffer.push('");return""},g),contexts:[a],types:["ID"],data:g}))||0===b)&&g.buffer.push(b);((b=e["if"].call(a,"view.optionGroupPath",{hash:{},hashTypes:{},hashContexts:{},inverse:p.program(6,function(b,a){var c;(c=e.each.call(b, -"view.content",{hash:{},hashTypes:{},hashContexts:{},inverse:p.noop,fn:p.program(7,r,a),contexts:[b],types:["ID"],data:a}))||0===c?a.buffer.push(c):a.buffer.push("")},g),fn:p.program(3,function(b,a){var c;(c=e.each.call(b,"view.groupedContent",{hash:{},hashTypes:{},hashContexts:{},inverse:p.noop,fn:p.program(4,q,a),contexts:[b],types:["ID"],data:a}))||0===c?a.buffer.push(c):a.buffer.push("")},g),contexts:[a],types:["ID"],data:g}))||0===b)&&g.buffer.push(b);return""}),attributeBindings:"multiple disabled tabindex name required autofocus form size".split(" "), -multiple:!1,disabled:!1,required:!1,content:null,selection:null,value:v(function(b,a){if(2===arguments.length)return a;var e=s(this,"optionValuePath").replace(/^content\.?/,"");return e?s(this,"selection."+e):s(this,"selection")}).property("selection"),prompt:null,optionLabelPath:"content",optionValuePath:"content",optionGroupPath:null,groupView:h,groupedContent:v(function(){var b=s(this,"optionGroupPath"),a=y(),e=s(this,"content")||[];B(e,function(e){var c=s(e,b);s(a,"lastObject.label")!==c&&a.pushObject({label:c, -content:y()});s(a,"lastObject.content").push(e)});return a}).property("optionGroupPath","content.@each"),optionView:p,_change:function(){s(this,"multiple")?this._changeMultiple():this._changeSingle()},selectionDidChange:d("selection.@each",function(){var b=s(this,"selection");s(this,"multiple")?e(b)?this._selectionDidChangeMultiple():q(this,"selection",y([b])):this._selectionDidChangeSingle()}),valueDidChange:d("value",function(){var b=s(this,"content"),a=s(this,"value"),e=s(this,"optionValuePath").replace(/^content\.?/, -""),c=e?s(this,"selection."+e):s(this,"selection");a!==c&&(b=b?b.find(function(b){return a===(e?s(b,e):b)}):null,this.set("selection",b))}),_triggerChange:function(){var b=s(this,"selection"),a=s(this,"value");r(b)||this.selectionDidChange();r(a)||this.valueDidChange();this._change()},_changeSingle:function(){var b=this.$()[0].selectedIndex,a=s(this,"content"),e=s(this,"prompt");a&&s(a,"length")&&(e&&0===b?q(this,"selection",null):(e&&(b-=1),q(this,"selection",a.objectAt(b))))},_changeMultiple:function(){var b= -this.$("option:selected"),a=s(this,"prompt")?1:0,c=s(this,"content"),g=s(this,"selection");c&&b&&(b=b.map(function(){return this.index-a}).toArray(),c=c.objectsAt(b),e(g)?C(g,0,s(g,"length"),c):q(this,"selection",c))},_selectionDidChangeSingle:function(){var b=this.get("element");if(b){var a=s(this,"content"),e=s(this,"selection"),a=a?x(a,e):-1;s(this,"prompt")&&(a+=1);b&&(b.selectedIndex=a)}},_selectionDidChangeMultiple:function(){var b=s(this,"content"),a=s(this,"selection"),e=b?G(b,a):[-1],c=s(this, -"prompt")?1:0,b=this.$("option"),g;b&&b.each(function(){g=-1=arguments.length); -var e=E.resolveHelper(a.data.view.container,b);return e?e.call(this,a):W.bind.call(this,b,a)};v.resolveHelper=function(b,a){if(W[a])return W[a];if(b&&-1!==a.indexOf("-")){var e=b.lookup("helper:"+a);if(!e){var c=b.lookup("component-lookup:main");C.assert("Could not find 'component-lookup:main' on the provided container, which is necessary for performing component lookups",c);if(c=c.lookupFactory(a,b))e=E.makeViewHelper(c),b.register("helper:"+a,e)}return e}};v.bindHelper=function(b,a){C.assert("You cannot pass more than one argument to the bind helper", -2>=arguments.length);var e=a.contexts&&a.contexts.length?a.contexts[0]:this;if(!a.fn)return x(e,b,a);a.helperName="bind";return A.call(e,b,a,!1,y)};v.boundIfHelper=function(b,a){var e=a.contexts&&a.contexts.length?a.contexts[0]:this;a.helperName=a.helperName||"boundIf";return A.call(e,b,a,!0,G,G,["isTruthy","length"])};v.unboundIfHelper=function(b,a){var e=a.contexts&&a.contexts.length?a.contexts[0]:this,c=a.data,g=a.fn,q=a.inverse,r;V(e,b,c);r=J(e,b,a);G(r)||(g=q);g(e,{data:c})};v.withHelper=function(b, -a){var e,c,g="with";if(4===arguments.length){var q;C.assert("If you pass more than one argument to the with helper, it must be in the form #with foo as bar","as"===arguments[1]);a=arguments[3];e=arguments[2];(c=arguments[0])&&(g+=" "+c+" as "+e);C.assert("You must pass a block to the with helper",a.fn&&a.fn!==Handlebars.VM.noop);var r=K(a);r.data=K(a.data);r.data.keywords=K(a.data.keywords||{});if(P(c))q=c;else{q=V(this,c,a.data);c=q.path;q=q.root;var d=R.expando+Z(q);r.data.keywords[d]=q;q=c?d+"."+ -c:d}r.hash.keywordName=e;r.hash.keywordPath=q;e=this;b=c;a=r;c=!0}else C.assert("You must pass exactly one argument to the with helper",2===arguments.length),C.assert("You must pass a block to the with helper",a.fn&&a.fn!==Handlebars.VM.noop),g+=" "+b,e=a.contexts[0],c=!1;a.helperName=g;a.isWithHelper=!0;return A.call(e,b,a,c,y)};v.ifHelper=function(b,a){C.assert("You must pass exactly one argument to the if helper",2===arguments.length);C.assert("You must pass a block to the if helper",a.fn&&a.fn!== -Handlebars.VM.noop);a.helperName=a.helperName||"if "+b;return a.data.isUnbound?W.unboundIf.call(a.contexts[0],b,a):W.boundIf.call(a.contexts[0],b,a)};v.unlessHelper=function(b,a){C.assert("You must pass exactly one argument to the unless helper",2===arguments.length);C.assert("You must pass a block to the unless helper",a.fn&&a.fn!==Handlebars.VM.noop);var e=a.fn,c=a.inverse,g="unless";b&&(g+=" "+b);a.fn=c;a.inverse=e;a.helperName=a.helperName||g;return a.data.isUnbound?W.unboundIf.call(a.contexts[0], -b,a):W.boundIf.call(a.contexts[0],b,a)};v.bindAttrHelper=function(b){var a=b.hash;C.assert("You must specify at least one hash argument to bind-attr",!!Y(a).length);var e=b.data.view,c=[],g=this||window,q=++C.uuid,r=a["class"];null!=r&&(r=B(g,r,e,q,b),c.push('class="'+Handlebars.Utils.escapeExpression(r.join(" "))+'"'),delete a["class"]);r=Y(a);I.call(r,function(r){var d=a[r],p;C.assert(H("You must provide an expression as the value of bound attribute. You specified: %@=%@",[r,d]),"string"===typeof d); -p=V(g,d,b.data);var f="this"===d?p.root:J(g,d,b),s=D(f);C.assert(H("Attributes must be numbers, strings or booleans, not %@",[f]),null===f||void 0===f||"number"===s||"string"===s||"boolean"===s);"this"!==d&&!(p.isKeyword&&""===p.path)&&e.registerObserver(p.root,p.path,function ba(){var a=J(g,d,b);C.assert(H("Attributes must be numbers, strings or booleans, not %@",[a]),null===a||void 0===a||"number"===typeof a||"string"===typeof a||"boolean"===typeof a);var c=e.$("[data-bindattr-"+q+"='"+q+"']"); -!c||0===c.length?F(p.root,p.path,ba):N.applyAttributeBindings(c,r,a)});"string"===s||"number"===s&&!isNaN(f)?c.push(r+'="'+Handlebars.Utils.escapeExpression(f)+'"'):f&&"boolean"===s&&c.push(r+'="'+r+'"')},this);c.push("data-bindattr-"+q+'="'+q+'"');return new T(c.join(" "))};v.bindAttrHelperDeprecated=function(){C.warn("The 'bindAttr' view helper is deprecated in favor of 'bind-attr'");return W["bind-attr"].apply(this,arguments)};v.bindClasses=B});t("ember-handlebars/helpers/collection","ember-metal/core ember-metal/utils ember-handlebars-compiler ember-runtime/system/string ember-metal/property_get ember-handlebars/ext ember-handlebars/helpers/view ember-metal/computed ember-views/views/collection_view exports".split(" "), -function(a,m,n,f,l,k,d,h,c,b){var g=a["default"],p=n["default"],u=p.helpers,w=f.fmt,s=l.get,q=k.handlebarsGet,e=d.ViewHelper,r=c["default"],v=h.computed.alias;b["default"]=function(b,a){g.deprecate("Using the {{collection}} helper without specifying a class has been deprecated as the {{each}} helper now supports the same functionality.","collection"!==b);b&&b.data&&b.data.isRenderData?(a=b,b=void 0,g.assert("You cannot pass more than one argument to the collection helper",1===arguments.length)):g.assert("You cannot pass more than one argument to the collection helper", -2===arguments.length);var c=a.fn,d=a.data,f=a.inverse,h,k,l;b?(k=(h=d.keywords.controller)&&h.container,l=q(this,b,a)||k.lookupFactory("view:"+b),g.assert(w("%@ #collection: Could not find collection class %@",[d.view,b]),!!l)):l=r;var m=a.hash,n={},K=l.proto();m.itemView?(h=d.keywords.controller,g.assert('You specified an itemView, but the current context has no container to look the itemView up in. This probably means that you created a view manually, instead of through the container. Instead, use container.lookup("view:viewName"), which will properly instantiate your view.', -h&&h.container),k=h.container,h=k.lookupFactory("view:"+m.itemView),g.assert("You specified the itemView "+m.itemView+", but it was not found at "+k.describe("view:"+m.itemView)+" (and it was not registered in the container)",!!h)):h=m.itemViewClass?q(K,m.itemViewClass,a):K.itemViewClass;g.assert(w("%@ #collection: Could not find itemViewClass %@",[d.view,h]),!!h);delete m.itemViewClass;delete m.itemView;for(var t in m)if(m.hasOwnProperty(t)&&(k=t.match(/^item(.)(.*)$/))&&"itemController"!==t)n[k[1].toLowerCase()+ -k[2]]=m[t],delete m[t];c&&(n.template=c,delete a.fn);var I;f&&f!==p.VM.noop?(I=s(K,"emptyViewClass"),I=I.extend({template:f,tagName:n.tagName})):m.emptyViewClass&&(I=q(this,m.emptyViewClass,a));I&&(m.emptyView=I);n._context=m.keyword?this:v("content");c=e.propertiesFromHTMLOptions({data:d,hash:n},this);m.itemViewClass=h.extend(c);a.helperName=a.helperName||"collection";return u.view.call(this,l,a)}});t("ember-handlebars/helpers/debug","ember-metal/core ember-metal/utils ember-metal/logger ember-metal/property_get ember-handlebars/ext exports".split(" "), -function(a,m,n,f,l,k){var d=m.inspect,h=n["default"],c=l.normalizePath,b=l.handlebarsGet,g=[].slice;k.logHelper=function(){for(var a=g.call(arguments,0,-1),d=arguments[arguments.length-1],f=h.log,s=[],q=0;q=arguments.length);b&&(b.data&&b.data.isRenderData)&&(a=b,p.assert("{{view}} helper requires parent view to have a container but none was found. This usually happens when you are manually-managing views.",!!a.data.view.container),b=a.data.view.container.lookupFactory("view:default"));a.helperName=a.helperName||"view";return G.helper(this,b,a)}});t("ember-handlebars/helpers/yield",["ember-metal/core", -"ember-metal/property_get","exports"],function(a,m,n){var f=a["default"],l=m.get;n["default"]=function(a){for(var d=a.data.view;d&&!l(d,"layout");)d=d._contextView?d._contextView:l(d,"_parentView");f.assert("You called yield in a template that was not a layout",!!d);d._yield(this,a)}});t("ember-handlebars/loader","ember-handlebars/component_lookup ember-views/system/jquery ember-metal/error ember-runtime/system/lazy_load ember-handlebars-compiler exports".split(" "),function(a,m,n,f,l,k){function d(b){g('script[type="text/x-handlebars"], script[type="text/x-raw-handlebars"]', -b).each(function(){var b=g(this),a="text/x-raw-handlebars"===b.attr("type")?g.proxy(Handlebars.compile,Handlebars):g.proxy(u.compile,u),e=b.attr("data-template-name")||b.attr("id")||"application",a=a(b.html());if(void 0!==D.TEMPLATES[e])throw new p('Template named "'+e+'" already exists.');D.TEMPLATES[e]=a;b.remove()})}function h(){d(g(document))}function c(a){a.register("component-lookup:main",b)}var b=a["default"],g=m["default"],p=n["default"];a=f.onLoad;var u=l["default"];a("Ember.Application", -function(b){b.initializer({name:"domTemplates",initialize:h});b.initializer({name:"registerComponentLookup",after:"domTemplates",initialize:c})});k["default"]=d});t("ember-handlebars/string",["ember-runtime/system/string","exports"],function(a,m){function n(a){return new Handlebars.SafeString(a)}a["default"].htmlSafe=n;if(!0===D.EXTEND_PROTOTYPES||D.EXTEND_PROTOTYPES.String)String.prototype.htmlSafe=function(){return n(this)};m["default"]=n});t("ember-handlebars/views/handlebars_bound_view","ember-handlebars-compiler ember-metal/core ember-metal/error ember-metal/property_get ember-metal/property_set ember-metal/merge ember-metal/run_loop ember-metal/computed ember-views/views/view ember-views/views/states ember-handlebars/views/metamorph_view ember-handlebars/ext exports".split(" "), -function(a,m,n,f,l,k,d,h,c,b,g,p,u){function w(b,a,e,c){this.path=b;this.pathRoot=a;this.isEscaped=e;this.templateData=c;this.morph=q();this.state="preRender";this.buffer=this._parentView=this.updateId=null}var s=a["default"].SafeString;a=m["default"].K;var q=S("metamorph"),e=n["default"],r=f.get,v=l.set;n=k["default"];var y=d["default"];d=b.cloneStates;b=b.states;g=g._MetamorphView;var A=p.handlebarsGet;w.prototype={isVirtual:!0,isView:!0,destroy:function(){this.updateId&&(y.cancel(this.updateId), -this.updateId=null);this._parentView&&this._parentView.removeChild(this);this.morph=null;this.state="destroyed"},propertyWillChange:a,propertyDidChange:a,normalizedValue:function(){var b=this.path,a=this.pathRoot,e;""===b?b=a:(e=this.templateData,b=A(a,b,{data:e}));return b},renderToBuffer:function(b){var a;a=""+this.morph.startTag();a+=this.render();a+=this.morph.endTag();b.push(a)},render:function(){var b=this.isEscaped,a=this.normalizedValue();null===a||void 0===a?a="":a instanceof s||(a=String(a)); -b&&(a=Handlebars.Utils.escapeExpression(a));return a},rerender:function(){switch(this.state){case "inBuffer":throw new e("Something you did tried to replace an {{expression}} before it was inserted into the DOM.");case "hasElement":case "inDOM":this.updateId=y.scheduleOnce("render",this,"update")}return this},update:function(){this.updateId=null;this.morph.html(this.render())},transitionTo:function(b){this.state=b}};b=d(b);n(b._default,{rerenderIfNeeded:a});n(b.inDOM,{rerenderIfNeeded:function(b){b.normalizedValue()!== -b._lastNormalizedValue&&b.rerender()}});p=g.extend({instrumentName:"boundHandlebars",_states:b,shouldDisplayFunc:null,preserveContext:!1,previousContext:null,displayTemplate:null,inverseTemplate:null,path:null,pathRoot:null,normalizedValue:function(){var b=r(this,"path"),a=r(this,"pathRoot"),e=r(this,"valueNormalizerFunc"),c;""===b?b=a:(c=r(this,"templateData"),b=A(a,b,{data:c}));return e?e(b):b},rerenderIfNeeded:function(){this.currentState.rerenderIfNeeded(this)},render:function(b){var a=r(this, -"isEscaped"),e=r(this,"shouldDisplayFunc"),c=r(this,"preserveContext"),g=r(this,"previousContext"),d=r(this,"inverseTemplate"),q=r(this,"displayTemplate"),f=this.normalizedValue();this._lastNormalizedValue=f;if(e(f))if(v(this,"template",q),c)v(this,"_context",g);else if(q)v(this,"_context",f);else{null===f||void 0===f?f="":f instanceof s||(f=String(f));a&&(f=Handlebars.Utils.escapeExpression(f));b.push(f);return}else d?(v(this,"template",d),c?v(this,"_context",g):v(this,"_context",f)):v(this,"template", -function(){return""});return this._super(b)}});u._HandlebarsBoundView=p;u.SimpleHandlebarsView=w});t("ember-handlebars/views/metamorph_view","ember-metal/core ember-metal/property_get ember-metal/property_set ember-views/views/view ember-metal/mixin ember-metal/run_loop exports".split(" "),function(a,m,n,f,l,k,d){function h(){g.once(b,"notifyMutationListeners")}var c=a["default"];a=f.CoreView;var b=f.View;f=l.Mixin;var g=k["default"],p=S("metamorph");k=f.create({isVirtual:!0,tagName:"",instrumentName:"metamorph", -init:function(){this._super();this.morph=p();c.deprecate("Supplying a tagName to Metamorph views is unreliable and is deprecated. You may be setting the tagName on a Handlebars helper that creates a Metamorph.",!this.tagName)},beforeRender:function(b){b.push(this.morph.startTag());b.pushOpeningTag()},afterRender:function(b){b.pushClosingTag();b.push(this.morph.endTag())},createElement:function(){this.outerHTML=this.renderToBuffer().string();this.clearBuffer()},domManager:{remove:function(b){b.morph.remove(); -h()},prepend:function(b,a){b.morph.prepend(a);h()},after:function(b,a){b.morph.after(a);h()},html:function(b,a){b.morph.html(a);h()},replace:function(b){var a=b.morph;b.transitionTo("preRender");g.schedule("render",this,function(){if(!b.isDestroying){b.clearRenderedChildren();var c=b.renderToBuffer();b.invokeRecursively(function(b){b.propertyWillChange("element")});b.triggerRecursively("willInsertElement");a.replaceWith(c.string());b.transitionTo("inDOM");b.invokeRecursively(function(b){b.propertyDidChange("element")}); -b.triggerRecursively("didInsertElement");h()}})},empty:function(b){b.morph.html("");h()}}});d._Metamorph=k;f=b.extend(k);d._MetamorphView=f;k=a.extend(k);d._SimpleMetamorphView=k});t("ember-metal","ember-metal/core ember-metal/merge ember-metal/instrumentation ember-metal/utils ember-metal/error ember-metal/enumerable_utils ember-metal/platform ember-metal/array ember-metal/logger ember-metal/property_get ember-metal/events ember-metal/observer_set ember-metal/property_events ember-metal/properties ember-metal/property_set ember-metal/map ember-metal/get_properties ember-metal/set_properties ember-metal/watch_key ember-metal/chains ember-metal/watch_path ember-metal/watching ember-metal/expand_properties ember-metal/computed ember-metal/observer ember-metal/mixin ember-metal/binding ember-metal/run_loop ember-metal/libraries ember-metal/is_none ember-metal/is_empty ember-metal/is_blank exports".split(" "), -function(a,m,n,f,l,k,d,h,c,b,g,p,u,w,s,q,e,r,v,y,A,x,G,B,C,E,M,L,H,K,t,I,N){var z=a["default"],F=m["default"],P=n.instrument,O=n.subscribe,R=n.unsubscribe,X=n.reset,U=f.generateGuid,Y=f.GUID_KEY,da=f.GUID_PREFIX,ea=f.guidFor,V=f.META_DESC,J=f.EMPTY_META,Z=f.meta,D=f.getMeta,W=f.setMeta,T=f.metaPath,ca=f.inspect,$=f.typeOf,fa=f.tryCatchFinally,aa=f.isArray,la=f.makeArray,ja=f.canInvoke,ra=f.tryInvoke,ma=f.tryFinally,sa=f.wrap,ta=f.apply,ha=f.applyStr,oa=l["default"],ua=k["default"],pa=d.create,ba= -d.platform,qa=h.map,xa=h.forEach,ya=h.filter,za=h.indexOf,Aa=c["default"],Ba=b.get,Ca=b.getWithDefault,Da=b.normalizeTuple,ia=b._getPath,ka=g.on,Ea=g.addListener,Fa=g.removeListener,Ga=g.suspendListener,Ha=g.suspendListeners,Ia=g.sendEvent,Ja=g.hasListeners,Ka=g.watchedEvents,La=g.listenersFor,Ma=g.listenersDiff,Na=g.listenersUnion,Oa=p["default"],Pa=u.propertyWillChange,Qa=u.propertyDidChange,Ra=u.overrideChains,Sa=u.beginPropertyChanges,Ta=u.endPropertyChanges,Ua=u.changeProperties,Va=w.Descriptor, -Wa=w.defineProperty,Xa=s.set,Ya=s.trySet,Za=q.OrderedSet,$a=q.Map,ab=q.MapWithDefault,bb=e["default"],cb=r["default"],db=v.watchKey,eb=v.unwatchKey,ga=y.flushPendingChains,fb=y.removeChainWatcher,gb=y.ChainNode,hb=y.finishChains,ib=A.watchPath,jb=A.unwatchPath,kb=x.watch,lb=x.isWatching,mb=x.unwatch,nb=x.rewatch,ob=x.destroy,pb=G["default"],qb=B.ComputedProperty,rb=B.computed,sb=B.cacheFor,tb=C.addObserver,ub=C.observersFor,vb=C.removeObserver,wb=C.addBeforeObserver,xb=C._suspendBeforeObserver,yb= -C._suspendObserver,zb=C._suspendBeforeObservers,Ab=C._suspendObservers,Bb=C.beforeObserversFor,Cb=C.removeBeforeObserver,Db=E.IS_BINDING,Eb=E.mixin,Fb=E.Mixin,Gb=E.required,Hb=E.aliasMethod,Ib=E.observer,Jb=E.immediateObserver,Kb=E.beforeObserver,Lb=M.Binding,Mb=M.isGlobalPath,Nb=M.bind,Ob=M.oneWay,Pb=L["default"],Qb=H["default"],Rb=K.isNone,Sb=K.none,Tb=t.isEmpty,Ub=t.empty,Vb=I["default"],va=z.Instrumentation={};va.instrument=P;va.subscribe=O;va.unsubscribe=R;va.reset=X;z.instrument=P;z.subscribe= -O;z.generateGuid=U;z.GUID_KEY=Y;z.GUID_PREFIX=da;z.create=pa;z.platform=ba;var wa=z.ArrayPolyfills={};wa.map=qa;wa.forEach=xa;wa.filter=ya;wa.indexOf=za;z.Error=oa;z.guidFor=ea;z.META_DESC=V;z.EMPTY_META=J;z.meta=Z;z.getMeta=D;z.setMeta=W;z.metaPath=T;z.inspect=ca;z.typeOf=$;z.tryCatchFinally=fa;z.isArray=aa;z.makeArray=la;z.canInvoke=ja;z.tryInvoke=ra;z.tryFinally=ma;z.wrap=sa;z.apply=ta;z.applyStr=ha;z.Logger=Aa;z.get=Ba;z.getWithDefault=Ca;z.normalizeTuple=Da;z._getPath=ia;z.EnumerableUtils=ua; -z.on=ka;z.addListener=Ea;z.removeListener=Fa;z._suspendListener=Ga;z._suspendListeners=Ha;z.sendEvent=Ia;z.hasListeners=Ja;z.watchedEvents=Ka;z.listenersFor=La;z.listenersDiff=Ma;z.listenersUnion=Na;z._ObserverSet=Oa;z.propertyWillChange=Pa;z.propertyDidChange=Qa;z.overrideChains=Ra;z.beginPropertyChanges=Sa;z.endPropertyChanges=Ta;z.changeProperties=Ua;z.Descriptor=Va;z.defineProperty=Wa;z.set=Xa;z.trySet=Ya;z.OrderedSet=Za;z.Map=$a;z.MapWithDefault=ab;z.getProperties=bb;z.setProperties=cb;z.watchKey= -db;z.unwatchKey=eb;z.flushPendingChains=ga;z.removeChainWatcher=fb;z._ChainNode=gb;z.finishChains=hb;z.watchPath=ib;z.unwatchPath=jb;z.watch=kb;z.isWatching=lb;z.unwatch=mb;z.rewatch=nb;z.destroy=ob;z.expandProperties=pb;z.ComputedProperty=qb;z.computed=rb;z.cacheFor=sb;z.addObserver=tb;z.observersFor=ub;z.removeObserver=vb;z.addBeforeObserver=wb;z._suspendBeforeObserver=xb;z._suspendBeforeObservers=zb;z._suspendObserver=yb;z._suspendObservers=Ab;z.beforeObserversFor=Bb;z.removeBeforeObserver=Cb; -z.IS_BINDING=Db;z.required=Gb;z.aliasMethod=Hb;z.observer=Ib;z.immediateObserver=Jb;z.beforeObserver=Kb;z.mixin=Eb;z.Mixin=Fb;z.oneWay=Ob;z.bind=Nb;z.Binding=Lb;z.isGlobalPath=Mb;z.run=Pb;z.libraries=Qb;z.libraries.registerCoreLibrary("Ember",z.VERSION);z.isNone=Rb;z.none=Sb;z.isEmpty=Tb;z.empty=Ub;z.isBlank=Vb;z.merge=F;z.onerror=null;z.__loader.registry["ember-debug"]&&S("ember-debug");N["default"]=z});t("ember-metal/array",["exports"],function(a){var m=Array.prototype,n=function(a){return a&&-1< -Function.prototype.toString.call(a).indexOf("[native code]")},f=n(m.map)?m.map:function(a,f){if(void 0===this||null===this)throw new TypeError;var c=Object(this),b=c.length>>>0;if("function"!==typeof a)throw new TypeError;for(var g=Array(b),p=0;p>>0;if("function"!==typeof a)throw new TypeError;for(var g=0;gf&&(f=Math.max(0,this.length+f));for(var c=f,b=this.length;c("+this._from+" -> "+this._to+")"+b},connect:function(a){b.assert("Must pass a valid object to Ember.Binding.connect()",!!a);var e=this._from,r=this._to;p(a,r,g(c(e)?b.lookup:a,e));s(a, -e,this,this.fromDidChange);this._oneWay||s(a,r,this,this.toDidChange);this._readyToSync=!0;return this},disconnect:function(a){b.assert("Must pass a valid object to Ember.Binding.disconnect()",!!a);var e=!this._oneWay;q(a,this._from,this,this.fromDidChange);e&&q(a,this._to,this,this.toDidChange);this._readyToSync=!1;return this},fromDidChange:function(b){this._scheduleSync(b,"fwd")},toDidChange:function(b){this._scheduleSync(b,"back")},_scheduleSync:function(b,a){var e=this._directionMap,c=e.get(b); -c||(r.schedule("sync",this,this._sync,b),e.set(b,a));"back"===c&&"fwd"===a&&e.set(b,"fwd")},_sync:function(a){var r=b.LOG_BINDINGS;if(!a.isDestroyed&&this._readyToSync){var q=this._directionMap,d=q.get(a),f=this._from,s=this._to;q.remove(a);if("fwd"===d){var h=g(c(this._from)?b.lookup:a,this._from);r&&b.Logger.log(" ",this.toString(),"->",h,a);this._oneWay?p(a,s,h):e(a,s,this,this.toDidChange,function(){p(a,s,h)})}else if("back"===d){var k=g(a,this._to);r&&b.Logger.log(" ",this.toString(),"<-",k, -a);e(a,f,this,this.fromDidChange,function(){p(c(f)?b.lookup:a,f,k)})}}}};(function(b,a){for(var e in a)a.hasOwnProperty(e)&&(b[e]=a[e])})(y,{from:function(){var b=new this;return b.from.apply(b,arguments)},to:function(){var b=new this;return b.to.apply(b,arguments)},oneWay:function(b,a){return(new this(null,b)).oneWay(a)}});h.bind=function(b,a,e){return(new y(a,e)).connect(b)};h.oneWay=function(b,a,e){return(new y(a,e)).oneWay().connect(b)};h.Binding=y;h.isGlobalPath=c});t("ember-metal/chains","ember-metal/core ember-metal/property_get ember-metal/utils ember-metal/array ember-metal/watch_key exports".split(" "), -function(a,m,n,f,l,k){function d(b,a,e){if(b&&"object"===typeof b){var c=q(b),g=c.chainWatchers;c.hasOwnProperty("chainWatchers")||(g=c.chainWatchers={});g[a]||(g[a]=[]);g[a].push(e);w(b,a,c)}}function h(b,a,e){if(b&&"object"===typeof b){var c=b[p];if(!c||c.hasOwnProperty("chainWatchers")){var g=c&&c.chainWatchers;if(g&&g[a])for(var g=g[a],r=0,q=g.length;r=a[e]||b.add(e);return b};a.add=function(b){var a,e,c;e=this._paths;e[b]=(e[b]||0)+1;a=this.value();e=g(a,b);if(e[0]&&e[0]===a)b=e[1],a=b.match(r)[0],b=b.slice(a.length+1);else if(e[0])c=e[0],a=b.slice(0,0-(e[1].length+1)),b=e[1];else{v.push([this,b]);e.length=0;return}e.length=0;this.chain(a,b,c)};a.remove=function(b){var a,e;e=this._paths;0=c.count&&(delete e[c._key],c.destroy())};a.willChange=function(b){var a=this._chains;if(a)for(var e in a)a.hasOwnProperty(e)&&a[e].willChange(b);this._parent&&this._parent.chainWillChange(this, -this._key,1,b)};a.chainWillChange=function(b,a,e,c){this._key&&(a=this._key+"."+a);this._parent?this._parent.chainWillChange(this,a,e+1,c):(1a});G("gte",function(b,a){return E(this,b)>=a});G("lt",function(b,a){return E(this,b)=s&&(s=0),g=f.splice(0,6E4),g=[b,s].concat(g),b+=6E4,k-=s,h=h.concat(d.apply(a,g));return h},replace:function(a, -b,g,d){return a.replace?a.replace(b,g,d):h._replace(a,b,g,d)},intersection:function(a,b){var g=[];h.forEach(a,function(a){0<=h.indexOf(b,a)&&g.push(a)});return g}};m["default"]=h});t("ember-metal/error",["ember-metal/platform","exports"],function(a,m){function n(){var a=Error.apply(this,arguments);Error.captureStackTrace&&Error.captureStackTrace(this,D.Error);for(var d=0;d=r&&(q.clear(),e.flush())}var b=a.META_KEY,g=a.guidFor,p=a.tryFinally,u=m.sendEvent,w=m.listenersUnion,s=m.listenersDiff;a=n["default"];var q=new a,e=new a,r=0,v,y;f.propertyWillChange=l;f.propertyDidChange=k;f.overrideChains=function(b,a,c){h(b,a,c,!0)};f.beginPropertyChanges=function(){r++};f.endPropertyChanges=c;f.changeProperties=function(b,a){r++;p(b,c,a)}});t("ember-metal/property_get",["ember-metal/core","ember-metal/utils","ember-metal/error","exports"], -function(a,m,n,f){function l(a,g){var e=0===g.indexOf(u),f=!e&&p.test(g);if(!a||f)a=d.lookup;e&&(g=g.slice(5));a===d.lookup&&(e=g.match(w)[0],a=b(a,e),g=g.slice(e.length+1));if(!g||0===g.length)throw new c("Path cannot be empty");return[a,g]}function k(a,c){var e,g,f;if(null===a&&-1===c.indexOf("."))return b(d.lookup,c);e=0===c.indexOf(u);if(!a||e)e=l(a,c),a=e[0],c=e[1],e.length=0;e=c.split(".");f=e.length;for(g=0;null!=a&&gd&&(e=a[0]);if(b.isActive.apply(b,[e].concat(c)))return x(this,"activeClass")}).property("resolvedParams", -"routeArgs"),loading:a(function(){if(!x(this,"routeArgs"))return x(this,"loadingClass")}).property("routeArgs"),router:a(function(){return x(this,"controller").container.lookup("router:main")}),_invoke:function(b){if(!M(b))return!0;if(!1!==this.preventDefault)if(A.FEATURES.isEnabled("ember-routing-linkto-target-attribute")){var a=x(this,"target");(!a||"_self"===a)&&b.preventDefault()}else b.preventDefault();!1===this.bubbles&&b.stopPropagation();if(x(this,"_isDisabled"))return!1;if(x(this,"loading"))return A.Logger.warn("This link-to is in an inactive loading state because at least one of its parameters presently has a null/undefined value, or the provided route name is invalid."), -!1;b=x(this,"router");a=x(this,"routeArgs");a=x(this,"replace")?b.replaceWith.apply(b,a):b.transitionTo.apply(b,a);b=b.router.generate.apply(b.router,v(this));B.scheduleOnce("routerTransitions",this,this._eagerUpdateUrl,a,b)},_eagerUpdateUrl:function(b,a){if(b.isActive&&b.urlMethod){0===a.indexOf("#")&&(a=a.slice(1));var c=x(this,"router.router");"update"===b.urlMethod?c.updateURL(a):"replace"===b.urlMethod&&c.replaceURL(a);b.method(null)}},resolvedParams:a(function(){var b=this.parameters,a=b.options, -c=a.types,a=a.data;return 0===b.params.length?(b=this.container.lookup("controller:application"),[x(b,"currentRouteName")]):K(b.context,b.params,{types:c,data:a})}).property("router.url"),routeArgs:a(function(){var b=x(this,"resolvedParams").slice(0),a=x(this,"router"),c=b[0];if(c){A.assert(C("The attempt to link-to route '%@' failed. The router did not find '%@' in its possible routes: '%@'",[c,c,E(a.router.recognizer.names).join("', '")]),a.hasRoute(c));a=a.router.recognizer.handlersFor(c);c!== -a[a.length-1].handler&&(this.currentWhen||this.set("currentWhen",c),c=a[a.length-1].handler,b[0]=c);c=1;for(a=b.length;c "+b,{fullName:b});return a}});t("ember-routing/system/dsl",["ember-metal/core","exports"],function(a,m){function n(a){this.parent=a;this.matches=[]}function f(a,d,f){l.assert("You must use `this.resource` to nest","function"!==typeof f);f=f||{};"string"!==typeof f.path&&(f.path="/"+d);a.parent&&"application"!==a.parent&&(d=a.parent+"."+d);a.push(f.path, -d,null)}var l=a["default"];m["default"]=n;n.prototype={resource:function(a,d,h){l.assert("'basic' cannot be used as a resource name.","basic"!==a);2===arguments.length&&"function"===typeof d&&(h=d,d={});1===arguments.length&&(d={});"string"!==typeof d.path&&(d.path="/"+a);var c=!1;l.FEATURES.isEnabled("ember-routing-consistent-resources")?c=!0:h&&(c=!0);c?(c=new n(a),f(c,"loading"),f(c,"error",{path:"/_unused_dummy_error_path_route_"+a+"/:error"}),h&&h.call(c),this.push(d.path,a,c.generate())):this.push(d.path, -a,null);l.FEATURES.isEnabled("ember-routing-named-substates")&&(a=a.split(".").pop(),f(this,a+"_loading"),f(this,a+"_error",{path:"/_unused_dummy_error_path_route_"+a+"/:error"}))},push:function(a,d,f){var c=d.split(".");if(""===a||"/"===a||"index"===c[c.length-1])this.explicitIndex=!0;this.matches.push([a,d,f])},route:function(a,d){l.assert("'basic' cannot be used as a route name.","basic"!==a);f(this,a,d);l.FEATURES.isEnabled("ember-routing-named-substates")&&(f(this,a+"_loading"),f(this,a+"_error", -{path:"/_unused_dummy_error_path_route_"+a+"/:error"}))},generate:function(){var a=this.matches;this.explicitIndex||this.route("index",{path:"/"});return function(d){for(var f=0,c=a.length;fb.length)&&a){var c=b[0],e={};/_id$/.test(c)&&1===b.length?e[c]=B(a,"id"):e=E(a,b);return e}},setupController:function(a,b,c){a&&void 0!==b&&C(a,"model",b)},controllerFor:function(a,b){var c=this.container,e=c.lookup("route:"+a);e&&e.controllerName&&(a=e.controllerName);c=c.lookup("controller:"+a);x.assert("The controller named '"+a+"' could not be found. Make sure that this route exists and has already been entered at least once. If you are accessing a controller not associated with a route, make sure the controller class is explicitly defined.", -c||!0===b);return c},generateController:function(a,b){var c=this.container;b=b||this.modelFor(a);return N(c,a,b)},modelFor:function(a){var b=this.container.lookup("route:"+a),c=this.router?this.router.router.activeTransition:null;return c&&(a=b&&b.routeName||a,c.resolvedModels.hasOwnProperty(a))?c.resolvedModels[a]:b&&b.currentModel},renderTemplate:function(a,b){this.render()},render:function(a,b){x.assert("The name in the given arguments is undefined",0 "+d,{fullName:d}));f.routeName=g;return f}},_setupRouter:function(a, -b){var c,e=this;a.getHandler=this._getHandlerFunction();var g=function(){b.setURL(c)};a.updateURL=function(a){c=a;K.once(g)};if(b.replaceURL){var d=function(){b.replaceURL(c)};a.replaceURL=function(a){c=a;K.once(d)}}a.didTransition=function(a){e.didTransition(a)}},_doTransition:function(a,b){b=P.call(b);b[0]=b[0]||"/";var c=b[0],e=!1,g;if(B.FEATURES.isEnabled("query-params-new")){var d=b[b.length-1];d&&d.hasOwnProperty("queryParams")&&(1===b.length&&(e=!0,c=null),g=b[b.length-1].queryParams)}!e&& -"/"!==c.charAt(0)&&B.assert("The route "+c+" was not found",this.router.hasRoute(c));if(g){c||(c=this.router.activeTransition?this.router.activeTransition.state.handlerInfos:this.router.state.handlerInfos,c=c[c.length-1].name,b.unshift(c));var c=this._queryParamsFor(c),e={},f;for(f in g)if(g.hasOwnProperty(f)){var d=g[f],r=c.map[f];if(!r)throw new C("Unrecognized query param "+f+" provided as transition argument");e[r.urlKey]=r.route.serializeQueryParam(d,r.urlKey,r.type)}b[b.length-1].queryParams= -e}g=this.router[a].apply(this.router,b);g.then(null,function(a){if(a&&a.name){if("UnrecognizedURLError"===a.name)B.assert("The URL '"+a.message+"' did not match any routes in your application");else if("TransitionAborted"!==a.name)throw a;return a}},"Ember: Process errors from Router");return g},_queryParamsFor:function(a){if(this._qpCache[a])return this._qpCache[a];var b={},c=[];this._qpCache[a]={map:b,qps:c};var e=this.router;a=e.recognizer.handlersFor(a);for(var g=0,d=a.length;gm)return 1;switch(f){case "boolean":case "number":return ag?1:0;case "string":return f=a.localeCompare(g),0>f?-1:0m?1:0;case "instance":return d&&d.detect(a)?a.compare(a,g):0;case "date":return f=a.getTime(), -m=g.getTime(),fm?1:0;default:return 0}}});t("ember-runtime/computed/array_computed","ember-metal/core ember-runtime/computed/reduce_computed ember-metal/enumerable_utils ember-metal/platform ember-metal/observer ember-metal/error exports".split(" "),function(a,m,n,f,l,k,d){function h(){var a=this;b.apply(this,arguments);this.func=function(b){return function(c){a._hasInstanceMeta(this,c)||w(a._dependentKeys,function(b){g(this,b,function(){a.recomputeOnce.call(this,c)})},this);return b.apply(this, -arguments)}}(this.func);return this}var c=a["default"],b=m.ReduceComputedProperty,g=l.addObserver,p=k["default"],u=[].slice;a=f.create;var w=n["default"].forEach;h.prototype=a(b.prototype);h.prototype.initialValue=function(){return c.A()};h.prototype.resetValue=function(a){a.clear();return a};h.prototype.didChange=function(a,b){};d.arrayComputed=function(a){var b;1b?Math.max(0,q+b):b=q)break;p=a.objectAt(f);T(r,d,this);f=new y(a,p,f,this.instanceMeta.propertyName,this.cp,c);this.setValue(g.call(this.instanceMeta.context,this.getValue(),p,f,this.instanceMeta.sugarMeta))}}},dependentArrayDidChange:function(a,b,c,g){if(!this.suspended){var d=this.callbacks.addedItem;c= -H(a);var f=this.dependentKeysByGuid[c],r=Array(g),q=this.cp._itemPropertyKeys[f];c=e(a,"length");var p=0>b?Math.max(0,c+b):barguments.length&&(e=C(a,"length"));3>arguments.length&&(c=0);if(c===e)return c;d=c+Math.floor((e-c)/2);f=a.objectAt(d);r=g(f);q=g(b);if(r===q)return d;f=this.order(f,b);0===f&&(f=rf?this.binarySearch(a,b,d+1,e):0a)return a}})};q.map=e;q.mapBy=r;q.mapProperty=r;q.filter=v;q.filterBy=y;q.filterProperty=y;q.uniq=A;q.union=A;q.intersect=function(){var a=function(a){return H.map(a.property._dependentKeys,function(a){return t(a)})},b=O.call(arguments);b.push({initialize:function(a,b,c){c.itemCounts={}},addedItem:function(b,c,e,g){var d=t(c);a(e);var f=t(e.arrayChanged);e=e.property._dependentKeys.length;g=g.itemCounts;g[d]||(g[d]={});void 0===g[d][f]&&(g[d][f]=0);1===++g[d][f]&&e===F(g[d]).length&& -b.addObject(c);return b},removedItem:function(b,c,e,g){var d=t(c);a(e);e=t(e.arrayChanged);g=g.itemCounts;void 0===g[d][e]&&(g[d][e]=0);0===--g[d][e]&&(delete g[d][e],e=F(g[d]).length,0===e&&delete g[d],b.removeObject(c));return b}});return I.apply(null,b)};q.setDiff=function(a,b){if(2!==arguments.length)throw new L("setDiff requires exactly two dependent arrays.");return I(a,b,{addedItem:function(c,e,g,d){d=C(this,a);var f=C(this,b);g.arrayChanged===d?f.contains(e)||c.addObject(e):c.removeObject(e); -return c},removedItem:function(c,e,g,d){d=C(this,a);var f=C(this,b);g.arrayChanged===f?d.contains(e)&&c.addObject(e):c.removeObject(e);return c}})};D=a.extend();q.sort=function(a,b){G.assert("Ember.computed.sort requires two arguments: an array key to sort and either a sort properties key or sort function",2===arguments.length);var c,e;"function"===typeof b?c=function(a,c,e){e.order=b;e.binarySearch=x}:(e=b,c=function(b,c,g){function d(){var b=C(this,e),r,q=g.sortProperties=[],p=g.sortPropertyAscending= -{},h,k;G.assert("Cannot sort: '"+e+"' is not an array.",E(b));c.property.clearItemPropertyKeys(a);R(b,function(b){-1!==(h=b.indexOf(":"))?(r=b.substring(0,h),k="desc"!==b.substring(h+1).toLowerCase()):(r=b,k=!0);q.push(r);p[r]=k;c.property.itemPropertyKey(a,r)});b.addObserver("@each",this,f)}function f(){K.once(this,r,c.propertyName)}function r(a){d.call(this);c.property.recomputeOnce.call(this,a)}Q(this,e,f);d.call(this);g.order=function(a,b){for(var c=b instanceof D,e,g,d=0;da&&(g=f[a]))return g;g="controller:"+c;if(!d.has(g))throw new u('Could not resolve itemController: "'+c+'"'); -c=this._isVirtual?p(this,"parentController"):this;g=d.lookupFactory(g).create({target:c,parentController:c,model:b});return f[a]=g},_subControllers:null,_resetSubControllers:function(){var a,b=this._subControllers;if(b.length){for(var c=0,g=b.length;g>c;c++)(a=b[c])&&a.destroy();b.length=0}},willDestroy:function(){this._resetSubControllers();this._super()}})});t("ember-runtime/controllers/controller","ember-metal/core ember-metal/property_get ember-runtime/system/object ember-metal/mixin ember-metal/computed ember-runtime/mixins/action_handler ember-runtime/mixins/controller_content_model_alias_deprecation exports".split(" "), -function(a,m,n,f,l,k,d,h){var c=a["default"];a=n["default"];f=f.Mixin.create(k["default"],d["default"],{isController:!0,target:null,container:null,parentController:null,store:null,model:null,content:l.computed.alias("model"),deprecatedSendHandles:function(a){return!!this[a]},deprecatedSend:function(a){var g=[].slice.call(arguments,1);c.assert(""+this+" has the action "+a+" but it is not a function","function"===typeof this[a]);c.deprecate("Action handlers implemented directly on controllers are deprecated in favor of action handlers on an `actions` object ( action: `"+ -a+"` on "+this+")",!1);this[a].apply(this,g)}});l=a.extend(f);h.Controller=l;h.ControllerMixin=f});t("ember-runtime/controllers/object_controller",["ember-runtime/controllers/controller","ember-runtime/system/object_proxy","exports"],function(a,m,n){n["default"]=m["default"].extend(a.ControllerMixin)});t("ember-runtime/copy","ember-metal/enumerable_utils ember-metal/utils ember-runtime/system/object ember-runtime/mixins/copyable ember-metal/platform exports".split(" "),function(a,m,n,f,l,k){function d(a, -f,k,l){var q,e,r;if("object"!==typeof a||null===a)return a;if(f&&0<=(e=g(k,a)))return l[e];D.assert("Cannot clone an Ember.Object that does not implement Ember.Copyable",!(a instanceof c)||b&&b.detect(a));if("array"===h(a)){if(q=a.slice(),f)for(e=q.length;0<=--e;)q[e]=d(q[e],f,k,l)}else if(b&&b.detect(a))q=a.copy(f,k,l);else if(a instanceof Date)q=new Date(a.getTime());else for(r in q={},a)a.hasOwnProperty(r)&&"__"!==r.substring(0,2)&&(q[r]=f?d(a[r],f,k,l):a[r]);f&&(k.push(a),l.push(q));return q} -var h=m.typeOf,c=n["default"],b=f["default"],g=a["default"].indexOf;k["default"]=function(a,c){return"object"!==typeof a||null===a?a:b&&b.detect(a)?a.copy(c):d(a,c,c?[]:null,c?[]:null)}});t("ember-runtime/core",["exports"],function(a){a.isEqual=function(a,n){return a&&"function"===typeof a.isEqual?a.isEqual(n):a instanceof Date&&n instanceof Date?a.getTime()===n.getTime():a===n}});t("ember-runtime/ext/function",["ember-metal/core","ember-metal/expand_properties","ember-metal/computed"],function(a, -m,n){var f=a["default"],l=m["default"],k=n.computed,d=Array.prototype.slice;a=Function.prototype;if(!0===f.EXTEND_PROTOTYPES||f.EXTEND_PROTOTYPES.Function)a.property=function(){var a=k(this);return a.property.apply(a,arguments)},a.observes=function(){for(var a=function(a){c.push(a)},c=[],b=0;ba||a>=w(this,"length")?void 0:w(this,a)},objectsAt:function(a){var b=this;return B(a,function(a){return b.objectAt(a)})},nextObject:function(a){return this.objectAt(a)}, -"[]":a(function(a,b){void 0!==b&&this.replace(0,w(this,"length"),b);return this}),firstObject:a(function(){return this.objectAt(0)}),lastObject:a(function(){return this.objectAt(w(this,"length")-1)}),contains:function(a){return 0<=this.indexOf(a)},slice:function(a,b){var c=u.A(),e=w(this,"length");q(a)&&(a=0);if(q(b)||b>e)b=e;0>a&&(a=e+a);for(0>b&&(b=e+b);ab&&(b+=e);for(c=b;c=c)b=c-1;0>b&&(b+=c);for(c=b;0<=c;c--)if(this.objectAt(c)===a)return c;return-1},addArrayObserver:function(a,b){var c=b&&b.willChange||"arrayWillChange",g=b&&b.didChange||"arrayDidChange",d=w(this,"hasArrayObservers");d||e(this,"hasArrayObservers");v(this,"@array:before",a,c);v(this,"@array:change",a,g);d||r(this,"hasArrayObservers");return this},removeArrayObserver:function(a,b){var c=b&&b.willChange||"arrayWillChange", -g=b&&b.didChange||"arrayDidChange",d=w(this,"hasArrayObservers");d&&e(this,"hasArrayObservers");y(this,"@array:before",a,c);y(this,"@array:change",a,g);d&&r(this,"hasArrayObservers");return this},hasArrayObservers:a(function(){return x(this,"@array:change")||x(this,"@array:before")}),arrayContentWillChange:function(a,b,c){void 0===a?(a=0,b=c=-1):(void 0===b&&(b=-1),void 0===c&&(c=-1));G(this,"@each")&&w(this,"@each");A(this,"@array:before",[this,a,b,c]);var e;if(0<=a&&0<=b&&w(this,"hasEnumerableObservers")){e= -[];for(b=a+b;aM(a,b)&&a.push(b)});return a},"[]":d(function(a,b){return this}),addEnumerableObserver:function(a,b){var c=b&&b.willChange||"enumerableWillChange",e=b&&b.didChange||"enumerableDidChange",g=q(this,"hasEnumerableObservers");g||v(this,"hasEnumerableObservers");A(this,"@enumerable:before",a,c);A(this,"@enumerable:change",a,e);g||y(this,"hasEnumerableObservers");return this},removeEnumerableObserver:function(a,b){var c= -b&&b.willChange||"enumerableWillChange",e=b&&b.didChange||"enumerableDidChange",g=q(this,"hasEnumerableObservers");g&&v(this,"hasEnumerableObservers");x(this,"@enumerable:before",a,c);x(this,"@enumerable:change",a,e);g&&y(this,"hasEnumerableObservers");return this},hasEnumerableObservers:d(function(){return B(this,"@enumerable:change")||B(this,"@enumerable:before")}),enumerableContentWillChange:function(a,b){var c,e;c="number"===typeof a?a:a?q(a,"length"):a=-1;e="number"===typeof b?b:b?q(b,"length"): -b=-1;c=0>e||0>c||0!==e-c;-1===a&&(a=null);-1===b&&(b=null);v(this,"[]");c&&v(this,"length");G(this,"@enumerable:before",[this,a,b]);return this},enumerableContentDidChange:function(a,b){var c,e;c="number"===typeof a?a:a?q(a,"length"):a=-1;e="number"===typeof b?b:b?q(b,"length"):b=-1;c=0>e||0>c||0!==e-c;-1===a&&(a=null);-1===b&&(b=null);G(this,"@enumerable:change",[this,a,b]);c&&y(this,"length");y(this,"[]");return this},sortBy:function(){var a=arguments;return this.toArray().sort(function(b,c){for(var e= -0;eg(this,"length"))throw new u("Index out of range");this.replace(a,0,[b]);return this},removeAt:function(a,c){if("number"===typeof a){if(0>a||a>=g(this,"length"))throw new u("Index out of range");void 0===c&&(c= -1);this.replace(a,c,b)}return this},pushObject:function(a){this.insertAt(g(this,"length"),a);return a},pushObjects:function(a){if(!w.detect(a)&&!p(a))throw new TypeError("Must pass Ember.Enumerable to Ember.MutableArray#pushObjects");this.replace(g(this,"length"),0,a);return this},popObject:function(){var a=g(this,"length");if(0===a)return null;var b=this.objectAt(a-1);this.removeAt(a-1,1);return b},shiftObject:function(){if(0===g(this,"length"))return null;var a=this.objectAt(0);this.removeAt(0); -return a},unshiftObject:function(a){this.insertAt(0,a);return a},unshiftObjects:function(a){this.replace(0,0,a);return this},reverseObjects:function(){var a=g(this,"length");if(0===a)return this;var b=this.toArray().reverse();this.replace(0,a,b);return this},setObjects:function(a){if(0===a.length)return this.clear();var b=g(this,"length");this.replace(0,b,a);return this},removeObject:function(a){for(var b=g(this,"length")||0;0<=--b;)this.objectAt(b)===a&&this.removeAt(b);return this},addObject:function(a){this.contains(a)|| -this.pushObject(a);return this}})});t("ember-runtime/mixins/mutable_enumerable",["ember-metal/enumerable_utils","ember-runtime/mixins/enumerable","ember-metal/mixin","ember-metal/property_events","exports"],function(a,m,n,f,l){var k=n.required,d=f.beginPropertyChanges,h=f.endPropertyChanges,c=a["default"].forEach;l["default"]=n.Mixin.create(m["default"],{addObject:k(Function),addObjects:function(a){d(this);c(a,function(a){this.addObject(a)},this);h(this);return this},removeObject:k(Function),removeObjects:function(a){d(this); -for(var c=a.length-1;0<=c;c--)this.removeObject(a[c]);h(this);return this}})});t("ember-runtime/mixins/observable","ember-metal/core ember-metal/property_get ember-metal/property_set ember-metal/utils ember-metal/get_properties ember-metal/set_properties ember-metal/mixin ember-metal/events ember-metal/property_events ember-metal/observer ember-metal/computed ember-metal/is_none exports".split(" "),function(a,m,n,f,l,k,d,h,c,b,g,p,u){var w=a["default"],s=m.get,q=m.getWithDefault,e=n.set,r=f.apply, -v=l["default"],y=k["default"],A=h.hasListeners,x=c.beginPropertyChanges,G=c.propertyWillChange,B=c.propertyDidChange,C=c.endPropertyChanges,t=b.addObserver,M=b.addBeforeObserver,L=b.removeObserver,H=b.observersFor,K=g.cacheFor,D=p.isNone,I=Array.prototype.slice;u["default"]=d.Mixin.create({get:function(a){return s(this,a)},getProperties:function(){return r(null,v,[this].concat(I.call(arguments)))},set:function(a,b){e(this,a,b);return this},setProperties:function(a){return y(this,a)},beginPropertyChanges:function(){x(); -return this},endPropertyChanges:function(){C();return this},propertyWillChange:function(a){G(this,a);return this},propertyDidChange:function(a){B(this,a);return this},notifyPropertyChange:function(a){this.propertyWillChange(a);this.propertyDidChange(a);return this},addBeforeObserver:function(a,b,c){M(this,a,b,c)},addObserver:function(a,b,c){t(this,a,b,c)},removeObserver:function(a,b,c){L(this,a,b,c)},hasObserverFor:function(a){return A(this,a+":change")},getWithDefault:function(a,b){return q(this, -a,b)},incrementProperty:function(a,b){D(b)&&(b=1);w.assert("Must pass a numeric value to incrementProperty",!isNaN(parseFloat(b))&&isFinite(b));e(this,a,(parseFloat(s(this,a))||0)+b);return s(this,a)},decrementProperty:function(a,b){D(b)&&(b=1);w.assert("Must pass a numeric value to decrementProperty",!isNaN(parseFloat(b))&&isFinite(b));e(this,a,(s(this,a)||0)-b);return s(this,a)},toggleProperty:function(a){e(this,a,!s(this,a));return s(this,a)},cacheFor:function(a){return K(this,a)},observersForKey:function(a){return H(this, -a)}})});t("ember-runtime/mixins/promise_proxy","ember-metal/property_get ember-metal/property_set ember-metal/computed ember-metal/mixin ember-metal/error exports".split(" "),function(a,m,n,f,l,k){function d(a,c){b(a,"isFulfilled",!1);b(a,"isRejected",!1);return c.then(function(c){b(a,"isFulfilled",!0);b(a,"content",c);return c},function(c){b(a,"isRejected",!0);b(a,"reason",c);throw c;},"Ember: PromiseProxy")}function h(a){return function(){var b=c(this,"promise");return b[a].apply(b,arguments)}} -var c=a.get,b=m.set;a=n.computed;var g=l["default"];l=a.not;m=a.or;k["default"]=f.Mixin.create({reason:null,isPending:l("isSettled").readOnly(),isSettled:m("isRejected","isFulfilled").readOnly(),isRejected:!1,isFulfilled:!1,promise:a(function(a,b){if(2===arguments.length)return d(this,b);throw new g("PromiseProxy's promise must be set");}),then:h("then"),"catch":h("catch"),"finally":h("finally")})});t("ember-runtime/mixins/sortable","ember-metal/core ember-metal/property_get ember-metal/property_set ember-metal/enumerable_utils ember-metal/mixin ember-runtime/mixins/mutable_enumerable ember-runtime/compare ember-metal/observer ember-metal/computed exports".split(" "), -function(a,m,n,f,l,k,d,h,c,b){var g=a["default"],p=m.get,u=h.addObserver,w=h.removeObserver;a=c.computed;m=l.beforeObserver;n=l.observer;var s=f["default"].forEach;b["default"]=l.Mixin.create(k["default"],{sortProperties:null,sortAscending:!0,sortFunction:d["default"],orderBy:function(a,b){var c=0,d=p(this,"sortProperties"),f=p(this,"sortAscending"),h=p(this,"sortFunction");g.assert("you need to define `sortProperties`",!!d);s(d,function(g){0===c&&(c=h.call(this,p(a,g),p(b,g)),0!==c&&!f&&(c*=-1))}, -this);return c},destroy:function(){var a=p(this,"content"),b=p(this,"sortProperties");a&&b&&s(a,function(a){s(b,function(b){w(a,b,this,"contentItemSortPropertyDidChange")},this)},this);return this._super()},isSorted:a.bool("sortProperties"),arrangedContent:a("content","sortProperties.@each",function(a,b){var c=p(this,"content"),d=p(this,"isSorted"),f=p(this,"sortProperties"),h=this;return c&&d?(c=c.slice(),c.sort(function(a,b){return h.orderBy(a,b)}),s(c,function(a){s(f,function(b){u(a,b,this,"contentItemSortPropertyDidChange")}, -this)},this),g.A(c)):c}),_contentWillChange:m("content",function(){var a=p(this,"content"),b=p(this,"sortProperties");a&&b&&s(a,function(a){s(b,function(b){w(a,b,this,"contentItemSortPropertyDidChange")},this)},this);this._super()}),sortPropertiesWillChange:m("sortProperties",function(){this._lastSortAscending=void 0}),sortPropertiesDidChange:n("sortProperties",function(){this._lastSortAscending=void 0}),sortAscendingWillChange:m("sortAscending",function(){this._lastSortAscending=p(this,"sortAscending")}), -sortAscendingDidChange:n("sortAscending",function(){void 0!==this._lastSortAscending&&p(this,"sortAscending")!==this._lastSortAscending&&p(this,"arrangedContent").reverseObjects()}),contentArrayWillChange:function(a,b,c,g){if(p(this,"isSorted")){var d=p(this,"arrangedContent"),f=a.slice(b,b+c),h=p(this,"sortProperties");s(f,function(a){d.removeObject(a);s(h,function(b){w(a,b,this,"contentItemSortPropertyDidChange")},this)},this)}return this._super(a,b,c,g)},contentArrayDidChange:function(a,b,c,g){var d= -p(this,"isSorted"),f=p(this,"sortProperties");d&&(d=a.slice(b,b+g),s(d,function(a){this.insertItemSorted(a);s(f,function(b){u(a,b,this,"contentItemSortPropertyDidChange")},this)},this));return this._super(a,b,c,g)},insertItemSorted:function(a){var b=p(this,"arrangedContent"),c=p(b,"length"),c=this._binarySearch(a,0,c);b.insertAt(c,a)},contentItemSortPropertyDidChange:function(a){var b=p(this,"arrangedContent"),c=b.indexOf(a),g=b.objectAt(c-1),c=b.objectAt(c+1),g=g&&this.orderBy(a,g),c=c&&this.orderBy(a, -c);if(0>g||0d?this._binarySearch(a,g+1,c):0 -s(this,"content.length"))throw new y("Index out of range");this._replace(a,0,[b]);return this},insertAt:function(a,b){if(s(this,"arrangedContent")===s(this,"content"))return this._insertAt(a,b);throw new y("Using insertAt on an arranged ArrayProxy is not allowed.");},removeAt:function(a,b){if("number"===typeof a){var c=s(this,"content"),e=s(this,"arrangedContent"),g=[],d;if(0>a||a>=s(this,"length"))throw new y("Index out of range");void 0===b&&(b=1);for(d=a;d";this.toString=y(a);return a}});l.PrototypeMixin.ownerConstructor=l;t.config.overridePrototypeMixin&&t.config.overridePrototypeMixin(l.PrototypeMixin);l.__super__=null;k=N.create({ClassMixin:a(),PrototypeMixin:a(),isClass:!0,isMethod:!1,extend:function(){var a=v(),b;a.ClassMixin=N.create(this.ClassMixin);a.PrototypeMixin=N.create(this.PrototypeMixin);a.ClassMixin.ownerConstructor= -a;a.PrototypeMixin.ownerConstructor=a;Z.apply(a.PrototypeMixin,arguments);a.superclass=this;a.__super__=this.prototype;b=a.prototype=Y(this.prototype);b.constructor=a;B(b);E(b).proto=b;a.ClassMixin.apply(a);return a},createWithMixins:function(){0=g;)if(r=a.objectAt(d))e.assert("When using @each to observe the array "+a+", the array must return an object","instance"===C(r)||"object"===C(r)),x(r,b,c,"contentKeyWillChange"),t(r,b,c,"contentKeyDidChange"),r=v(r),f[r]||(f[r]=[]),f[r].push(d)}function q(a,b,c,e,g){var d=c._objects;d||(d=c._objects={});for(var f;--g>=e;)if(f=a.objectAt(g))G(f,b,c,"contentKeyWillChange"),B(f,b,c,"contentKeyDidChange"), -f=v(f),f=d[f],f[y.call(f,g)]=null}var e=a["default"],r=m.get,v=f.guidFor,y=k.indexOf;a=h["default"];c=c.computed;var t=b.addObserver,x=b.addBeforeObserver,G=b.removeBeforeObserver,B=b.removeObserver,C=f.typeOf,E=g.watchedEvents,M=p.defineProperty,L=u.beginPropertyChanges,H=u.propertyDidChange,K=u.propertyWillChange,D=u.endPropertyChanges,I=u.changeProperties,N=l["default"].forEach,z=a.extend(d["default"],{init:function(a,b,c){this._super();this._keyName=b;this._owner=c;this._content=a},objectAt:function(a){return(a= -this._content.objectAt(a))&&r(a,this._keyName)},length:c(function(){var a=this._content;return a?r(a,"length"):0})}),F=/^.+:(before|change)$/;f=a.extend({init:function(a){this._super();this._content=a;a.addArrayObserver(this);N(E(this),function(a){this.didAddListener(a)},this)},unknownProperty:function(a,b){var c;c=new z(this._content,a,this);M(this,a,null,c);this.beginObservingContentKey(a);return c},arrayWillChange:function(a,b,c,e){e=this._keys;var g;c=0=--b[a]){var b=this._content,c=r(b,"length");q(b,a,this,0,c)}},contentKeyWillChange:function(a,b){K(this,b)},contentKeyDidChange:function(a,b){H(this,b)}});w.EachArray=z;w.EachProxy=f});t("ember-runtime/system/lazy_load",["ember-metal/core","ember-metal/array","ember-runtime/system/native_array","exports"],function(a,m,n,f){var l=a["default"],k=m.forEach,d=l.ENV.EMBER_LOAD_HOOKS|| -{},h={};f.onLoad=function(a,b){var g;d[a]=d[a]||l.A();d[a].pushObject(b);(g=h[a])&&b(g)};f.runLoadHooks=function(a,b){h[a]=b;if("object"===typeof window&&"function"===typeof window.dispatchEvent&&"function"===typeof CustomEvent){var g=new CustomEvent(a,{detail:b,name:a});window.dispatchEvent(g)}d[a]&&k.call(d[a],function(a){a(b)})}});t("ember-runtime/system/namespace","ember-metal/core ember-metal/property_get ember-metal/array ember-metal/utils ember-metal/mixin ember-runtime/system/object exports".split(" "), -function(a,m,n,f,l,k,d){function h(a,b,c){var d=a.length;v[a.join(".")]=b;for(var f in b)if(y.call(b,f)){var r=b[f];a[d]=f;r&&r.toString===g?(r.toString=u(a.join(".")),r[x]=a.join(".")):r&&r.isNamespace&&!c[e(r)]&&(c[e(r)]=!0,h(a,r,c))}a.length=d}function c(){var a=w.lookup,b,c;if(!r.PROCESSED)for(var e in a)if(t.test(e)&&(!a.hasOwnProperty||a.hasOwnProperty(e))){try{c=(b=a[e])&&b.isNamespace}catch(g){continue}c&&(b[x]=e)}}function b(a){if(a=a.superclass)return a[x]?a[x]:b(a)}function g(){!w.BOOTED&& -!this[x]&&p();var a;this[x]?a=this[x]:this._toString?a=this._toString:(a=(a=b(this))?"(subclass of "+a+")":"(unknown mixin)",this.toString=u(a));return a}function p(){var a=!r.PROCESSED,b=w.anyUnprocessedMixins;a&&(c(),r.PROCESSED=!0);if(a||b){for(var a=r.NAMESPACES,e=0,g=a.length;eb?Math.ceil(b):Math.floor(b);0>b&&(b+=e);for(c=b;cb?Math.ceil(b):Math.floor(b);0>b&&(b+=c);for(c=b;0<=c;c--)if(this[c]===a)return c;return-1},copy:function(a){return a?this.map(function(a){return q(a,!0)}):this.slice()}}),v=["length"];k(r.keys(),function(a){Array.prototype[a]&&v.push(a)});0",[c.join(",")])}})});t("ember-runtime/system/string",["ember-metal/core","ember-metal/utils","exports"],function(a,m,n){function f(a,b){if(!w(b)|| -2arguments.length&&(a=0);this._operations=0=q&&a<=e){g(k,f,q,e,r);return}k.type===c&&(r+=k.count)}d(r)},_composeAt:function(a){var c=this._operations[a],d;c&&(0arguments.length&&(a=[]);var g=d(a,"length");this._operations=g?[new l(c, -g,a)]:[]}function l(a,c,d){this.type=a;this.count=c;this.items=d}function k(a,c,d,f){this.operation=a;this.index=c;this.split=d;this.rangeStart=f}var d=a.get,h=m["default"].forEach,c="r";n["default"]=f;f.RETAIN=c;f.INSERT="i";f.DELETE="d";f.prototype={addItems:function(a,c){var f=d(c,"length");if(!(1>f)){var h=this._findArrayOperation(a),k=h.operation,m=h.index,q=h.rangeStart,f=new l("i",f,c);k?h.split?(this._split(m,a-q,f),h=m+1):(this._operations.splice(m,0,f),h=m):(this._operations.push(f),h=m); -this._composeInsert(h)}},removeItems:function(a,c){if(!(1>c)){var d=this._findArrayOperation(a),f=d.index,h=d.rangeStart,k;k=new l("d",c);d.split?(this._split(f,a-h,k),d=f+1):(this._operations.splice(f,0,k),d=f);return this._composeDelete(d)}},apply:function(a){var g=[],d=0;h(this._operations,function(c,f){a(c.items,d,c.type,f);"d"!==c.type&&(d+=c.count,g=g.concat(c.items))});this._operations=[new l(c,g.length,g)]},_findArrayOperation:function(a){var c,d,f=!1,h,l,q;c=l=0;for(d=this._operations.length;c< -d;++c)if(h=this._operations[c],"d"!==h.type)if(q=l+h.count-1,a===l)break;else if(a>l&&a<=q){f=!0;break}else l=q+1;return new k(h,c,f,l)},_split:function(a,c,d){var f=this._operations[a],h=f.items.slice(c),h=new l(f.type,h.length,h);f.count=c;f.items=f.items.slice(0,c);this._operations.splice(a+1,0,d,h)},_composeInsert:function(a){var c=this._operations[a],d=this._operations[a-1],f=this._operations[a+1],h=f&&f.type;"i"===(d&&d.type)?(d.count+=c.count,d.items=d.items.concat(c.items),"i"===h?(d.count+= -f.count,d.items=d.items.concat(f.items),this._operations.splice(a,2)):this._operations.splice(a,1)):"i"===h&&(c.count+=f.count,c.items=c.items.concat(f.items),this._operations.splice(a+1,1))},_composeDelete:function(a){var c=this._operations[a],d=c.count,f=this._operations[a-1],h,k,q=!1,e=[];"d"===(f&&f.type)&&(c=f,a-=1);for(var r=a+1;0d?(e=e.concat(f.items.splice(0,d)),f.count-=d,r-=1,k=d,d=0):(k===d&&(q=!0),e=e.concat(f.items), -d-=k),"i"===h&&(c.count-=k));0').css({position:"absolute",left:"-1000px",top:"-1000px"}).appendTo("body").on("click",a).trigger("click").remove()}var f=a["default"],l=m["default"];l(function(){n(function(){!this.checked&&!l.event.special.click&&(l.event.special.click={trigger:function(){if(l.nodeName(this, -"input")&&"checkbox"===this.type&&this.click)return this.click(),!1}})});n(function(){f.warn("clicked checkboxes should be checked! the jQuery patch didn't work",this.checked)})})});t("ember-testing/test","ember-metal/core ember-metal/run_loop ember-metal/platform ember-runtime/compare ember-runtime/ext/rsvp ember-testing/setup_for_testing ember-application/system/application exports".split(" "),function(a,m,n,f,l,k,d,h){function c(a,c){var e=v[c].method,d=v[c].meta;return function(){var c=r.call(arguments), -g=A.lastPromise;c.unshift(a);if(!d.wait)return e.apply(a,c);g?b(function(){g=A.resolve(g).then(function(){return e.apply(a,c)})}):g=e.apply(a,c);return g}}function b(a){w.currentRunLoop?a():w(a)}function g(a,b,c,e){a[b]=function(){var a=arguments;return e?c.apply(this,a):this.then(function(){return c.apply(this,a)})}}function p(a,c){var e,d;A.lastPromise=null;e=a(c);d=A.lastPromise;if(e&&e instanceof A.Promise||!d)return e;b(function(){d=A.resolve(d).then(function(){return e})});return d}var u=a["default"], -w=m["default"];a=n.create;var s=f["default"],q=l["default"],e=k["default"],r=[].slice,v={},t=[],A={registerHelper:function(a,b){v[a]={method:b,meta:{wait:!1}}},registerAsyncHelper:function(a,b){v[a]={method:b,meta:{wait:!0}}},unregisterHelper:function(a){delete v[a];delete A.Promise.prototype[a]},onInjectHelpers:function(a){t.push(a)},promise:function(a){return new A.Promise(a)},adapter:null,resolve:function(a){return A.promise(function(b){return b(a)})},registerWaiter:function(a,b){1===arguments.length&& -(b=a,a=null);this.waiters||(this.waiters=u.A());this.waiters.push([a,b])},unregisterWaiter:function(a,b){var c;this.waiters&&(1===arguments.length&&(b=a,a=null),c=[a,b],this.waiters=u.A(this.waiters.filter(function(a){return 0!==s(a,c)})))}};d["default"].reopen({testHelpers:{},originalMethods:{},testing:!1,setupForTesting:function(){e();this.testing=!0;this.Router.reopen({location:"none"})},helperContainer:window,injectTestHelpers:function(a){a&&(this.helperContainer=a);this.testHelpers={};for(var b in v)this.originalMethods[b]= -this.helperContainer[b],this.testHelpers[b]=this.helperContainer[b]=c(this,b),g(A.Promise.prototype,b,c(this,b),v[b].meta.wait);a=0;for(b=t.length;a":">",'"':""","'":"'","`":"`"};a=a.toString();return!q.test(a)?a:a.replace(s,function(a){return b[a]|| -"&"})}function b(a){this.tagNames=[a||null];this.buffer=""}var g=f.setInnerHTML,p=l["default"];d.prototype={add:function(a){a in this.seen||(this.seen[a]=!0,this.list.push(a))},toDOM:function(){return this.list.join(" ")}};var u=/[^a-zA-Z0-9\-]/,t=/[^a-zA-Z0-9\-]/g,s=/&(?!\w+;)|[<>"'`]/g,q=/[&<>"'`]/,e=function(){var a=document.createElement("div"),b=document.createElement("input");b.setAttribute("name","foo");a.appendChild(b);return!!a.innerHTML.match("foo")}();k["default"]=function(a){return new b(a)}; -b.prototype={_element:null,_hasElement:!0,elementClasses:null,classes:null,elementId:null,elementAttributes:null,elementProperties:null,elementTag:null,elementStyle:null,parentBuffer:null,push:function(a){this.buffer+=a;return this},addClass:function(a){this.elementClasses=this.elementClasses||new d;this.elementClasses.add(a);this.classes=this.elementClasses.list;return this},setClasses:function(a){this.elementClasses=null;var b=a.length,c;for(c=0;c"}},pushClosingTag:function(){var a=this.tagNames.pop();a&&(this.buffer+="")},currentTagName:function(){return this.tagNames[this.tagNames.length- -1]},generateElement:function(){var a=this.tagNames.pop(),b=this.elementId,d=this.classes,g=this.elementAttributes,f=this.elementProperties,q=this.elementStyle,k="",l,m,a=g&&g.name&&!e?"<"+h(a)+' name="'+c(g.name)+'">':a,a=document.createElement(a),n=p(a);b&&(n.attr("id",b),this.elementId=null);d&&(n.attr("class",d.join(" ")),this.elementClasses=this.classes=null);if(q){for(m in q)q.hasOwnProperty(m)&&(k+=m+":"+q[m]+";");n.attr("style",k);this.elementStyle=null}if(g){for(l in g)g.hasOwnProperty(l)&& -n.attr(l,g[l]);this.elementAttributes=null}if(f){for(m in f)f.hasOwnProperty(m)&&n.prop(m,f[m]);this.elementProperties=null}return a},element:function(){var a=this.innerString();a&&(this._element=g(this._element,a));return this._element},string:function(){if(this._hasElement&&this._element){var a=this.element(),b=a.outerHTML;return"undefined"===typeof b?p("
").append(a).html():b}return this.innerString()},innerString:function(){return this.buffer}}});t("ember-views/system/utils",["ember-metal/core", -"exports"],function(a,m){var n=a["default"],f="undefined"!==typeof document&&function(){var a=document.createElement("div");a.innerHTML="
";a.firstChild.innerHTML="";return testEl.firstChild.innerHTML===""}();var movesWhitespace=typeof document!=="undefined"&&function(){var testEl=document.createElement("div");testEl.innerHTML="Test: Value";return testEl.childNodes[0].nodeValue==="Test:"&&testEl.childNodes[2].nodeValue===" Value"}();var findChildById=function(element,id){if(element.getAttribute("id")===id){return element}var len=element.childNodes.length,idx,node,found;for(idx=0;idx0){var len=matches.length,idx;for(idx=0;idxTest');canSet=el.options.length===1}innerHTMLTags[tagName]=canSet;return canSet};function setInnerHTML(element,html){var tagName=element.tagName;if(canSetInnerHTML(tagName)){setInnerHTMLWithoutFix(element,html)}else{var outerHTML=element.outerHTML||(new XMLSerializer).serializeToString(element);var startTag=outerHTML.match(new RegExp("<"+tagName+"([^>]*)>","i"))[0],endTag="";var wrapper=document.createElement("div");setInnerHTMLWithoutFix(wrapper,startTag+html+endTag);element=wrapper.firstChild;while(element.tagName!==tagName){element=element.nextSibling}}return element}__exports__.setInnerHTML=setInnerHTML;function isSimpleClick(event){var modifier=event.shiftKey||event.metaKey||event.altKey||event.ctrlKey,secondaryClick=event.which>1;return!modifier&&!secondaryClick}__exports__.isSimpleClick=isSimpleClick});define("ember-views/views/collection_view",["ember-metal/core","ember-metal/platform","ember-metal/binding","ember-metal/merge","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/string","ember-views/views/container_view","ember-views/views/view","ember-metal/mixin","ember-runtime/mixins/array","exports"],function(__dependency1__,__dependency2__,__dependency3__,__dependency4__,__dependency5__,__dependency6__,__dependency7__,__dependency8__,__dependency9__,__dependency10__,__dependency11__,__exports__){"use strict";var Ember=__dependency1__["default"];var create=__dependency2__.create;var isGlobalPath=__dependency3__.isGlobalPath;var merge=__dependency4__["default"];var get=__dependency5__.get;var set=__dependency6__.set;var fmt=__dependency7__.fmt;var ContainerView=__dependency8__["default"];var CoreView=__dependency9__.CoreView;var View=__dependency9__.View;var observer=__dependency10__.observer;var beforeObserver=__dependency10__.beforeObserver;var EmberArray=__dependency11__["default"];var CollectionView=ContainerView.extend({content:null,emptyViewClass:View,emptyView:null,itemViewClass:View,init:function(){var ret=this._super();this._contentDidChange();return ret},_contentWillChange:beforeObserver("content",function(){var content=this.get("content");if(content){content.removeArrayObserver(this)}var len=content?get(content,"length"):0;this.arrayWillChange(content,0,len)}),_contentDidChange:observer("content",function(){var content=get(this,"content");if(content){this._assertArrayLike(content);content.addArrayObserver(this)}var len=content?get(content,"length"):0;this.arrayDidChange(content,0,null,len)}),_assertArrayLike:function(content){},destroy:function(){if(!this._super()){return}var content=get(this,"content");if(content){content.removeArrayObserver(this)}if(this._createdEmptyView){this._createdEmptyView.destroy()}return this},arrayWillChange:function(content,start,removedCount){var emptyView=get(this,"emptyView");if(emptyView&&emptyView instanceof View){emptyView.removeFromParent()}var childViews=this._childViews,childView,idx,len;len=this._childViews.length;var removingAll=removedCount===len;if(removingAll){this.currentState.empty(this);this.invokeRecursively(function(view){view.removedFromDOM=true},false)}for(idx=start+removedCount-1;idx>=start;idx--){childView=childViews[idx];childView.destroy()}},arrayDidChange:function(content,start,removed,added){var addedViews=[],view,item,idx,len,itemViewClass,emptyView;len=content?get(content,"length"):0;if(len){itemViewClass=get(this,"itemViewClass");if("string"===typeof itemViewClass&&isGlobalPath(itemViewClass)){itemViewClass=get(itemViewClass)||itemViewClass}for(idx=start;idx0){var changedViews=views.slice(start,start+removed);this.currentState.childViewsWillChange(this,views,start,removed);this.initializeViews(changedViews,null,null)}},removeChild:function(child){this.removeObject(child);return this},childViewsDidChange:function(views,start,removed,added){if(added>0){var changedViews=views.slice(start,start+added);this.initializeViews(changedViews,this,get(this,"templateData"));this.currentState.childViewsDidChange(this,views,start,added)}this.propertyDidChange("childViews")},initializeViews:function(views,parentView,templateData){forEach(views,function(view){set(view,"_parentView",parentView);if(!view.container&&parentView){set(view,"container",parentView.container)}if(!get(view,"templateData")){set(view,"templateData",templateData)}})},currentView:null,_currentViewWillChange:beforeObserver("currentView",function(){var currentView=get(this,"currentView");if(currentView){currentView.destroy()}}),_currentViewDidChange:observer("currentView",function(){var currentView=get(this,"currentView");if(currentView){this.pushObject(currentView)}}),_ensureChildrenAreInDOM:function(){this.currentState.ensureChildrenAreInDOM(this)}});merge(states._default,{childViewsWillChange:Ember.K,childViewsDidChange:Ember.K,ensureChildrenAreInDOM:Ember.K});merge(states.inBuffer,{childViewsDidChange:function(parentView,views,start,added){throw new EmberError("You cannot modify child views while in the inBuffer state")}});merge(states.hasElement,{childViewsWillChange:function(view,views,start,removed){for(var i=start;i=lengthBefore;i--){if(childViews[i]){childViews[i].destroy()}}},_applyClassNameBindings:function(classBindings){var classNames=this.classNames,elem,newClass,dasherizedClass;a_forEach(classBindings,function(binding){var oldClass;var parsedPath=View._parsePropertyPath(binding);var observer=function(){newClass=this._classStringForProperty(binding);elem=this.$();if(oldClass){elem.removeClass(oldClass);classNames.removeObject(oldClass)}if(newClass){elem.addClass(newClass);oldClass=newClass}else{oldClass=null}};dasherizedClass=this._classStringForProperty(binding);if(dasherizedClass){a_addObject(classNames,dasherizedClass);oldClass=dasherizedClass}this.registerObserver(this,parsedPath.path,observer);this.one("willClearRender",function(){if(oldClass){classNames.removeObject(oldClass);oldClass=null}})},this)},_unspecifiedAttributeBindings:null,_applyAttributeBindings:function(buffer,attributeBindings){var attributeValue,unspecifiedAttributeBindings=this._unspecifiedAttributeBindings=this._unspecifiedAttributeBindings||{};a_forEach(attributeBindings,function(binding){var split=binding.split(":"),property=split[0],attributeName=split[1]||property;if(property in this){this._setupAttributeBindingObservation(property,attributeName);attributeValue=get(this,property);View.applyAttributeBindings(buffer,attributeName,attributeValue)}else{unspecifiedAttributeBindings[property]=attributeName}},this);this.setUnknownProperty=this._setUnknownProperty},_setupAttributeBindingObservation:function(property,attributeName){var attributeValue,elem;var observer=function(){elem=this.$();attributeValue=get(this,property);View.applyAttributeBindings(elem,attributeName,attributeValue)};this.registerObserver(this,property,observer)},setUnknownProperty:null,_setUnknownProperty:function(key,value){var attributeName=this._unspecifiedAttributeBindings&&this._unspecifiedAttributeBindings[key];if(attributeName){this._setupAttributeBindingObservation(key,attributeName)}defineProperty(this,key);return set(this,key,value)},_classStringForProperty:function(property){var parsedPath=View._parsePropertyPath(property);var path=parsedPath.path;var val=get(this,path);if(val===undefined&&isGlobalPath(path)){val=get(Ember.lookup,path)}return View._classStringForValue(path,val,parsedPath.className,parsedPath.falsyClassName)},element:computed("_parentView",function(key,value){if(value!==undefined){return this.currentState.setElement(this,value)}else{return this.currentState.getElement(this)}}),$:function(sel){return this.currentState.$(this,sel)},mutateChildViews:function(callback){var childViews=this._childViews,idx=childViews.length,view;while(--idx>=0){view=childViews[idx];callback(this,view,idx)}return this},forEachChildView:function(callback){var childViews=this._childViews;if(!childViews){return this}var len=childViews.length,view,idx;for(idx=0;idx=0;i--){childViews[i].removedFromDOM=true}if(viewName&&nonVirtualParentView){nonVirtualParentView.set(viewName,null)}childLen=childViews.length;for(i=childLen-1;i>=0;i--){childViews[i].destroy()}return this},createChildView:function(view,attrs){if(!view){throw new TypeError("createChildViews first argument must exist")}if(view.isView&&view._parentView===this&&view.container===this.container){return view}attrs=attrs||{};attrs._parentView=this;if(CoreView.detect(view)){attrs.templateData=attrs.templateData||get(this,"templateData");attrs.container=this.container;view=view.create(attrs);if(view.viewName){set(get(this,"concreteView"),view.viewName,view)}}else if("string"===typeof view){var fullName="view:"+view;var ViewKlass=this.container.lookupFactory(fullName);attrs.templateData=get(this,"templateData");view=ViewKlass.create(attrs)}else{attrs.container=this.container;if(!get(view,"templateData")){attrs.templateData=get(this,"templateData")}setProperties(view,attrs)}return view},becameVisible:Ember.K,becameHidden:Ember.K,_isVisibleDidChange:observer("isVisible",function(){if(this._isVisible===get(this,"isVisible")){return}run.scheduleOnce("render",this,this._toggleVisibility)}),_toggleVisibility:function(){var $el=this.$();if(!$el){return}var isVisible=get(this,"isVisible");if(this._isVisible===isVisible){return}$el.toggle(isVisible);this._isVisible=isVisible;if(this._isAncestorHidden()){return -}if(isVisible){this._notifyBecameVisible()}else{this._notifyBecameHidden()}},_notifyBecameVisible:function(){this.trigger("becameVisible");this.forEachChildView(function(view){var isVisible=get(view,"isVisible");if(isVisible||isVisible===null){view._notifyBecameVisible()}})},_notifyBecameHidden:function(){this.trigger("becameHidden");this.forEachChildView(function(view){var isVisible=get(view,"isVisible");if(isVisible||isVisible===null){view._notifyBecameHidden()}})},_isAncestorHidden:function(){var parent=get(this,"parentView");while(parent){if(get(parent,"isVisible")===false){return true}parent=get(parent,"parentView")}return false},clearBuffer:function(){this.invokeRecursively(nullViewsBuffer)},transitionTo:function(state,children){var priorState=this.currentState,currentState=this.currentState=this._states[state];this._state=state;if(priorState&&priorState.exit){priorState.exit(this)}if(currentState.enter){currentState.enter(this)}if(state==="inDOM"){meta(this).cache.element=undefined}if(children!==false){this.forEachChildView(function(view){view.transitionTo(state)})}},handleEvent:function(eventName,evt){return this.currentState.handleEvent(this,eventName,evt)},registerObserver:function(root,path,target,observer){if(!observer&&"function"===typeof target){observer=target;target=null}if(!root||typeof root!=="object"){return}var view=this,stateCheckedObserver=function(){view.currentState.invokeObserver(this,observer)},scheduledObserver=function(){run.scheduleOnce("render",this,stateCheckedObserver)};addObserver(root,path,target,scheduledObserver);this.one("willClearRender",function(){removeObserver(root,path,target,scheduledObserver)})}});function notifyMutationListeners(){run.once(View,"notifyMutationListeners")}var DOMManager={prepend:function(view,html){view.$().prepend(html);notifyMutationListeners()},after:function(view,html){view.$().after(html);notifyMutationListeners()},html:function(view,html){view.$().html(html);notifyMutationListeners()},replace:function(view){var element=get(view,"element");set(view,"element",null);view._insertElementLater(function(){jQuery(element).replaceWith(get(view,"element"));notifyMutationListeners()})},remove:function(view){view.$().remove();notifyMutationListeners()},empty:function(view){view.$().empty();notifyMutationListeners()}};View.reopen({domManager:DOMManager});View.reopenClass({_parsePropertyPath:function(path){var split=path.split(":"),propertyPath=split[0],classNames="",className,falsyClassName;if(split.length>1){className=split[1];if(split.length===3){falsyClassName=split[2]}classNames=":"+className;if(falsyClassName){classNames+=":"+falsyClassName}}return{path:propertyPath,classNames:classNames,className:className===""?undefined:className,falsyClassName:falsyClassName}},_classStringForValue:function(path,val,className,falsyClassName){if(isArray(val)){val=get(val,"length")!==0}if(className||falsyClassName){if(className&&!!val){return className}else if(falsyClassName&&!val){return falsyClassName}else{return null}}else if(val===true){var parts=path.split(".");return dasherize(parts[parts.length-1])}else if(val!==false&&val!=null){return val}else{return null}}});var mutation=EmberObject.extend(Evented).create();View.addMutationListener=function(callback){mutation.on("change",callback)};View.removeMutationListener=function(callback){mutation.off("change",callback)};View.notifyMutationListeners=function(){mutation.trigger("change")};View.views={};View.childViewsProperty=childViewsProperty;View.applyAttributeBindings=function(elem,name,value){var type=typeOf(value);if(name!=="value"&&(type==="string"||type==="number"&&!isNaN(value))){if(value!==elem.attr(name)){elem.attr(name,value)}}else if(name==="value"||type==="boolean"){if(isNone(value)||value===false){elem.removeAttr(name);elem.prop(name,"")}else if(value!==elem.prop(name)){elem.prop(name,value)}}else if(!value){elem.removeAttr(name)}};__exports__.CoreView=CoreView;__exports__.View=View;__exports__.ViewCollection=ViewCollection});define("ember",["ember-metal","ember-runtime","ember-handlebars","ember-views","ember-routing","ember-application","ember-extension-support"],function(__dependency1__,__dependency2__,__dependency3__,__dependency4__,__dependency5__,__dependency6__,__dependency7__){"use strict";if(Ember.__loader.registry["ember-testing"]){requireModule("ember-testing")}function throwWithMessage(msg){return function(){throw new Ember.Error(msg)}}function generateRemovedClass(className){var msg=" has been moved into a plugin: https://github.com/emberjs/ember-states";return{extend:throwWithMessage(className+msg),create:throwWithMessage(className+msg)}}Ember.StateManager=generateRemovedClass("Ember.StateManager");Ember.State=generateRemovedClass("Ember.State")});define("metamorph",[],function(){"use strict";var K=function(){},guid=0,disableRange=function(){if("undefined"!==typeof MetamorphENV){return MetamorphENV.DISABLE_RANGE_API}else if("undefined"!==ENV){return ENV.DISABLE_RANGE_API}else{return false}}(),supportsRange=!disableRange&&typeof document!=="undefined"&&"createRange"in document&&typeof Range!=="undefined"&&Range.prototype.createContextualFragment,needsShy=typeof document!=="undefined"&&function(){var testEl=document.createElement("div");testEl.innerHTML="
";testEl.firstChild.innerHTML="";return testEl.firstChild.innerHTML===""}(),movesWhitespace=document&&function(){var testEl=document.createElement("div");testEl.innerHTML="Test: Value";return testEl.childNodes[0].nodeValue==="Test:"&&testEl.childNodes[2].nodeValue===" Value"}();var Metamorph=function(html){var self;if(this instanceof Metamorph){self=this}else{self=new K}self.innerHTML=html;var myGuid="metamorph-"+guid++;self.start=myGuid+"-start";self.end=myGuid+"-end";return self};K.prototype=Metamorph.prototype;var rangeFor,htmlFunc,removeFunc,outerHTMLFunc,appendToFunc,afterFunc,prependFunc,startTagFunc,endTagFunc;outerHTMLFunc=function(){return this.startTag()+this.innerHTML+this.endTag()};startTagFunc=function(){return""};endTagFunc=function(){return""};if(supportsRange){rangeFor=function(morph,outerToo){var range=document.createRange();var before=document.getElementById(morph.start);var after=document.getElementById(morph.end);if(outerToo){range.setStartBefore(before);range.setEndAfter(after)}else{range.setStartAfter(before);range.setEndBefore(after)}return range};htmlFunc=function(html,outerToo){var range=rangeFor(this,outerToo);range.deleteContents();var fragment=range.createContextualFragment(html);range.insertNode(fragment)};removeFunc=function(){var range=rangeFor(this,true);range.deleteContents()};appendToFunc=function(node){var range=document.createRange();range.setStart(node);range.collapse(false);var frag=range.createContextualFragment(this.outerHTML());node.appendChild(frag)};afterFunc=function(html){var range=document.createRange();var after=document.getElementById(this.end);range.setStartAfter(after);range.setEndAfter(after);var fragment=range.createContextualFragment(html);range.insertNode(fragment)};prependFunc=function(html){var range=document.createRange();var start=document.getElementById(this.start);range.setStartAfter(start);range.setEndAfter(start);var fragment=range.createContextualFragment(html);range.insertNode(fragment)}}else{var wrapMap={select:[1,""],fieldset:[1,"
","
"],table:[1,"","
"],tbody:[2,"","
"],tr:[3,"","
"],colgroup:[2,"","
"],map:[1,"",""],_default:[0,"",""]};var findChildById=function(element,id){if(element.getAttribute("id")===id){return element}var len=element.childNodes.length,idx,node,found;for(idx=0;idx0){var len=matches.length,idx;for(idx=0;idx2&&key.slice(keyLength-2)==="[]"){isArray=true;key=key.slice(0,keyLength-2);if(!queryParams[key]){queryParams[key]=[]}}value=pair[1]?decodeURIComponent(pair[1]):""}if(isArray){queryParams[key].push(value)}else{queryParams[key]=decodeURIComponent(value)}}return queryParams},recognize:function(path){var states=[this.rootState],pathLen,i,l,queryStart,queryParams={},isSlashDropped=false;path=decodeURI(path);queryStart=path.indexOf("?");if(queryStart!==-1){var queryString=path.substr(queryStart+1,path.length);path=path.substr(0,queryStart);queryParams=this.parseQueryString(queryString)}if(path.charAt(0)!=="/"){path="/"+path}pathLen=path.length;if(pathLen>1&&path.charAt(pathLen-1)==="/"){path=path.substr(0,pathLen-1);isSlashDropped=true}for(i=0,l=path.length;i=0&&proceed;--i){var route=routes[i];recognizer.add(routes,{as:route.handler});proceed=route.path==="/"||route.path===""||route.handler.slice(-6)===".index"}})},hasRoute:function(route){return this.recognizer.hasRoute(route)},transitionByIntent:function(intent,isIntermediate){var wasTransitioning=!!this.activeTransition;var oldState=wasTransitioning?this.activeTransition.state:this.state;var newTransition;var router=this;try{var newState=intent.applyToState(oldState,this.recognizer,this.getHandler,isIntermediate);if(handlerInfosEqual(newState.handlerInfos,oldState.handlerInfos)){var queryParamChangelist=getChangelist(oldState.queryParams,newState.queryParams);if(queryParamChangelist){this._changedQueryParams=queryParamChangelist.changed;for(var k in queryParamChangelist.removed){if(queryParamChangelist.removed.hasOwnProperty(k)){this._changedQueryParams[k]=null}}trigger(this,newState.handlerInfos,true,["queryParamsDidChange",queryParamChangelist.changed,queryParamChangelist.all,queryParamChangelist.removed]);this._changedQueryParams=null;if(!wasTransitioning&&this.activeTransition){return this.activeTransition}else{newTransition=new Transition(this);oldState.queryParams=finalizeQueryParamChange(this,newState.handlerInfos,newState.queryParams,newTransition);newTransition.promise=newTransition.promise.then(function(result){updateURL(newTransition,oldState,true);if(router.didTransition){router.didTransition(router.currentHandlerInfos)}return result},null,promiseLabel("Transition complete"));return newTransition}}return new Transition(this)}if(isIntermediate){setupContexts(this,newState);return}newTransition=new Transition(this,intent,newState);if(this.activeTransition){this.activeTransition.abort() -}this.activeTransition=newTransition;newTransition.promise=newTransition.promise.then(function(result){return finalizeTransition(newTransition,result.state)},null,promiseLabel("Settle transition promise when transition is finalized"));if(!wasTransitioning){notifyExistingHandlers(this,newState,newTransition)}return newTransition}catch(e){return new Transition(this,intent,null,e)}},reset:function(){if(this.state){forEach(this.state.handlerInfos,function(handlerInfo){var handler=handlerInfo.handler;if(handler.exit){handler.exit()}})}this.state=new TransitionState;this.currentHandlerInfos=null},activeTransition:null,handleURL:function(url){var args=slice.call(arguments);if(url.charAt(0)!=="/"){args[0]="/"+url}return doTransition(this,args).method(null)},updateURL:function(){throw new Error("updateURL is not implemented")},replaceURL:function(url){this.updateURL(url)},transitionTo:function(name){return doTransition(this,arguments)},intermediateTransitionTo:function(name){doTransition(this,arguments,true)},refresh:function(pivotHandler){var state=this.activeTransition?this.activeTransition.state:this.state;var handlerInfos=state.handlerInfos;var params={};for(var i=0,len=handlerInfos.length;i=0;--i){var handlerInfo=handlerInfos[i];merge(params,handlerInfo.params);if(handlerInfo.handler.inaccessibleByURL){urlMethod=null}}if(urlMethod){params.queryParams=transition._visibleQueryParams||state.queryParams;var url=router.recognizer.generate(handlerName,params);if(urlMethod==="replace"){router.replaceURL(url)}else{router.updateURL(url)}}}function finalizeTransition(transition,newState){try{log(transition.router,transition.sequence,"Resolved all models on destination route; finalizing transition.");var router=transition.router,handlerInfos=newState.handlerInfos,seq=transition.sequence;setupContexts(router,newState,transition);if(transition.isAborted){router.state.handlerInfos=router.currentHandlerInfos;return Promise.reject(logAbort(transition))}updateURL(transition,newState,transition.intent.url);transition.isActive=false;router.activeTransition=null;trigger(router,router.currentHandlerInfos,true,["didTransition"]);if(router.didTransition){router.didTransition(router.currentHandlerInfos)}log(router,transition.sequence,"TRANSITION COMPLETE.");return handlerInfos[handlerInfos.length-1].handler}catch(e){if(!(e instanceof TransitionAborted)){var infos=transition.state.handlerInfos;transition.trigger(true,"error",e,transition,infos[infos.length-1].handler);transition.abort()}throw e}}function doTransition(router,args,isIntermediate){var name=args[0]||"/";var lastArg=args[args.length-1];var queryParams={};if(lastArg&&lastArg.hasOwnProperty("queryParams")){queryParams=pop.call(args).queryParams}var intent;if(args.length===0){log(router,"Updating query params");var handlerInfos=router.state.handlerInfos;intent=new NamedTransitionIntent({name:handlerInfos[handlerInfos.length-1].name,contexts:[],queryParams:queryParams})}else if(name.charAt(0)==="/"){log(router,"Attempting URL transition to "+name);intent=new URLTransitionIntent({url:name})}else{log(router,"Attempting transition to "+name);intent=new NamedTransitionIntent({name:args[0],contexts:slice.call(args,1),queryParams:queryParams})}return router.transitionByIntent(intent,isIntermediate)}function handlerInfosEqual(handlerInfos,otherHandlerInfos){if(handlerInfos.length!==otherHandlerInfos.length){return false}for(var i=0,len=handlerInfos.length;i0){router._triggerWillChangeContext(changing,newTransition)}trigger(router,oldHandlers,true,["willTransition",newTransition])}__exports__["default"]=Router});define("router/transition-intent",["./utils","exports"],function(__dependency1__,__exports__){"use strict";var merge=__dependency1__.merge;function TransitionIntent(props){this.initialize(props);this.data=this.data||{}}TransitionIntent.prototype={initialize:null,applyToState:null};__exports__["default"]=TransitionIntent});define("router/transition-intent/named-transition-intent",["../transition-intent","../transition-state","../handler-info/factory","../utils","exports"],function(__dependency1__,__dependency2__,__dependency3__,__dependency4__,__exports__){"use strict";var TransitionIntent=__dependency1__["default"];var TransitionState=__dependency2__["default"];var handlerInfoFactory=__dependency3__["default"];var isParam=__dependency4__.isParam;var extractQueryParams=__dependency4__.extractQueryParams;var merge=__dependency4__.merge;var subclass=__dependency4__.subclass;__exports__["default"]=subclass(TransitionIntent,{name:null,pivotHandler:null,contexts:null,queryParams:null,initialize:function(props){this.name=props.name;this.pivotHandler=props.pivotHandler;this.contexts=props.contexts||[];this.queryParams=props.queryParams},applyToState:function(oldState,recognizer,getHandler,isIntermediate){var partitionedArgs=extractQueryParams([this.name].concat(this.contexts)),pureArgs=partitionedArgs[0],queryParams=partitionedArgs[1],handlers=recognizer.handlersFor(pureArgs[0]);var targetRouteName=handlers[handlers.length-1].handler;return this.applyToHandlers(oldState,handlers,getHandler,targetRouteName,isIntermediate)},applyToHandlers:function(oldState,handlers,getHandler,targetRouteName,isIntermediate,checkingIfActive){var i;var newState=new TransitionState;var objects=this.contexts.slice(0);var invalidateIndex=handlers.length;if(this.pivotHandler){for(i=0;i=0;--i){var result=handlers[i];var name=result.handler;var handler=getHandler(name);var oldHandlerInfo=oldState.handlerInfos[i];var newHandlerInfo=null;if(result.names.length>0){if(i>=invalidateIndex){newHandlerInfo=this.createParamHandlerInfo(name,handler,result.names,objects,oldHandlerInfo)}else{newHandlerInfo=this.getHandlerInfoForDynamicSegment(name,handler,result.names,objects,oldHandlerInfo,targetRouteName,i)}}else{newHandlerInfo=this.createParamHandlerInfo(name,handler,result.names,objects,oldHandlerInfo)}if(checkingIfActive){newHandlerInfo=newHandlerInfo.becomeResolved(null,newHandlerInfo.context);var oldContext=oldHandlerInfo&&oldHandlerInfo.context;if(result.names.length>0&&newHandlerInfo.context===oldContext){newHandlerInfo.params=oldHandlerInfo&&oldHandlerInfo.params}newHandlerInfo.context=oldContext}var handlerToUse=oldHandlerInfo;if(i>=invalidateIndex||newHandlerInfo.shouldSupercede(oldHandlerInfo)){invalidateIndex=Math.min(i,invalidateIndex);handlerToUse=newHandlerInfo}if(isIntermediate&&!checkingIfActive){handlerToUse=handlerToUse.becomeResolved(null,handlerToUse.context)}newState.handlerInfos.unshift(handlerToUse)}if(objects.length>0){throw new Error("More context objects were passed than there are dynamic segments for the route: "+targetRouteName)}if(!isIntermediate){this.invalidateChildren(newState.handlerInfos,invalidateIndex)}merge(newState.queryParams,oldState.queryParams);merge(newState.queryParams,this.queryParams||{});return newState},invalidateChildren:function(handlerInfos,invalidateIndex){for(var i=invalidateIndex,l=handlerInfos.length;i0){objectToUse=objects[objects.length-1];if(isParam(objectToUse)){return this.createParamHandlerInfo(name,handler,names,objects,oldHandlerInfo)}else{objects.pop()}}else if(oldHandlerInfo&&oldHandlerInfo.name===name){return oldHandlerInfo}else{if(this.preTransitionState){var preTransitionHandlerInfo=this.preTransitionState.handlerInfos[i];objectToUse=preTransitionHandlerInfo&&preTransitionHandlerInfo.context}else{return oldHandlerInfo}}return handlerInfoFactory("object",{name:name,handler:handler,context:objectToUse,names:names})},createParamHandlerInfo:function(name,handler,names,objects,oldHandlerInfo){var params={};var numNames=names.length;while(numNames--){var oldParams=oldHandlerInfo&&name===oldHandlerInfo.name&&oldHandlerInfo.params||{};var peek=objects[objects.length-1];var paramName=names[numNames];if(isParam(peek)){params[paramName]=""+objects.pop()}else{if(oldParams.hasOwnProperty(paramName)){params[paramName]=oldParams[paramName]}else{throw new Error("You didn't provide enough string/numeric parameters to satisfy all of the dynamic segments for route "+name)}}}return handlerInfoFactory("param",{name:name,handler:handler,params:params})}})});define("router/transition-intent/url-transition-intent",["../transition-intent","../transition-state","../handler-info/factory","../utils","exports"],function(__dependency1__,__dependency2__,__dependency3__,__dependency4__,__exports__){"use strict";var TransitionIntent=__dependency1__["default"];var TransitionState=__dependency2__["default"];var handlerInfoFactory=__dependency3__["default"];var oCreate=__dependency4__.oCreate;var merge=__dependency4__.merge;var subclass=__dependency4__.subclass;__exports__["default"]=subclass(TransitionIntent,{url:null,initialize:function(props){this.url=props.url},applyToState:function(oldState,recognizer,getHandler){var newState=new TransitionState;var results=recognizer.recognize(this.url),queryParams={},i,len;if(!results){throw new UnrecognizedURLError(this.url)}var statesDiffer=false;for(i=0,len=results.length;i=handlerInfos.length?handlerInfos.length-1:payload.resolveIndex;return Promise.reject({error:error,handlerWithError:currentState.handlerInfos[errorHandlerIndex].handler,wasAborted:wasAborted,state:currentState})}function proceed(resolvedHandlerInfo){var wasAlreadyResolved=currentState.handlerInfos[payload.resolveIndex].isResolved;currentState.handlerInfos[payload.resolveIndex++]=resolvedHandlerInfo;if(!wasAlreadyResolved){var handler=resolvedHandlerInfo.handler;if(handler&&handler.redirect){handler.redirect(resolvedHandlerInfo.context,payload)}}return innerShouldContinue().then(resolveOneHandlerInfo,null,promiseLabel("Resolve handler"))}function resolveOneHandlerInfo(){if(payload.resolveIndex===currentState.handlerInfos.length){return{error:null,state:currentState}}var handlerInfo=currentState.handlerInfos[payload.resolveIndex];return handlerInfo.resolve(innerShouldContinue,payload).then(proceed,null,promiseLabel("Proceed"))}}};__exports__["default"]=TransitionState});define("router/transition",["rsvp/promise","./handler-info","./utils","exports"],function(__dependency1__,__dependency2__,__dependency3__,__exports__){"use strict";var Promise=__dependency1__["default"];var ResolvedHandlerInfo=__dependency2__.ResolvedHandlerInfo;var trigger=__dependency3__.trigger;var slice=__dependency3__.slice;var log=__dependency3__.log;var promiseLabel=__dependency3__.promiseLabel;function Transition(router,intent,state,error){var transition=this;this.state=state||router.state;this.intent=intent;this.router=router;this.data=this.intent&&this.intent.data||{};this.resolvedModels={};this.queryParams={};if(error){this.promise=Promise.reject(error);return}if(state){this.params=state.params;this.queryParams=state.queryParams;var len=state.handlerInfos.length;if(len){this.targetName=state.handlerInfos[state.handlerInfos.length-1].name}for(var i=0;i0&&array[len-1]&&array[len-1].hasOwnProperty("queryParams")){queryParams=array[len-1].queryParams;head=slice.call(array,0,len-1);return[head,queryParams]}else{return[array,null]}}__exports__.extractQueryParams=extractQueryParams;function coerceQueryParamsToString(queryParams){for(var key in queryParams){if(typeof queryParams[key]==="number"){queryParams[key]=""+queryParams[key]}else if(isArray(queryParams[key])){for(var i=0,l=queryParams[key].length;i=0;i--){var handlerInfo=handlerInfos[i],handler=handlerInfo.handler;if(handler.events&&handler.events[name]){if(handler.events[name].apply(handler,args)===true){eventWasHandled=true}else{return}}}if(!eventWasHandled&&!ignoreFailure){throw new Error("Nothing handled the event '"+name+"'.")}}__exports__.trigger=trigger;function getChangelist(oldObject,newObject){var key;var results={all:{},changed:{},removed:{}};merge(results.all,newObject);var didChange=false;coerceQueryParamsToString(oldObject);coerceQueryParamsToString(newObject);for(key in oldObject){if(oldObject.hasOwnProperty(key)){if(!newObject.hasOwnProperty(key)){didChange=true;results.removed[key]=oldObject[key]}}}for(key in newObject){if(newObject.hasOwnProperty(key)){if(isArray(oldObject[key])&&isArray(newObject[key])){if(oldObject[key].length!==newObject[key].length){results.changed[key]=newObject[key];didChange=true}else{for(var i=0,l=oldObject[key].length;i":">",'"':""","'":"'","`":"`",'=':'='},a=/[&<>"'`=]/g,c=/[&<>"'`=]/;g.extend=function(a,b){for(var k in b)Object.prototype.hasOwnProperty.call(b,k)&&(a[k]=b[k])};var d=Object.prototype.toString;g.toString=d;var e=function(a){return"function"===typeof a};e(/x/)&&(e=function(a){return"function"=== -typeof a&&"[object Function]"===d.call(a)});g.isFunction=e;var x=Array.isArray||function(a){return a&&"object"===typeof a?"[object Array]"===d.call(a):!1};g.isArray=x;g.escapeExpression=function(b){if(b instanceof l)return b.toString();if(!b&&0!==b)return"";b=""+b;return!c.test(b)?b:b.replace(a,h)};g.isEmpty=function(a){return!a&&0!==a?!0:x(a)&&0===a.length?!0:!1};return g}(y),p=function(){function l(g,b){var a;b&&b.firstLine&&(a=b.firstLine,g+=" - "+a+":"+b.firstColumn);for(var c=Error.prototype.constructor.call(this, -g),d=0;d= 1.0.0"};var x=d.isArray,f=d.isFunction,r=d.toString;c.HandlebarsEnvironment=g;g.prototype={constructor:g,logger:k,log:a,registerHelper:function(a,b,k){if("[object Object]"===r.call(a)){if(k||b)throw new e("Arg not supported with multiple helpers");d.extend(this.helpers,a)}else k&&(b.not=k),this.helpers[a]=b},registerPartial:function(a,b){"[object Object]"===r.call(a)?d.extend(this.partials,a):this.partials[a]=b}};var k= -{methodMap:{0:"debug",1:"info",2:"warn",3:"error"},DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,log:function(a,b){if(k.level<=a){var c=k.methodMap[a];"undefined"!==typeof console&&console[c]&&console[c].call(console,b)}}};c.logger=k;c.log=a;var n=function(a){var b={};d.extend(b,a);return b};c.createFrame=n;return c}(v,p),A=function(l,h,g){function b(a,b,c){var d=function(a,n){n=n||{};return b(a,n.data||c)};d.program=a;d.depth=0;return d}var a={},c=g.COMPILER_REVISION,d=g.REVISION_CHANGES;a.checkRevision= -function(a){var b=a&&a[0]||1;if(b!==c){if(ba.length&&(a+=this._input.substr(0, -20-a.length));return(a.substr(0,20)+(20a[0].length))if(a=b,d=g,!this.options.flex)break;if(a){if(b=a[0].match(/(?:\r\n?|\n).*/g))this.yylineno+= -b.length;this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:b?b[b.length-1].length-b[b.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+a[0].length};this.yytext+=a[0];this.match+=a[0];this.matches=a;this.yyleng=this.yytext.length;this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]);this._more=!1;this._input=this._input.slice(a[0].length);this.matched+=a[0];a=this.performAction.call(this,this.yy, -this,e[d],this.conditionStack[this.conditionStack.length-1]);this.done&&this._input&&(this.done=!1);if(a)return a}else return""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var a=this.next();return"undefined"!==typeof a?a:this.lex()},begin:function(a){this.conditionStack.push(a)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length- -1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(a){this.begin(a)},options:{},performAction:function(a,b,d,e){function g(a,d){return b.yytext=b.yytext.substr(a,b.yyleng-d)}switch(d){case 0:"\\\\"===b.yytext.slice(-2)?(g(0,1),this.begin("mu")):"\\"===b.yytext.slice(-1)?(g(0,1),this.begin("emu")):this.begin("mu");if(b.yytext)return 14;break;case 1:return 14;case 2:return this.popState(),14;case 3:return g(0,4),this.popState(),15;case 4:return 35; -case 5:return 36;case 6:return 25;case 7:return 16;case 8:return 20;case 9:return 19;case 10:return 19;case 11:return 23;case 12:return 22;case 13:this.popState();this.begin("com");break;case 14:return g(3,5),this.popState(),15;case 15:return 22;case 16:return 41;case 17:return 40;case 18:return 40;case 19:return 44;case 21:return this.popState(),24;case 22:return this.popState(),18;case 23:return b.yytext=g(1,2).replace(/\\"/g,'"'),32;case 24:return b.yytext=g(1,2).replace(/\\'/g,"'"),32;case 25:return 42; -case 26:return 34;case 27:return 34;case 28:return 33;case 29:return 40;case 30:return b.yytext=g(1,2),40;case 31:return"INVALID";case 32:return 5}},rules:[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/, -/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/],conditions:{mu:{rules:[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[3],inclusive:!1},INITIAL:{rules:[0,1,32],inclusive:!0}}}}(); -g.lexer=b;h.prototype=g;g.Parser=h;return new h}()}(),v),B=function(l){function h(){}var g={};g.Compiler=h;h.prototype={compiler:h,disassemble:function(){for(var b=this.opcodes,a,c=[],d,e,g=0,f=b.length;gc||this.addDepth(c-1);return a},block:function(b){var a=b.mustache,c=b.program;b=b.inverse;c&&(c=this.compileProgram(c));b&&(b=this.compileProgram(b));var a=a.sexpr,d=this.classifySexpr(a);"helper"===d?this.helperSexpr(a,c,b):"simple"===d?(this.simpleSexpr(a),this.opcode("pushProgram",c),this.opcode("pushProgram",b),this.opcode("emptyHash"), -this.opcode("blockValue")):(this.ambiguousSexpr(a,c,b),this.opcode("pushProgram",c),this.opcode("pushProgram",b),this.opcode("emptyHash"),this.opcode("ambiguousBlockValue"));this.opcode("append")},hash:function(b){b=b.pairs;var a,c;this.opcode("pushHash");for(var d=0,e=b.length;dthis.stackVars.length&&this.stackVars.push("stack"+this.stackSlot);return this.topStackName()},topStackName:function(){return"stack"+this.stackSlot},flushInline:function(){var a=this.inlineStack;if(a.length){this.inlineStack=[];for(var b=0,c=a.length;b0&&t-1 in e)}function r(e){var t=kt[e]={};return ct.each(e.match(pt)||[],function(e,n){t[n]=!0}),t}function i(e,n,r,i){if(ct.acceptData(e)){var o,a,s=ct.expando,u=e.nodeType,l=u?ct.cache:e,c=u?e[s]:e[s]&&s;if(c&&l[c]&&(i||l[c].data)||r!==t||"string"!=typeof n)return c||(c=u?e[s]=tt.pop()||ct.guid++:s),l[c]||(l[c]=u?{}:{toJSON:ct.noop}),("object"==typeof n||"function"==typeof n)&&(i?l[c]=ct.extend(l[c],n):l[c].data=ct.extend(l[c].data,n)),a=l[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[ct.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[ct.camelCase(n)])):o=a,o}}function o(e,t,n){if(ct.acceptData(e)){var r,i,o=e.nodeType,a=o?ct.cache:e,u=o?e[ct.expando]:ct.expando;if(a[u]){if(t&&(r=n?a[u]:a[u].data)){ct.isArray(t)?t=t.concat(ct.map(t,ct.camelCase)):t in r?t=[t]:(t=ct.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;for(;i--;)delete r[t[i]];if(n?!s(r):!ct.isEmptyObject(r))return}(n||(delete a[u].data,s(a[u])))&&(o?ct.cleanData([e],!0):ct.support.deleteExpando||a!=a.window?delete a[u]:a[u]=null)}}}function a(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(St,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:Et.test(r)?ct.parseJSON(r):r}catch(o){}ct.data(e,n,r)}else r=t}return r}function s(e){var t;for(t in e)if(("data"!==t||!ct.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function u(){return!0}function l(){return!1}function c(){try{return G.activeElement}catch(e){}}function f(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function p(e,t,n){if(ct.isFunction(t))return ct.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return ct.grep(e,function(e){return e===t!==n});if("string"==typeof t){if($t.test(t))return ct.filter(t,e,n);t=ct.filter(t,e)}return ct.grep(e,function(e){return ct.inArray(e,t)>=0!==n})}function d(e){var t=Ut.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function h(e,t){return ct.nodeName(e,"table")&&ct.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function g(e){return e.type=(null!==ct.find.attr(e,"type"))+"/"+e.type,e}function m(e){var t=on.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function y(e,t){for(var n,r=0;null!=(n=e[r]);r++)ct._data(n,"globalEval",!t||ct._data(t[r],"globalEval"))}function v(e,t){if(1===t.nodeType&&ct.hasData(e)){var n,r,i,o=ct._data(e),a=ct._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)ct.event.add(t,n,s[n][r])}a.data&&(a.data=ct.extend({},a.data))}}function b(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!ct.support.noCloneEvent&&t[ct.expando]){i=ct._data(t);for(r in i.events)ct.removeEvent(t,r,i.handle);t.removeAttribute(ct.expando)}"script"===n&&t.text!==e.text?(g(t).text=e.text,m(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),ct.support.html5Clone&&e.innerHTML&&!ct.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&tn.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}function x(e,n){var r,i,o=0,a=typeof e.getElementsByTagName!==Y?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==Y?e.querySelectorAll(n||"*"):t;if(!a)for(a=[],r=e.childNodes||e;null!=(i=r[o]);o++)!n||ct.nodeName(i,n)?a.push(i):ct.merge(a,x(i,n));return n===t||n&&ct.nodeName(e,n)?ct.merge([e],a):a}function w(e){tn.test(e.type)&&(e.defaultChecked=e.checked)}function T(e,t){if(t in e)return t;for(var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=kn.length;i--;)if(t=kn[i]+n,t in e)return t;return r}function C(e,t){return e=t||e,"none"===ct.css(e,"display")||!ct.contains(e.ownerDocument,e)}function N(e,t){for(var n,r,i,o=[],a=0,s=e.length;s>a;a++)r=e[a],r.style&&(o[a]=ct._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&C(r)&&(o[a]=ct._data(r,"olddisplay",A(r.nodeName)))):o[a]||(i=C(r),(n&&"none"!==n||!i)&&ct._data(r,"olddisplay",i?n:ct.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}function k(e,t,n){var r=vn.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function E(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;4>o;o+=2)"margin"===n&&(a+=ct.css(e,n+Nn[o],!0,i)),r?("content"===n&&(a-=ct.css(e,"padding"+Nn[o],!0,i)),"margin"!==n&&(a-=ct.css(e,"border"+Nn[o]+"Width",!0,i))):(a+=ct.css(e,"padding"+Nn[o],!0,i),"padding"!==n&&(a+=ct.css(e,"border"+Nn[o]+"Width",!0,i)));return a}function S(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=fn(e),a=ct.support.boxSizing&&"border-box"===ct.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=pn(e,t,o),(0>i||null==i)&&(i=e.style[t]),bn.test(i))return i;r=a&&(ct.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+E(e,t,n||(a?"border":"content"),r,o)+"px"}function A(e){var t=G,n=wn[e];return n||(n=j(e,t),"none"!==n&&n||(cn=(cn||ct("