Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/spreed.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/js/vendor
diff options
context:
space:
mode:
authorChristoph Wurst <christoph@winzerhof-wurst.at>2016-10-17 20:27:34 +0300
committerChristoph Wurst <christoph@winzerhof-wurst.at>2016-10-17 20:27:34 +0300
commit1fbda6ed4b3b7e96c8ffa8ccf1f7e1937c107dc6 (patch)
tree459a5059428a9765c90e051f251c3e7a8a5af080 /js/vendor
parent8f9cb3db4b85e80ae8f9bc4288f1f894f2b919dc (diff)
add Backbone.Marionette
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'js/vendor')
-rw-r--r--js/vendor/backbone.marionette/.bower.json51
-rw-r--r--js/vendor/backbone.marionette/ISSUE_TEMPLATE.md22
-rw-r--r--js/vendor/backbone.marionette/PULL_REQUEST_TEMPLATE.md6
-rw-r--r--js/vendor/backbone.marionette/bower.json41
-rw-r--r--js/vendor/backbone.marionette/changelog.md1815
-rw-r--r--js/vendor/backbone.marionette/lib/backbone.marionette.js3330
-rw-r--r--js/vendor/backbone.marionette/lib/backbone.marionette.js.map1
-rw-r--r--js/vendor/backbone.marionette/lib/backbone.marionette.min.js11
-rw-r--r--js/vendor/backbone.marionette/lib/backbone.marionette.min.js.map1
-rw-r--r--js/vendor/backbone.marionette/license.txt1
-rw-r--r--js/vendor/backbone.marionette/marionette-logo.pngbin0 -> 3618 bytes
-rw-r--r--js/vendor/backbone.marionette/package.json90
-rw-r--r--js/vendor/backbone.marionette/readme.md142
-rw-r--r--js/vendor/backbone.marionette/trigger-deploy-mn-com.js32
-rw-r--r--js/vendor/backbone.radio/.bower.json38
-rw-r--r--js/vendor/backbone.radio/CHANGELOG.md132
-rw-r--r--js/vendor/backbone.radio/LICENSE21
-rw-r--r--js/vendor/backbone.radio/README.md353
-rw-r--r--js/vendor/backbone.radio/bower.json29
-rw-r--r--js/vendor/backbone.radio/build/backbone.radio.js350
-rw-r--r--js/vendor/backbone.radio/build/backbone.radio.js.map1
-rw-r--r--js/vendor/backbone.radio/build/backbone.radio.min.js3
-rw-r--r--js/vendor/backbone.radio/build/backbone.radio.min.js.map1
-rw-r--r--js/vendor/backbone.radio/gulpfile.babel.js233
-rw-r--r--js/vendor/backbone.radio/package.json91
-rw-r--r--js/vendor/backbone.radio/src/backbone.radio.js323
-rw-r--r--js/vendor/backbone/.bower.json32
-rw-r--r--js/vendor/backbone/LICENSE22
-rw-r--r--js/vendor/backbone/backbone-min.js2
-rw-r--r--js/vendor/backbone/backbone-min.map1
-rw-r--r--js/vendor/backbone/backbone.js1894
-rw-r--r--js/vendor/backbone/bower.json8
-rw-r--r--js/vendor/underscore/.bower.json35
-rw-r--r--js/vendor/underscore/LICENSE23
-rw-r--r--js/vendor/underscore/README.md22
-rw-r--r--js/vendor/underscore/bower.json7
-rw-r--r--js/vendor/underscore/underscore-min.js6
-rw-r--r--js/vendor/underscore/underscore-min.map1
-rw-r--r--js/vendor/underscore/underscore.js1548
39 files changed, 10719 insertions, 0 deletions
diff --git a/js/vendor/backbone.marionette/.bower.json b/js/vendor/backbone.marionette/.bower.json
new file mode 100644
index 000000000..e5931ef59
--- /dev/null
+++ b/js/vendor/backbone.marionette/.bower.json
@@ -0,0 +1,51 @@
+{
+ "name": "backbone.marionette",
+ "description": "The Backbone Framework",
+ "homepage": "http://marionettejs.org",
+ "main": "./lib/backbone.marionette.js",
+ "version": "3.1.0",
+ "keywords": [
+ "backbone",
+ "framework",
+ "client",
+ "browser",
+ "composite"
+ ],
+ "author": {
+ "name": "Derick Bailey",
+ "email": "derickbailey@gmail.com"
+ },
+ "ignore": [
+ "api",
+ "docs",
+ "gulp",
+ "jsdoc",
+ "src",
+ "tasks",
+ "test",
+ ".babelrc",
+ ".editorconfig",
+ ".eslintrc",
+ ".gitignore",
+ ".jscsrc",
+ ".npmignore",
+ ".travis.yml",
+ "CONTRIBUTING.md",
+ "gulpfile.babel.js",
+ "SpecRunner.html",
+ "upgradeGuide.md"
+ ],
+ "dependencies": {
+ "backbone.radio": "^2.0.0"
+ },
+ "_release": "3.1.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v3.1.0",
+ "commit": "c1d41d73c60ad117b285fd7495b4c1801ca1873d"
+ },
+ "_source": "https://github.com/marionettejs/backbone.marionette.git",
+ "_target": "^3.1.0",
+ "_originalSource": "backbone.marionette",
+ "_direct": true
+} \ No newline at end of file
diff --git a/js/vendor/backbone.marionette/ISSUE_TEMPLATE.md b/js/vendor/backbone.marionette/ISSUE_TEMPLATE.md
new file mode 100644
index 000000000..e38fa93bf
--- /dev/null
+++ b/js/vendor/backbone.marionette/ISSUE_TEMPLATE.md
@@ -0,0 +1,22 @@
+### Description
+
+ 1. The problem you are facing (in as much detail as is necessary to describe the problem to someone who doesn't know anything about the system you're building)
+ 2. A summary of the proposed solution
+ 3. A description of how this solution solves the problem, in more detail than item #2
+ 4. Any additional discussion on possible problems this might introduce, questions that you have related to the changes, etc.
+
+### Expected behavior
+
+Tell us what you think should happen.
+
+### Actual behavior
+
+If possible, please create a small demo that demonstrates the issue.
+You can fork https://jsfiddle.net/marionettejs/adhv48ky/ for quick demo setup.
+Please refrain from giving code examples in altJS languages like CoffeeScript, etc. Marionette is written in plain-old JavaScript and is generally easier for all members in the community to read.
+
+### Environment
+
+1. Marionette version:
+2. Backbone version:
+3. Additional build tools, etc:
diff --git a/js/vendor/backbone.marionette/PULL_REQUEST_TEMPLATE.md b/js/vendor/backbone.marionette/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..87944e4db
--- /dev/null
+++ b/js/vendor/backbone.marionette/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,6 @@
+### Proposed changes
+ -
+ -
+ -
+
+Link to the issue:
diff --git a/js/vendor/backbone.marionette/bower.json b/js/vendor/backbone.marionette/bower.json
new file mode 100644
index 000000000..07f39ac31
--- /dev/null
+++ b/js/vendor/backbone.marionette/bower.json
@@ -0,0 +1,41 @@
+{
+ "name": "backbone.marionette",
+ "description": "The Backbone Framework",
+ "homepage": "http://marionettejs.org",
+ "main": "./lib/backbone.marionette.js",
+ "version": "3.1.0",
+ "keywords": [
+ "backbone",
+ "framework",
+ "client",
+ "browser",
+ "composite"
+ ],
+ "author": {
+ "name": "Derick Bailey",
+ "email": "derickbailey@gmail.com"
+ },
+ "ignore": [
+ "api",
+ "docs",
+ "gulp",
+ "jsdoc",
+ "src",
+ "tasks",
+ "test",
+ ".babelrc",
+ ".editorconfig",
+ ".eslintrc",
+ ".gitignore",
+ ".jscsrc",
+ ".npmignore",
+ ".travis.yml",
+ "CONTRIBUTING.md",
+ "gulpfile.babel.js",
+ "SpecRunner.html",
+ "upgradeGuide.md"
+ ],
+ "dependencies": {
+ "backbone.radio": "^2.0.0"
+ }
+}
diff --git a/js/vendor/backbone.marionette/changelog.md b/js/vendor/backbone.marionette/changelog.md
new file mode 100644
index 000000000..99f3d2dec
--- /dev/null
+++ b/js/vendor/backbone.marionette/changelog.md
@@ -0,0 +1,1815 @@
+### v3.1.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v3.0.0...v3.1.0)
+
+#### General
+* Performance optimizations for `triggerMethod`, `mergeOptions` and other internal event handlers
+* Significant render and removal optimizations for CollectionView utilizing Backbone's `update` event
+
+#### Features
+* `Region.detachView` and `View.detachChildView` were added for removing a view from a region without destroying it. This is preferred to the now deprecated `preventDestroy` region show/empty option
+* `childViewEventPrefix: false` will disable auto-proxying of child events to the parent view
+* `Application` will now accept a region definition object literal as an instantiation option
+* Regions are now destroyed when removed from a View
+
+#### Fixes
+* Fixed an issue with Lodash 4 compatibility related to behavior events
+
+#### Deprecations
+* Region `empty`'s `preventDestroy` option was deprecated in favor of `detachView`
+* A region definition object literal's `selector` key was deprecated due to redundacy in favor of the existing key `el`
+
+#### Misc
+* Many documentation fixes for v3
+* Removed shouldReplace logic from `attachHtml` so overriding no longer breaks `replaceElement` functionality
+* Exposed `View.normalizeUIString` for external libraries
+* Improvements were made for Views initialized with existing DOM elements
+
+### v3.0.0
+
+Version 3.0.0 of Marionette has arrived and contains many improvements over version
+2.x but also some API Changes. Below is a list of the changes made to each component.
+
+To help the community transition over we have released a v2 patch tool to assist
+the upgrade. [Marionette Patch Tool] (https://github.com/marionettejs/marionette-v3-compat)
+
+#### View
+* `LayoutView` + `ItemView` merge and rename to `View`.
+* `Marionette.View` -> `ViewMixin`
+* Added `LayoutView` shortcut methods such as `showChildView`.
+* `isDestroyed` and `isRendered` made private with a public accessor method.
+* Now set `_isDestroyed` to false by default
+* Call `Backbone.View` with result of options (163188eeb8)
+* `CompositeView`'s `renderChildren` is now public.
+* Renamed `childEvents` to `childViewEvents`.
+* Removed passing view options as a function
+* Renamed `templateHelpers` to `templateContext`
+* Made sure `before:render` is triggered before emptying regions.
+* Regions are not attached directly to the layout. Use `getRegion` to access the region or `showChildView` to show a `View` within it.
+* Allowed `CompositeView` to attach to existing HTML with `template:false`
+* Added `hasRegion` for layouts
+* Enabled passing `preventDestroy` to `region.empty`.
+* `View` now removes its element before destroying child regions. There was an option to turn it on, but now it’s available by default. This helps remove all of the synchronous paints going up the tree.
+
+#### CollectionView
+* The `childView` attribute now accepts a function
+* `getChildView` was removed
+* `emptyView` now accepts a function as an arg.
+* Proxied events do not append “this” as an argument
+* Removed the `apply:filter` event from `CollectionView`.
+* `removeChildView` now returns the removed view.
+
+#### Regions
+* Fixed inconsistency in `addRegion`, it now behaves like `addRegions` and adds the region to internal this.regions.
+* `View` can replace regions's el.
+* Replaced region manager with `region-mixin`.
+* Removed static `buildRegion`
+* Removed `swap` events.
+
+#### Application
+* Introduced region to `Application` (`rootRegion`)
+* Removed regions
+* Removed Initializers and Finalizers Callbacks
+* Removed Application `vent`, `commands`, `requests`
+
+#### Object
+* Added support for `Object.isDestroyed`
+
+#### ES6
+* Added Rest & Spread ES6 syntax
+* using ES6 Modules
+* Replaced `var` and `let` with `const`.
+
+#### General Enhancements
+* Added `DEV_MODE`
+* Changed `_.rest` multiple arg usage to drop for lodash 3 support.
+* Behavior, View Mixins.
+* Added `cid` field to object, application, behavior, and region
+* Added `TemplateCache` options.
+* Allow a user to define trigger handlers in options.
+* Increased Lodash compatibility, (now supports upto lodash 4)
+* Added first class support for Backbone.Radio in Mn.Object
+* Updated BB and _ deps to modern versions
+* Updated Radio from 0.9 to 2.0
+* `delegateEntityEvents`. Delegate Events used to set delegate entity events, it was extracted because now backbone calls delegateEvent everytime the element is set.
+* Added `Backbone.Babysitter` to `Mn` and removed the Babysitter dependency.
+
+#### Deprecations
+* Deprecated `CompositeView`
+* Deprecated `Behavior` Lookups.
+
+#### Removed
+* Removed `Marionette.Module` - there’s a shim that you can pull in to get Module and Deferred
+* Removed `Marionette.Deferred`
+* Removed `component.json`
+* Removed `Controller`
+* Removed `Callbacks`
+* Removed `Wreqr` (replaced with `Radio`)
+* Removed `actAsCollection`
+* Removed `_getValue`.
+
+#### API Renames
+* Renamed `render:collection` => `render:children`
+* Renamed `bindEntityEvents` => `bindEvents`.
+
+### v3.0.0-pre5
+
+#### Documentation
+
+* Improved installation docs.
+* Updated `CollectionView` docs to reflect API changes.
+* Improved `Behavior` docs.
+* Improved functions docs.
+* Improved update guide.
+* Added "basics" docs.
+
+#### API Changes
+
+* `emptyView` now accepts a function as an arg.
+* Removed the `apply:filter` event from `CollectionView`.
+* `removeChildView` now returns the removed view.
+* `bindEntityEvents` renamed `bindEvents`.
+* Deprecated Behavior Lookups.
+* Added Backbone.Babysitter to Mn and removed the Babysitter dependency.
+
+#### Bug fixes
+
+* `CollectionView` now only triggers `destroy:children` if it has been rendered.
+* Parent views will now successfully listen for `destroy` in `childViewEvents`.
+
+#### Misc
+
+* Replaced `var` and `let` with `const`.
+* Added consistent function declarations and added rules to eslint.
+* Tweaked peerDependencies to only allow patch versions.
+* Directory structure changes and file naming consistency.
+* Improved test coverage.
+* Removed bundled build.
+
+### v3.0.0-pre4
+
+#### Documentation
+
+* Improved `View` documentation.
+* Added `Backbone.Radio` integration documentation.
+* Fixed broken links in `CollectionView` documentation.
+* Removed `Marionette.Module` documentation.
+* Add installation documentation.
+* Removed outdated API documentation.
+* Added Upgrade Guide.
+
+#### API Changes
+
+* return `this` from all functions that do not return anything, useful for chaining.
+* Removed `getValue` and internal `getOption`.
+
+#### Bug fixes
+
+* CollectionView#reorder will no longer remove an already displayed emptyView.
+* Calling `Backbone.View` constructor with arguments consistently across all views.
+* Monitor for child already attached.
+* When a view is attached to an existing element, `isRendered()` should reflect `true`.
+* Region empty edge-case fix that prevents view destroy handlers calling `empty`.
+* Region now detaches previous html if there is no view.
+
+#### Misc
+
+* Build browser tests with rollup.
+* Fix bundled build.
+* Linter fixes.
+
+Also, [please help us finish v3](https://github.com/marionettejs/backbone.marionette/milestones/v3.0.0)!
+
+### v3.0.0-pre3
+
+#### Dependency Updates
+
+* Backbone and Underscore moved to peerDependencies to solve dependency conflicts for browserify and webpack users.
+* Added support for Lodash 4.
+
+#### Documentation
+
+* Application documentation updates.
+
+#### API Changes
+
+* Removed unused `collection` parameter from `CollectionView.isEmpty`.
+
+#### Bug fixes
+
+* `replaceElement` and `allowMissingEl` are now able to be overridden in `Region.show`.
+
+#### Misc
+
+* Gulp test-browser task fixed.
+* es-lint fixes.
+* Added more es6 syntax.
+* Fixed the UMD exported build.
+
+Also, [please help us finish v3](https://github.com/marionettejs/backbone.marionette/milestones/v3.0.0)!
+
+### v3.0.0-pre2
+
+Extra release to remove public release of v3.0.0-pre.1, this release is available via the `prerelease` tag on npm.
+
+### v3.0.0-pre.1
+
+This is a "family and friends" release. The documentation is still mostly for 2.4.4.
+Please let us know if you run into any issues. Also, [please help us finish v3](https://github.com/marionettejs/backbone.marionette/milestones/v3.0.0)!
+
+### v2.4.7 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.4.6...v2.4.7)
+
+#### Fixes
+
+* CollectionView#reorder will no longer remove an already displayed emptyView.
+* Fixed build of sourcemap files.
+
+### v2.4.6 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.4.5...v2.4.6)
+
+#### Misc
+
+* Updated Backbone dependency to 1.3.x.
+
+### v2.4.5 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.4.4...v2.4.5)
+
+#### Fixes
+
+* `Marionette.View#ui` will now bind events when names are hyphenated.
+* Nonexistent event handlers now fail silently.
+
+#### Misc
+
+* Updated Backbone dependency to 1.3.3.
+* devDependencies updated.
+* Updated uglify to fix deprecated sourcemap pragma //@ replaced with //#.
+
+### v2.4.4 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.4.3...v2.4.4)
+
+#### Fixes
+
+* `Region#empty` will return the region instance whether or not it has a current view.
+* `CollectionView#reorder` will now correctly respect any set filter.
+* Fixed `childEvents` failing to trigger during showing a view in a region.
+* Stop deleting the `currentView._parent` if showing the same view in a region.
+
+#### Misc
+
+* `LayoutView#showChildView` new `options` argument passed to underlying `Region#show` to enable full `show` functionality.
+* Added support for passing down arguments to `Object#destroy`.
+
+### v2.4.3 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.4.2...v2.4.3)
+
+#### Fixes
+
+* `TemplateCache#loadTemplate` accepts empty script-tag templates.
+* Parent LayoutView's `childEvents` continue working with views attached manually using `Region#attachView`.
+* When an array of items (length > 1) are added to a collection backing a CollectionView using the `at` option, the child views are appended to the DOM in the proper order.
+* When models are added to a collection backing a CollectionView with the `at` option, the child views are rendered in the proper order even when the CollectionView has a filter.
+* `CollectionView#isEmpty` respects a `false` return value even when there are no child views.
+* `Region#empty` reliably destroys views when called with options.
+* CollectionView child views can, in turn, render children within `onBeforeShow` as documented.
+* CollectionView `childView` and `emptyView` can be pure `Backbone.View` classes.
+
+#### Docs
+
+* Better documentation around view `childEvents` that reinforces the distinction between child view `triggers` and `events`.
+* Guidance on achieving full event lifecycle while using `Backbone.View` as the child view within CollectionViews or LayoutViews/Regions.
+
+#### Misc
+
+* Allow `Application` to be initialized with multiple arguments for consistency with earlier releases.
+* More comprehensive support for Backbone child views, including a more rigorous test suite and support for `render`, `destroy`, and `dom:refresh` lifecycle events when shown by CollectionViews or LayoutViews/Regions.
+* Bumped Backbone dependency to 1.2.3
+
+### v2.4.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.4.1...v2.4.2)
+
+#### Fixes
+
+* Fixed a bug where `reorderOnSort` would not reorder back to the original order.
+* Stop deleting `$childViewContainer` so that it can be accessed in behaviors.
+* Ensure `before:show` and `show` events are triggered on `CollectionView` children.
+* Ensure `onBeforeAttach` and `onAttach` are called for `CollectionView` children.
+* Allow for disabling of `triggerBeforeAttach` and `triggerAttach` via `show()` options.
+* Added the documented `buffer` argument to `attachBuffer` and changed implementation so this was used rather than `_createBuffer`.
+* Fixed potential memory leak when destroying children on `CollectionView` by making the `checkEmpty` call optional.
+
+#### Docs
+
+* Improve documentation around the requirement for an initial render to bind events in `CollectionView`.
+* Add documentation around UI interpolation usage.
+* Add documentation to warn about the full re-render of a `CollectionView` or `CompositeView` if `reorderOnSort` is not set.
+
+#### Misc
+
+* Bumped Underscore and Backbone dependencies to 1.8.3 and 1.2.1 respectively.
+
+### v2.4.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.4.0...v2.4.1)
+
+#### Fixes
+
+* Fixed a nasty bug where `reorderOnSort` when used on a `CompositeView` would not respect the `childViewContainer`.
+
+#### General
+
+* Add JSCS for style linting and consistency.
+
+#### Docs
+
+* Improve internal linking across docs, to make it easier for people to understand how pieces relate to each other.
+
+### v2.4.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.3.2...v2.4.0)
+
+#### 2.4 In Overview
+
+The Marionette 2.4 release is primarily focused around adding power and performance to `Marionette.CollectionView’s` and `CompositeViews`. It is now possible for users to declaratively sort, filter, and reorder in a performant and clear way on the view layer. Prior to this work it was difficult and required significant workarounds.
+
+As well as working on the `CollectionView` layer we have added full support for lodash and multiple builds of backbone, underscore and lodash. Allowing the user to pick whatever tools they wish.
+
+The other powerful feature that we introduced in this release is the concept of `childEvents` for `LayoutView` and their subviews. Prior to this release there was never a great way to listen or react to events that were triggered on subviews, like when something was rendered or destroyed. Now we have brought over the declarative `childEvents` hash from `CollectionView` into the `LayoutView`.
+
+As always come and join us in [chat](https://gitter.im/marionettejs/backbone.marionette/)
+
+#### Features
+
+* CollectionView
+ * You can now set a filter method on a `CollectionView` or `CompositeView` to filter what views are show. This is useful for when you are displaying a list that a user can filter.
+ * Add the `reorderOnSort` option to `CollectionView` and `CompositeView` to use jQuery to move child nodes around without having to re-render the entire tree. This is a massive perf boost and is an easy win if you are sorting your collections.
+ * The `CollectionView` now has a `viewComparator`, to enable custom sorting on a per view basis regardless of what how your backing collection is sorted.
+ * Refactor sort param lookup to use `Marionette.getOption`.
+ * **Fix** childViews now fire a `before:show` event even if the childView is inserted after the parent `CollectionView` or `CompositeView` has been shown.
+
+* Regions
+ * The `empty` method now takes an optional `preventDestroy` flag to prevent the destruction of the view shown within.
+ * `this.myRegion.empty({preventDestroy: true})`
+
+* TemplateCache
+ * The templateCache `get` method now takes a second param of options to enable passing options to the loading of templates.
+
+* LayoutView
+ * Add a new helper method for easier showing of child nodes `showChildView`
+ * `this.showChildView('sidebar', new SidebarView());`
+ * Add a new helper method of easier retrieving of child nodes `getChildView`
+ * `this.getChildView(‘sidebar’)`
+ * Add a `destroyImmediate` option to the `LayoutView`, to destroy the layout view element and then remove the child nodes. This is a perf optimization that you can now opt into.
+ * `@ui` interpolation is now supported within region definitions on a `LayoutView`
+ * `regionEvent` support was added
+ * you can access this functionality via `onChildViewX` or via the declarative `childEvents` hash
+
+* ItemViews
+ * the `isRendered` property is now set to `true` after render, even if no template is set.
+ * Views
+ * The `destroy` method now returns this instance that was destroyed to enable easier chaining of view actions.
+ * If you define the options hash on your `Marionette.View` or if you pass options as a function to your `Marionette.View`, pass the result of options down to the backbone view constructor.
+ * All views now have a `isRendered` property, that is updated after `render` and `destroy`.
+
+* Object
+ * The `destroy` method now returns this instance that was destroyed to enable easier chaining of object actions.
+
+* Behavior
+ * The `destroy` method now returns this instance that was destroyed to enable easier chaining of behavior actions.
+ * Expose the `UI` hash to a behavior instance. The behavior `UI` hash is a composite of the view hash and the behavior hash merged with the behavior hash tasking precedence.
+
+#### Util
+
+* `Marionette._getValue` will now use `call` under the hood if no arguments are passed (micro optimization).
+* Add `Marionette.mergeOptions` to `Marionette.View*` classes, `Marionette.Object`. `Marionette.AppRouter`, `Marionette.Controller`
+* `mergeOptions` is a handy function to pluck certain `options` and attach them directly to an instance.
+
+#### Docs
+
+* Minor documentation cleanups and fixes
+
+#### Deprecation Notices
+
+* Deprecate `Marionette.Controller`, Use `Marionette.Object` instead.
+
+#### Misc
+
+* YAML api documentation is now linted on each PR.
+* Add `Marionette.FEATURES` flag.
+* Refactor several methods to enable 100% compatibility with lodash.
+
+### v2.3.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.3.1...v2.3.2)
+
+#### 2.3.2 in overview:
+
+##### Bug Fixes
+
+* Fix IE8 regression in `Marionette._getValue` to always call `apply` with either an array of params or an empty array.
+
+### v2.3.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.3.0...v2.3.1)
+
+#### 2.3.1 in overview:
+
+##### Features
+
+* Regions can set a `parentEl` as a way of specifying the DOM tree (default `body`) that they are scoped with. (useful for instance in `LayoutView`).
+
+```js
+ var region = new Region({parentEl: $(“#sub-tree”)})
+```
+
+##### Bug Fixes
+
+* Layout region lookups are now scoped to the layout and not to the entire DOM.
+
+* Calling `delegateEvents` after the `ui` hash has been modified now works.
+
+* Prevent unsetting event listeners on region swap when a view is swapped out from a region, but not destroyed, its DOM events will not be removed.
+
+* A view's `isDestroyed` state is now explicitly set to `false` when the view is created.
+
+##### Refactors
+
+* Added `Marionette._getValue`. This method is similar to `_.result`. If a function is provided we call it with context otherwise just return the value. If the value is undefined return a default value. This method is private and should not be used directly in your code.
+
+* Various other code refactors.
+
+### v2.3.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.2.2...v2.3.0)
+
+#### 2.3.0 in overview:
+
+This release of Marionette contains a significant amount of code optimizations and refactors. These changes will not be visible to you as end user however as they improve the underlying base of Marionette and speed up your app to improve consistency across the base classes. Such speed ups are most visible in the great work @megawac has been doing in both [serializeData](https://github.com/marionettejs/backbone.marionette/commit/62f15dc7ec880631a0bb79b18470c94b0a0ad086) and [triggerMethod](https://github.com/marionettejs/backbone.marionette/commit/e5957dde9a9a48eeb8097a0ce2f628d795668e64)
+
+As always you can come chat with us in the main chatroom at https://gitter.im/marionettejs/backbone.marionette/
+
+Work has been continuing on improving the documentation of Marionette, via an external custom JSDOC tool that @ChetHarrison has been spear heading via https://github.com/ChetHarrison/jsdoccer
+
+If you have not already checked out Marionette Inspector, it is a great tool that Jason Laster has been working on to make debugging and working with marionette much easier. https://github.com/MarionetteLabs/marionette.inspector
+
+##### Features
+
+* Marionette.isNodeAttached
+ * Determines whether the passed-in node is a child of the `document` or not.
+* View "attach" / onAttach event
+ * Triggered anytime that showing the view in a Region causes it to be attached to the `document`. Like other Marionette events, it also executes a callback method, `onAttach`, if you've specified one.
+* View "before:attach" / onBeforeAttach
+ * This is just like the "attach" event described above, but it's triggered right before the view is attached to the `document`.
+* AppRouter Enhancements
+ * `triggerMethod`, `bindEntityEvents`, and `unbindEntityEvents` are now available on AppRouter
+* Marionette.Application is now a subclass of Marionette.Object
+* Marionette.Behavior is now a subclass of Marionette.Object
+* Marionette.Region is now a subclass of Marionette.Object
+* CompositeView’s `getChildViewContainer` now receives `childView` as a second argument.
+* Region Triggers now pass the view, region instance, and trigger options to all handler methods
+* CollectionView `emptyViewOption` method now receives the model and index as options.
+* Allow non-DOM-backed regions with `allowMissingEl`
+ * `allowMissingEl` option is respected by `_ensureElement`
+ * `_ensureElement` returns a boolean, indicating whether or not element is available
+ * Region#show early-terminates on missing element
+* Regions now ensure the view being shown is valid
+ * Allowing you to handle the error of a region.show without the region killing the currentView and breaking without recourse.
+ * Appending isDestroyed to a Backbone.View on region empty now adds the same safety for not re-showing a removed Backbone view.
+* Marionette is now aliased as Mn on the `window`.
+* Collection/Composite Views now support passing in 'sort' as both a class property and as an option.
+* RegionManager will now auto instantiate regions that are attached to the regionManager instance.
+
+```js
+new Marionette.RegionManager({
+ regions: {
+ "aRegion": "#bar"
+ }
+});
+```
+
+##### Fixes
+
+* Region now uses `$.el.html(‘’)` instead of `.innerHTML` to clear contents.
+ * We can not use `.innerHTML` due to the fact that IE will not let us clear the html of tables and selects. We also do not want to use the more declarative `empty` method that jquery exposes since `.empty` loops over all of the children DOM nodes and unsets the listeners on each node. While this seems like a desirable thing, it comes at quite a high performance cost. For that reason we are simply clearing the html contents of the node.
+* Destroying an old view kept alive by `{preventDestroy: true}` no longer empties its former region.
+ * Now the destroy listener from previous view is removed on region show
+* AppRouter `this.options` now assigned prior to `initialize` being called.
+
+
+##### Deprecation Warnings
+
+* Marionette.Application.addInitializer
+* Marionette.Application Channel
+* Marionette.Application Regions
+* Marionette.Callbacks
+* Marionette.Deferred
+* Marionette.Module.addInitializer
+* Marionette.Module.addFinalizer
+
+
+### v2.2.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.2.1...v2.2.2)
+
+* Fixes
+
+ * Remove duplicate call to region.empty on view destroy.
+ * Fix call time of `swapOut`.
+ * Fix broken link in Marionette Error messages
+
+### v2.2.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.2.0...v2.2.1)
+
+* Fixes
+
+ * Revert collection type checking for `collectionView`.
+
+### v2.2.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.1.0...v2.2.0)
+
+* Features
+
+ * Normalize region selectors hash to allow a user to use the `@ui.` syntax
+ * `Marionette.triggerMethodOn`
+ * `triggerMethodOn` invokes `triggerMethod` on a specific context
+ * Marionette.Error
+ * `captureStackTrace` cleans up stack traces
+ * add view _behaviors reference to associated behaviors
+ * enabling you to easily test and spy on your behaviors
+ * CollectionViews now receive events from emptyViews in the childEvents hash
+ * Regions now receive `swapOut` and `beforeSwapOut` events.
+ * Application has `this.options`
+ * Application has `initialize` method
+ * Behaviors no longer wrap view methods
+
+* Bug Fixes
+
+ * LayoutView’s regions are scoped inside its `el`
+ * Fix inconsistent Marionette.Object constructor implementation.
+ * emptyView instances now proxy their events up to the collection / compositeView
+ * collection / compositeView does not listen to collection add/remove/reset events until after render.
+ * Marionette.normalizeUIKeys no longer mutates UI hash
+
+* Better Errors
+
+ * View destroyed error now includes the view cid in the error message.
+ * Throw an error when Marionette.bindEntityEvents is not an object or function
+ * Throw a descriptive error for `collectionViews`
+ * If you do not pass a valid `collectionView` instance you are now given a logical error.
+
+* Documentation Improvements
+
+ * New API docs are in progress
+ * Examples have been cleaned up
+
+### v2.2.0-pre.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.1.0...v2.2.0-pre.2)
+
+### v2.2.0-pre [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.1.0...v2.2.0-pre)
+
+### v2.1.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.0.3...v2.1.0)
+
+* Features
+
+ * Marionette.Object
+ * A base class which other classes can extend from. Marionette.Object incorporates many Backbone conventions and utilities like `initialize` and `Backbone.Events`. It is a user friendly class to base your classes on to get Backbone conventions on any generic class.
+
+ * Add a `el` reference to the views `el` from within a `behavior` instance.
+
+ * `ItemView`s can now have no template by setting `template: false`
+
+ * Application objects can now configure their default message channel.
+ * This will allow you to configure multiple applications to exist at the same time within an app without their event bus colliding.
+
+ * Application objects now have the `getOption` method.
+
+ * Regions now have a `hasView` method to determine if there is a view within a given region.
+
+ * Views no longer use toJSON directly on models. Instead they call into the new overridable methods `serializeModel` and `serializeCollection` via `serializeData`
+
+ * Return chainable objects from more methods to be consistent
+
+ * Application: emptyRegions
+ * Application: removeRegion
+ * CollectionView renderChildView
+
+ * Controller new
+ * LayoutView destroy
+
+ * Region reset
+ * Region attachView
+ * Region empty
+
+ * RegionManager destroy
+ * RegionManager emptyRegions (now returns regions)
+ * RegionManager removeRegions (now returns regions)
+ * RegionManager removeRegion (now returns region)
+ * View destroy
+ * View undelegateEvents
+ * View delegateEvents
+
+ * RegionManager `addRegions` now accepts a function that returns a region definition in addition to a region definition object
+ * This extends to Marionette.Application’s and CompositeView’s `regions` properties
+
+ * Added CollectionView `resortView`
+ * Override this method on a subclass of CollectionView to provide custom logic for rendering after sorting the collection.
+
+ * View instance is now passed as a third argument to `Marionette.Renderer.render`
+
+ * Add `getRegionManager` to Application
+
+* Fixes
+
+ * CollectionView now maintains proper order when adding a mode
+ * Fix component.js path
+ * Prevent AppRouter from erroring when appRoutes are passed into the router constructor as an option.
+ * UI hash keys now only allow documented syntax, enforcing `@ui.stuff` instead of `@ui<ANY_CHAR>stuff`
+
+### v2.1.0-pre [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.0.3...v2.1.0-pre)
+
+### v2.0.3 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.0.2...v2.0.3)
+
+ * Bug Fixes
+
+ * Fixed an issue where `before:show` was not triggered on a view's behavior when shown within a region.
+
+ * Destroying a view outside of its region will now cause the region to remove its reference to that view.
+
+### v2.0.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.0.1...v2.0.2)
+
+ * Bug Fixes
+ * Fixed issue where `render:collection` called before the entire collection and children had been rendered.
+
+ * General
+ * Remove bundled main entry point for bower.
+
+### v2.0.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.0.0...v2.0.1)
+ * Fix missing Wreqr and Babysitter in Core AMD definition.
+
+### v2.0.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.8.8...v2.0.0)
+ * This is a breaking release and contains many API updates and changes, thus changelog is quite large for this release, please refer to the [google doc](https://docs.google.com/document/d/1fuXb9N5LwmdPn-teMwAo3c8JTx6ifUowbqFY1NNSdp8/edit#) for the full details of what is new and what has changed.
+
+### v2.0.0-pre.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v2.0.0-pre.1...v2.0.0-pre.2)
+ * The changelog is quite large for this release, please refer to the [google doc](https://docs.google.com/document/d/1fuXb9N5LwmdPn-teMwAo3c8JTx6ifUowbqFY1NNSdp8/edit#)
+
+### v2.0.0-pre.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.8.5...v2.0.0-pre.1)
+ * The changelog is quite large for this release, please refer to the [google doc](https://docs.google.com/document/d/1fuXb9N5LwmdPn-teMwAo3c8JTx6ifUowbqFY1NNSdp8/edit#)
+
+### v1.8.8 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.8.7...v1.8.8)
+
+ * Fixes
+ * Fixed the case where `onShow` was not called on child view behaviors when inside a `Collection` or `Composite` view.
+
+### v1.8.7 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.8.6...v1.8.7)
+
+ * Fixes
+ * Fixed nasty ui interpolation bug with behaviors.
+
+ * General
+ * Minor Doc cleanup
+
+### v1.8.6 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.8.5...v1.8.6)
+
+ * Regions
+ * `Region.show` now returns the region instance to allow for region operation chaining.
+ * `Region.show` triggers the view's native `triggerMethod` if it exists. This is to handle the case that triggerMethod is wrapped by a `Marionette.Behavior`.
+
+ * General
+ * Update jquery 2.x upper bound dependency restrictions.
+ * The grunt test command will now complain if you do not have bower components installed.
+ * Readme cleanups.
+
+### v1.8.5 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.8.4...v1.8.5)
+
+ * Fixes
+ * Update the UMD build to be inline with the 2.x branch UMD implementation.
+
+### v1.8.4 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.8.3...v1.8.4)
+
+ * General
+ * Update bundled build to use the latest version of babysitter and wreqr.
+
+### v1.8.3 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.8.2...v1.8.3)
+
+ * Fixes
+ * Behaviors now have access to the views options and events during their initialize.
+
+### v1.8.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.8.0...v1.8.2)
+
+ * Fixes
+ * Behaviors now calls `stopListening` on close.
+ * Behaviors now undelegate `modelEvents` and `collectionEvents` when the parent view calls `undelegateEvents`.
+
+### v1.8.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.7.4...v1.8.0)
+
+ * General
+ * Update Gruntfile.
+ * The default task (`grunt`) now runs tests.
+ * `$ grunt dev` watch for watching.
+ * `$ grunt build` runs the tests and compiles.
+ * Add better inline documentation for module implementation.
+ * Add better inline behavior documentation.
+
+ * Fixes
+ * Behaviors now correctly lookup methods for `modelEvents` and `collectionEvents`.
+ * The `CollectionView` now triggers close on its children in the correct order.
+
+ * Features
+ * Add `onRoute` to the `appRouter`.
+ ```js
+ Marionette.AppRouter.extend({
+ onRoute: function(route, params) {
+ }
+ })
+ ```
+ * `Region.show` now takes an option to prevent closing the previous view in the region. By default a region will automatically close the previous view, however you can prevent this behavior by passing `{preventDestroy: true}` in the options parameter.
+ ```js
+ myRegion.show(view2, { preventDestroy: true })
+ ```
+ * Add a `getRegion` method to `Layout`. This is in line with the eventual goal of not attaching regions to the root layout object.
+ * Behavior instances now extend from Backbone.Events, allowing you to use `.listenTo` and `.on`.
+
+ * Allow Behaviors to have a functional hash lookup.
+ ```js
+ Marionette.ItemView.extend({
+ behaviors: function() {
+ // “this” will refer to the view instance
+ return : {
+ BehaviorA: {}
+ }
+ }
+ })
+ ```
+ * RegionManagers now calls `stopListening` on a regions on removal.
+
+ * Refactors
+ * Abstract underscore collection method mixin into a generic helper.
+ * Use built in marionette extend for behaviors.
+
+ * Tests
+ * Add a whitespace linter to the text coverage. Trailing whitespace now causes travis.ci to fail.
+ * Add test coverage for `bindEntitiyEvents` and `unbindEntityEvents`.
+ * Test public API for the `regionManager`.
+ * Improve view trigger tests for better control when testing.
+
+### v1.7.4 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.7.3...v1.7.4)
+
+* General
+ * Update bower dependencies to take advantage of the fact that marionette repos follow semver.
+
+* Fixes
+ * Behaviors events no longer collide with each other.
+ * Revert `stopListening` call on `stop` for modules. While this was a "fix", the docs were quite vague leading to breaking changes for many people.
+ * `startWithParent` is now respected when using a `moduleClass` property.
+
+### v1.7.3 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.7.2...v1.7.3)
+
+* Behaviors
+ * Adds the ability to use `@ui` interpolation within the events hash on a behavior.
+
+* Fixes
+ * Corrects broken view $el proxy in behaviors.
+
+### v1.7.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.7.1...v1.7.2)
+
+* Fixes
+ * Binds behavior events to the behavior instance, as compared to the view.
+
+### v1.7.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.7...v1.7.1)
+
+* Fixes
+ * Enables the use of string based behavior event methods.
+
+### v1.7.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.6.4...v1.7)
+
+Version 1.7 represents a significant step in formalizing the ways to improve your `view` code though reusable `behaviors`. Say goodbye to custom mixin strategies and welcome `behaviors` into town.
+
+* Behaviors
+
+ A `Behavior` is an isolated set of DOM / user interactions that can be mixed into any `View`. `Behaviors` allow you to blackbox `View` specific interactions into portable logical chunks, keeping your `views` simple and your code DRY. **[Read the docs here.](https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.behavior.md)**
+
+* Modules
+ * Call stop listening on module stop.
+
+* Events
+ * add a before:show event for views and regions
+
+* Docs
+ * Entire refactor of application docs.
+
+* Tests
+ * Rework the module tests to improve readability and consistency.
+
+* General
+ * switch from `~` to `^` for *trusted* dependencies.
+
+### v1.6.4 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.6.3...v1.6.4)
+ * Fixes
+ * Patches a bug that would cause modules to be initialized twice when a custom module class is passed
+
+### v1.6.3 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.6.2...v1.6.3)
+ * Improvements
+ * Enable more direct module instantiation on `Marionette.App`.
+ ```js
+ var ItemModule = Marionette.Module.extend({
+ startWithParent: false,
+ initialize: function(options) {},
+ onStart: function() {}
+ });
+
+ // ...
+
+ this.app.module('Items', ItemModule);
+ ```
+ * `ui` hash interpolation now supports a functional `ui` hash.
+
+ ```js
+ ui: function() {
+ return {
+ "foo": ".foo"
+ }
+ }
+ ```
+ * Fixes
+ * Fix `@ui` interpolation for handling complex selectors.
+
+ ```js
+ {
+ "click div:not(@ui.bar)": "tapper"
+ }
+ ```
+ * Bump `backbone.babysitter` and `backbone.wreqr` versions.
+ * General
+ * Improve readme docs for `CollectionView`, `AppRouter` and `ItemView`.
+ * Handle THE [npm self sign cert problem](http://blog.npmjs.org/post/78085451721/npms-self-signed-certificate-is-no-more)
+ * Replace unneeded argument slicing.
+ * Normalize error throwing to use internal `throwError` helper method.
+ * Use `_` type checks for non performant code to improve readability and consistency.
+
+### v1.6.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.6.1...v1.6.2)
+ * CollectionView/CompositeView
+ * allow `itemEvents` to use string based method names [PR 875](https://github.com/marionettejs/backbone.marionette/pull/875)
+ * Modules
+ * update module initialize to include moduleName and app [PR 898](https://github.com/marionettejs/backbone.marionette/pull/898)
+ * General
+ * significantly improve module documentation [PR 897](https://github.com/marionettejs/backbone.marionette/pull/897)
+
+### v1.6.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.6.0...v1.6.1)
+ * Modules
+ * Fix a bug where a module would not start by default when defined as an object literal
+
+### v1.6.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.5.1...v1.6.0)
+ * CompositeView
+ * add a `composite:collection:before:render` event
+
+ * CollectionView
+ * `checkEmpty` can now be overridden
+
+ * Modules
+ * `Modules` can now be created using the extend method, and then attached to an [Application](https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.application.module.md#extending-modules).
+
+ * General
+ * add a component.json file
+ * update bower.json
+ * add AMD build in bower.json
+
+ * Tests
+ * general clean up
+ * add sinon.js for test spys
+
+### v1.5.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.5.0...v1.5.1)
+ * CollectionView/CompositeView
+ * Fix bug where `show` and `onDomRefresh` was not called on `itemViews` in certain [conditions](https://github.com/marionettejs/backbone.marionette/pull/866)
+
+### v1.5.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.4.1...v1.5.0)
+ * Views
+ * View `options` can now be a [function](https://github.com/marionettejs/backbone.marionette/pull/819)
+ * `onDomRefresh` is now only called when said `view` is in the [DOM](https://github.com/marionettejs/backbone.marionette/pull/855)
+
+ * CollectionView/CompositeView
+ * `itemViewContainer` is now called with the correct [context](https://github.com/marionettejs/backbone.marionette/pull/841)
+ * Fix bug where reseting a `collection` within a `collectionView` would cause `onShow` and `onDomRefresh` to be called [incorrectly](https://github.com/marionettejs/backbone.marionette/pull/849) on the itemViews.
+ * `addItemView` now returns the `view` that was [added](https://github.com/marionettejs/backbone.marionette/pull/851)
+ * You can now specify an `itemEvents` hash or method which allows you to capture all bubbling itemEvents without having to [manually set bindings](https://github.com/marionettejs/backbone.marionette/pull/861).
+
+ ```js
+ itemEvents: {
+ "render": function() {
+ console.log("an itemView has been rendered");
+ }
+ }
+ ```
+
+ * Regions
+ * Region `close` event now passes the `view` being closed with the [event](https://github.com/marionettejs/backbone.marionette/pull/834).
+
+ * General
+ * Updated bower ignore folder
+ * Added an editor config file
+
+### v1.4.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.4.0...v1.4.1)
+* Views
+ * fix for inital view class options. Now retains set options at class instantiation
+
+### v1.4.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.3.0...v1.4.0)
+* Views
+ * adds the ability to use the new ```@ui.``` syntax within the events and triggers hash to prevent selector duplication
+
+### v1.3.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.2.3...v1.3.0)
+* CompositeView / CollectionView
+ * Massive perf boost in rendering collection and composite views by using document fragments [jsPerf](http://jsperf.com/marionette-documentfragment-collectionview/5)
+
+### v1.2.3 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.2.2...v1.2.3)
+* CompositeView
+ * Fixed bug where ```child views``` were being added before the initial render, thus raising errors.
+
+### v1.2.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.2.1...v1.2.2)
+* Views
+ * Move the instantiation of ```view``` options above the ```constructor``` This allows for view options to be accessed from within the ```initialize``` method for a given ```view```
+This is needed since backbone views no longer set the view options in the constructor
+
+### v1.2.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.2.0...v1.2.1)
+* Views
+ * fixed a bug so now view options are {} by default and not undefined.
+ * fixed a bug where the triggers preventDefault and stopPropagation were executing in the wrong context – triggers now prevent default and stop propagation by default once more.
+
+### v1.2.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.1.0...v1.2.0)
+* Update Backbone to [1.1.0](https://github.com/jashkenas/backbone/compare/1.0.0...1.1.0)
+
+* Views
+ * added the ability to customize the behavior of `triggers` preventDefault and stopPropagation
+
+* Collection View / CompositeView
+ * added the ability to specifiy `getEmptyView` for dynamic `emptyView` lookups
+
+### v1.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.4...v1.1.0)
+
+* Marionette.View / All Views
+ * Fix for `ui` bindings to not be removed from view prototype, if unrendered view is closed
+ * Template helpers can now be provided as a constructor function option
+
+* Layout
+ * Will properly attach regions if the layout's `close` method was called prior to `render`
+ * Calling `.addRegions` will correctly modify the layout instance' region list instead of the prototype's
+ * Fixed bug that prevented default `regionType` from being used
+
+* CompositeView
+ * The `itemViewContainer` can be supplied in the constructor function options
+
+* Application
+ * Added `closeRegions` method to close all regions on the app instance
+ * Added `getRegion` method to retrieve a region by name
+
+* AppRouter
+ * Added `appRoute` method to create app router handlers at runtime
+ * Added ability to set `appRoutes` in constructor function options
+
+* Marionette.triggerMethod
+ * Calls to the `Marionette.triggerMethod` can be made on objects that do not have a `trigger` method
+
+### v1.0.4 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.3...v1.0.4)
+
+* ItemView
+ * Added needed `constructor` function back - it added lots of things and needed to be there
+
+* CompositeView
+ * Added explicit call to CollectionView constructor to allow for inheritance overriding
+
+* Layout
+ * Small clarification for consistency on call to ItemView constructor
+
+### v1.0.3 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.2...v1.0.3)
+
+* ItemView
+ * Deleted unneeded `constructor` function - it added nothing and didn't need to be there
+
+* CompositeView
+ * Added `index` parameter to method signature, to show that it is available
+ * Deleted unneeded `constructor` function and removed call to `getItemView` as it was causing problems and was not needed in the constructor.
+
+* All Views
+ * Fixed a bug in the entity and collection event bindings, where `stopListening` would not unbind the event handlers
+
+* Renderer / All Views
+ * The `Renderer.render` method will throw a more meaningful error if the supplied template is falsey
+
+* Region
+ * Re-showing a closed view now works by re-rendering and re-inserting the view in to the DOM
+ * Region will trigger a `show` event when showing a view (updated the code to work like the docs already said)
+ * Set the `currentView` before triggering the `show` events from the region / view
+
+* RegionManager
+ * Fixed a bug to decrement the `.length` when a region is removed
+
+### v1.0.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.1...v1.0.2)
+
+* UI Elements
+ * Fix bug to unbind them after the "close" event / `onClose` method, so the `ui` elements are available during these
+
+* AppRouter
+ * Fix bug that was reversing the order of routes, causing the wrong route to be fired in many cases
+
+### v1.0.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0...v1.0.1)
+
+* AMD build: Removed `require('jQuery')` as Marionette now pulled `Backbone.$` as
+ `Marionette.$`.
+
+* Fixed RegionManager to allow region types to be specified again, not just
+ region instances.
+
+* NPM: Removed hard dependency on jQuery from the dependency list. This will
+ be pulled in by other libs, or should be pulled in manually, to get the
+ right version.
+
+### v1.0.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-rc6...v1.0.0)
+
+* RegionManager
+ * Created new `Marionette.RegionManager` object to manage a set of regions
+
+* Region
+ * Region will call the `close` method on a view, or the `remove` method if `close` is not found, when closing a view
+ * When calling the `show` method with the same view instance multiple times, subsequent calls will only re-render the view and not close / re-open it
+
+* Application
+ * Now uses `Marionette.RegionManager` to manage regions
+
+* Layout
+ * Now uses `Marionette.RegionManager` to manage regions
+ * Now supports dynamic add / remove of regions
+ * Can specify `regions` as a function that takes an `options` argument (the view's constructor options)
+
+* CollectionView / CompositeView
+ * When specifying `itemViewOptions` as a function, an item `index` argument will be passed as the second parameter
+ * Will call the `close` or `remove` method when closing a view, with `close` method taking precedence
+
+* CompositeView
+ * Fixed a bug that caused an error when the collection was `reset` (loaded) before the view was rendered
+
+* All Views
+ * Closing a view will properly unbind `ui` elements
+ * Closing and then re-rendering a view will re-bind the `ui` elements
+
+* Functions
+ * Removed the `Marionette.createObject` function - it was never used by Marionette, directly
+
+* jQuery
+ * Replaced direct calls to `$` with new `Marionette.$`, which is assigned to
+ `Backbone.$` for consistency w/ Backbone.
+
+* Backbone.Wreqr
+ * Updated to v0.2.0
+ * Renamed `addHandler` method to `setHandler`
+ * For more information, see the [Wreqr changelog](https://github.com/marionettejs/backbone.wreqr/blob/master/CHANGELOG.md)
+
+* Code Cleanup
+ * Replaced `that = this` with the `context` param of several calls to `_.each` to clean up the code
+ * Removed an unused method from the CompositeView implementation
+
+* Build process
+ * Updated to Grunt v0.4.x
+ * Added code coverage and other analysis reports
+
+### v1.0.0-rc6 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-rc5...v1.0.0-rc6)
+
+* CompositeView
+ * Corrected the timing of the "before:render" event / `onBeforeRender` callback, so that it will be called before serializing the data for the model / template
+
+### v1.0.0-rc5 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-rc4...v1.0.0-rc5)
+
+* CollectionView / ItemView
+ * Corrected the timing on the "show" event / `onShow` callback for itemView instances that are added after the CollectionView is in the DOM
+
+### v1.0.0-rc4 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-rc3...v1.0.0-rc4)
+
+* EventBinder
+ * **BREAKING:** Removed `Marionette.addEventBinder` function.
+
+* EventAggregator
+ * **BREAKING:** Removed `Marionette.EventAggregator` object. Use `Backbone.Wreqr.EventAggregator` instead
+
+* CollectionView / CompositeView
+ * Fixed several issues related to resetting the collection, and producing zombie "empty" views
+ * Fixed a bug that caused multiple emptyView instances when resetting the collection
+ * Forwarded events from child views are now called with `triggerMethod`, meaning they trigger the event and call the corresponding "onEventName" method
+
+* Modules
+ * Finalizers now run with the module as the `this` context
+
+* Marionette.getOption
+ * Fixed support for "falsey" values in an object's `options`
+
+* Build process
+ * Fixed build process to work on case-sensitive file systems (Linux, for example)
+
+### v1.0.0-rc3 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-rc2...v1.0.0-rc3)
+
+* Updated Backbone v0.9.10
+
+* Updated jQuery to v1.9.0
+ * Fixed a few minor unit test issues w/ jQuery update
+
+* Read [the upgrade guide](https://github.com/marionettejs/backbone.marionette/blob/master/upgradeGuide.md) for upgrading from v1.0.0-rc2 to v1.0.0-rc3
+
+### v1.0.0-rc3 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-rc2...v1.0.0-rc3)
+
+* **IMPORTANT:** Be sure to read [the upgrade guide](https://github.com/marionettejs/backbone.marionette/blob/master/upgradeGuide.md) for upgrading from v1.0.0-rc2 to v1.0.0-rc3
+
+* Backbone v0.9.9
+ * **BREAKING:** Backbone v0.9.2 is no longer supported
+ * Backbone v0.9.9 is now supported
+
+* Marionette.Async
+ * **BREAKING:** Marionette.Async is no longer supported
+
+* Backbone.EventBinder / Marionette.EventBinder
+ * **BREAKING:** Marionette.EventBinder / Backbone.EventBinder have been removed entirely.
+ * Backbone.Events supercedes the older objects
+ * Backbone.Wreqr.EventAggregator also supercedes Marionette.EventBinder
+
+* EventBinder -> EventAggregator
+ * **BREAKING:** Backbone.Werqr.EventAggregator largely replaces Backbone.EventBinder
+ * **BREAKING:** `bindTo` has been replaced with `listenTo`
+ * **BREAKING:** `unbindAll` has been replaced with `stopListening`
+ * **BREAKING:** `unbindFrom` has been removed and will not be replaced
+
+* Marionette.addEventBinder
+ * **BREAKING:** This function will mix in Backbone.Events to the target object if it does not exist
+ * **BREAKING:** This function will alter the `listenTo` method of the target to accept a `context` parameter as the 4th parameter of the method
+
+* All Views, Controller, etc
+ * **BREAKING:** Backbone.EventBinder is no longer mixed in
+ * **BREAKING:** See 'EventBinder -> EventAggregator' changes regarding method names to use for binding / unbinding events
+
+* CollectionView
+ * Added `removeChildView` to remove a specific view instance
+ * Fixed event handler leak for child views that have been removed
+ * Changed the implementation for triggering the "show" event / "onShow" method call, to avoid memory leaks
+ * Fixed the `index` parameter for adding a model to the collection, and getting the view in to the right place
+
+* All Views
+ * **BREAKING:** The `initialEvents` method has been removed. Use the `initialize` method, the `collectionEvents` or `modelEvents` configuration instead.
+ * Allow `modelEvents` and `collectionEvents` to be a function that returns a hash
+ * Allow `ui` configuration to be a function that returns a hash
+ * `modelEvents` and `collectionEvents` are now delegated / undelegated with Backbone.View's `.delegateEvents` and `.undelegateEvents` method calls
+ * View `triggers` now include an `args` object with `args.view`, `args.model` and `args.collection`
+
+* Modules
+ * Added alternate syntax for specifying `startWithParent` option
+ * Fixed a bug where a module would not be started without an explicit definition for that module (#388 & #400)
+
+### v1.0.0-rc2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-rc1...v1.0.0-rc2)
+
+* CollectionView / CompositeView
+ * **BREAKING: ** Changed the `item:added` event to `before:item:added` and `after:item:added`
+ * Fixed the `onShow` callbacks, so they can be used in the `initialize` method
+
+* AMD build
+ * Fixed the AMD build by adding Backbone.BabySitter to the AMD dependency list
+
+* All Views
+ * All views (include Marionette.View) now have a "dom:refresh" and `onDomRefresh` event / method triggered
+
+### v1.0.0-rc1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-beta6...v1.0.0-rc1)
+
+* Fixed IE < 9 support w/ calls to `.apply` when `arguments` was null or undefined
+
+* Module
+ * **BREAKING:** Renamed "initialize:before" event to "before:start", for consistency
+ * **BREAKING:** Renamed "initialize:after" event to "start", for consistency
+ * Triggers a "before:stop" event/method before the module is stopped
+ * Triggers a "stop" event/method after the module has been stopped
+
+* Marionette.View
+ * **BREAKING**: The `bindBackboneEntityTo` method has been removed from Marionette.View and replaced with `Marionette.bindEntityEvents` function.
+
+* Marionette.bindEntityEvents
+ * This function has been extracted from Marionette.View, and will bind an events hash to the events from an entity (model or collection), using the supplied EventBinder object (or any object with a bindTo method)
+
+* Marionette.EventBinder
+ * The context of the callback method defaults to the object w/ the `bindTo` method
+
+* CollectionView / CompositeView
+ * The "item:added"/`onItemAdded` callback method are now fired after an item view has been rendered and added to it's parent collection view
+ * The "itemview:" events - events that are forwarded from item views - can now have a custom prefix with the `itemViewEventPrefix` setting
+
+* ItemView
+ * Added a "dom:refresh" event/callback method that fires after a view has been rendered, placed in the DOM with a Marionette.Region, and is re-rendered
+
+* All Views
+ * The `modelEvents` and `collectionEvents` can now have a function configured as the value in the `{ "event:name": "value" }` configuration hash
+ * A view that uses `bindTo` for its own "close" event will have it's close handler called correctly
+ * Returning `false` from the `onBeforeClose` method will prevent the view from being closed
+
+### v1.0.0-beta6 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-beta5...v1.0.0-beta6)
+
+* CollectionView / CompositeView
+ * **BREAKING:** The `.children` attribute, used to store child views, is no longer an object literal. It is now an instance of `Backbone.ChildViewContainer` from Backbone.BabySitter
+ * Updated to use [Backbone.BabySitter](https://github.com/marionettejs/backbone.babysitter) to store and manage child views
+
+* Controller
+ * Added a default `close` method to unbind all events on the controller instance and controller event binder
+ * Trigger a "close"/onClose event/method when closing
+ * Fixed initialize method so `options` parameter is always a valid object
+
+* Modules
+ * Fixed an issue with grand-child modules being defined with a non-existent direct parent, and starting the top level parent directly
+
+### v1.0.0-beta5 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-beta4...v1.0.0-beta5)
+
+* Modules
+ * Fixed the `startWithParent` option so that you only have to specify `startWithParent: false` once, no matter how many files the module definition is split in to
+
+### v1.0.0-beta4 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-beta3...v1.0.0-beta4)
+
+* CollectionView / CompositeView
+ * **BREAKING:** Changed when the `itemViewOptions` gets called, in order to simplify the `buildItemView` method and make it easier to override
+ * **BREAKING:** The `storeChild` method now requires an instance of the item being rendered, as well as the view that was rendered for it
+
+* CompositeView / templateHelpers
+ * **BREAKING:** Fixed the `CompositeView` so that `serializeData` is no longer responsible for mixing in the `templateHelpers`
+
+* Controller
+ * Added a very basic `Marionette.Controller` object, and basic documentation for it
+
+* Marionette.getOption
+ * Added a convience method to get an object's options either from the object directly, or from it's `this.options`, with `this.options` taking precedence
+ * Converted use of `this.options` to use `Marionette.getOption` through most of the code
+
+* Marionette.createObject
+ * Added a convience method to create an object that inherits from another, as a wrapper / shim around `Object.create`
+
+### v1.0.0-beta3 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-beta2...v1.0.0-beta3)
+
+* Region
+ * Fixed "show" method so that it includes the view instance being shown, again
+
+### v1.0.0-beta2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v1.0.0-beta1...v1.0.0-beta2)
+
+* templateHelpers
+ * **BREAKING:** Changed when the templateHelpers is mixed in to the data for a view, so that it is no longer dependent on the `serializeData` implementation
+
+* Region
+ * **BREAKING:** Changed "view:show" event to "show"
+ * **BREAKING:** Changed "view:closed" event to "close"
+ * All region events and events that the triggers from a view are now triggered via Marionette.triggerMethod.
+
+* Marionette.EventAggregator
+ * **BREAKING:** The `bindTo` method no longer assumes you are binding to the EventAggregator instance. You must specify the object that is triggering the event: `ea.bindto(ea, "event", callback, context)`
+ * Marionette.EventAggregator combines Backbone.Wreqr.EventAggregator with Backbone.EventBinder, allowing the event aggregator to act as it's own event binder
+
+* CollectionView
+ * Fixed bug where adding an item to a collection would not allow the CollectionView to propagate the itemView's events
+ * Allow `itemViewOptions` to be specified in CollectionView constructor options
+
+* Application
+ * The events triggered from the Application object instance are now triggered with corresponding "on{EventName}" method calls
+
+* Backbone.EventBinder
+ * Updated to v0.1.0 of Backbone.EventBinder, allowing for jQuery/DOM events to be handled within the EventBinder instances / `bindTo` methods
+
+* AMD Wrapper
+ * The "core" AMD wrapper specifies Backbone.Wreqr and Backbone.EventBinder
+ * The "standard" AMD wrapper does not specify Backbone.Wreqr / EventBinder, as these are built in
+
+* Build / downloads
+ * The standard and AMD versions of `backbone.marionette.js` and `backbone.marionette.min.js` include all dependencies (EventBinder, Wreqr)
+ * The "core" versions of `backbone.marionette.js` and `backbone.marionette.min.js` do not include any dependencies (EventBinder, Wreqr)
+
+### v1.0.0-beta1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.10.2...v1.0.0-beta1)
+
+* Backbone.EventBinder
+ * **BREAKING:** Marionette's EventBinder has been extracted to the Backbone.EventBinder repository and plugin. You must include this file in your app, available at https://github.com/marionettejs/backbone.eventbinder
+
+* Backbone.Wreqr
+ * **BREAKING:** Marionette's EventAggregator has been extracted to the Backbone.Wreqr repository and plugin. You must include this file in your app, available at https://github.com/marionettejs/backbone.wreqr
+
+* All Views
+ * **BREAKING:** `beforeRender` method is now `onBeforeRender`
+ * **BREAKING:** `beforeClose` method is now `onBeforeClose`
+ * **BREAKING:** The `render` method for all Marionette views is bound to the view instance
+ * All view events are now triggered with `triggerMethod`, calling their corresponding method on the view if it exists
+ * All views now have an `isClosed` attribute on them, which is set to `true` when calling the `close()` method and reset to `false` when calling the `render()` method
+ * EventBinder is now attached to the views with the `Marionette.addEventBinder` method call
+
+* CompositeView
+ * **BREAKING:** CompositeView will only render a model in to it's template, instead of a model or collection. It will still render the collection as itemView instances.
+
+* Modules
+ * **BREAKING:** Split module definitions can now receive custom args per module definition, instead of sharing / replacing them across all definitions
+
+* CollectionView / CompositeView
+ * Cleaned up the `getItemViewContainer` code, and improved the error that is thrown when the specified container element is not found
+ * Can attach existing view instance w/ existing DOM element as child of collection view / composite view, in parent's `initialize` function
+ * Fixed a bug where an undefined `this.options` would prevent child views from being rendered, trying to find the index of the view
+
+* Layout
+ * Allow a Layout to be defined without `regions`, using Underscore v1.4.x
+
+* View / ItemView / CompositeView
+ * Removed the `serializeData` method and added directly to `ItemView` and `CompositeView` as needed
+
+* Application
+ * Application regions can now be specified as a jQuery selector string, a region type, or an object literal with a selector and type: `{selector: "#foo", regionType: MyCustomRegion}`
+ * added `.commands` as instance of Backbone.Wreqr.Commands, to facilitate command execution
+ * added `.execute` method for direct command execution
+ * added `.reqres` as instance of Backbone.Wreqr.RequestResponse, to facilitate request/response execution
+ * added `.request` method for direct requesting of a response
+
+* Marionette.triggerMethod
+ * Added `Marionette.triggerMethod` method to trigger an event and call the corresponding method. For example, `view.triggetMethod("before:render")` will trigger the "before:render" event and call the `onBeforeRender` method.
+
+* Marionette.addEventBinder
+ * Added `Marionette.addEventBinder` method to add all of the Backbone.Wreqr.EventBinder methods to a specified target object
+
+* Misc
+ * Added `Marionette.extend` as alias to Backbone's `extend` method for more consistent use
+ * jQuery ($) support now works from global `$` or `window.jQuery`
+ * Updated to Underscore.js v1.4.1
+ * Updated to jQuery v1.8.2
+
+### v0.10.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.10.1...v0.10.2)
+
+* Callbacks
+ * Fixed a bug that caused callbacks to fire multiple times after calling `reset`
+
+* Layout
+ * Fixed a bug that prevented the regions from being re-initialized correctly, when using `render` as a callback method for an event
+
+### v0.10.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.10.0...v0.10.1)
+
+* Modules
+ * Fixed a bug when defining modules in reverse order, that prevented `startWithParent` from working correctly
+
+### v0.10.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.13...v0.10.0)
+
+* Modules
+ * **BREAKING:** Module definition functions are executed immediately and only once, not every time you call `start`
+ * **BREAKING:** Renamed `startWithApp` to `startWithParent` in module definitions
+ * **BREAKING:** Sub-modules rely on the parent module to start them, by default, but can be started manually
+ * **BREAKING:** Sub-modules default to starting with their parent module start
+ * **BREAKING:** Specifying `startWithParent: false` for a sub-module will prevent the module from being started when the parent starts
+ * **BREAKING:** Specifying `startWithParent: false` for a top-level module will prevent the module from being started when the parent `Application` starts
+ * **BREAKING:** When starting a module, sub-modules will be started / initialized before parent modules (depth-first hierarchy traversal)
+ * **BREAKING:** When stopping a module, sub-modules will be stopped / finalized before parent modules (depth-first hierarchy traversal)
+ * Fixed: retrieving a module by name (`var foo = MyApp.module("Foo");`) will not change the module's definition or `startWithParent` setting
+
+* CollectionView
+ * Allow `itemViewOptions` to be a function, which recieves the `item` as an argument
+
+* Callbacks
+ * Added `reset` method to reset the list of callbacks and allow them to be run again, when needed
+
+### v0.9.13 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.12...v0.9.13)
+
+* CollectionView
+ * Fixed bug that prevented "collection:closed" event from being triggered
+ * Allow different item view to be rendered for each item in collection by overriding `getItemView` method
+
+* CompositeView
+ * Allow different item view to be rendered for each item in collection by overriding `getItemView` method
+
+* Layout
+ * Regions are initialized before prototype constructor, or `initialize` function are called
+
+* All Views
+ * Adds declarative event binding for models and collections. See [Marionette.View documentation](https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.view.md) for more information.
+
+* Build and test
+ * Removed all dependencies on Ruby, in favor of NodeJS and Grunt
+
+### v0.9.12 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.11...v0.9.12)
+
+* Moved [Marionette.Async](https://github.com/marionettejs/backbone.marionette.async) to it's own repository
+* De-linted source code
+* Corrected throwing an "Exception" to throwing an "Error"
+
+### v0.9.11 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.10...v0.9.11)
+
+* JamJS Support
+ * Updated the `package.json` file with more detail and support for [JamJS](http://jamjs.org/).
+
+* Layout
+ * Fixed a global variable leak
+
+### v0.9.10 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.9...v0.9.10)
+
+* ItemView and Layout
+ * **BREAKING:** Removed the default implementation of `initialEvents`, so that a collection "reset" event won't cause the ItemView or Layout to re-render
+* Build Process
+ * Changed from Anvil.js to Grunt.js for the build process
+
+### v0.9.9 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.8...v0.9.9)
+
+* Regions
+ * Added a `reset` method to regions, which closes the open view and deletes the region's cached `el`
+
+### v0.9.8 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.7...v0.9.8)
+
+* Modules
+ * Fixed a bug that ensures modules will start and stop the correct number of times, instead of always stopping immediately after they have been stopped once
+
+### v0.9.7 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.6...v0.9.7)
+
+* Modules
+ * Fixed a bug to ensure modules are only started once, no matter how many definitions the module is split in to
+
+* View Templates
+ * Better support for pre-compiled templates - can specify a function as the `template` setting for a view, and the function will be run as the template, directly.
+
+### v0.9.6 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.5...v0.9.6)
+
+* All Marionette Views
+ * Fixed bug that prevented `bindTo` function and other `EventBinder` functions from being available in `initialize` method of views
+
+### v0.9.5 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.4...v0.9.5)
+
+* Layout
+ * Fixed a typo / bug in default Region type used for layouts
+
+### v0.9.4 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.3...v0.9.5)
+
+* BindTo -> EventBindings
+ * **BREAKING:** Renamed `Marionette.BindTo` to `Marionette.EventBindings` and made it a constructor function instead of an object literal
+
+* Modules
+ * **BREAKING:** Changed the API of `Module.create` to be more clear and explicit about `app` parameter
+ * **BREAKING:** Defer module definition until module is started
+ * Modules now have `addInitializer` method to add initializers
+ * Modules can be started (run the initializers) with `start` method
+ * Modules are automatically started when Marionette.Application `start` method is called
+ * App.start sends options to module initializers
+ * Modules that are defined (or loaded from external source) afer app is started will auto-start by default
+ * Can specify a module is not started with the app, to prevent the module from being started when app.start is called
+ * Calling `start` on a module will start all of the sub-modules for that module
+
+* CollectionView/CompositeView
+ * Correctly handles non-existent collection and removing child item views that were added manually
+ * Corrected showing empty view and closing empty view when resetting collection and adding items
+ * Fixed bug to prevent showing the empty view more than once when rendering the collection view
+
+* Application
+ * Added a `removeRegion` method to close / remove regions, as a counter-function to the `addRegions` method
+
+* Marionette.View (all views / base view)
+ * Can specify a set of `ui` elements that are cached jQuery selectors
+
+* Layout
+ * An already closed layout can be re-rendered, and the regions will regenerate
+ * Allow a custom region type to be specified for all regions, as well as per-region instance
+
+### v0.9.3 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.2...v0.9.3)
+
+* CompositeView
+ * Cleaned up the method to get / cache the `itemViewContainer`
+ * Allow `itemViewContainer` to be a function that return a jQuery selector string
+
+* View `render` methods all return `this` in the standard Marionette views (the async views still return a deferred object).
+
+### v0.9.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.1...v0.9.2)
+
+* CompositeView
+ * Added `itemViewContainer` to specify which element children / itemView instances should be appended to
+
+* CollectionView
+ * Now triggers "before:render" and "render" events
+
+* Region
+ * Returns a deferred/promise from the `show` method, with Marionette.Async
+
+* Fixed bug in template cache for Marionette.Async
+
+* Marionette can now be installed with [Volo](https://github.com/volojs/volo)
+
+### v0.9.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.9.0...v0.9.1)
+
+* CollectionView and CompositeView properly close their `emptyView` instance when an item is added to the view's collection
+* CollectionView and CompositeView will show their `emptyView` after the last item has been removed from the collection
+
+### v0.9.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.8.4...v0.9.0)
+
+* **BREAKING** Async Support Removed From Core Marionette
+ * Marionette no longer supports asynchronous / deferred rendering in any view, by default
+ * Async / deferred rendering are now provided via `backbone.marionette.async.js` add-on
+
+* Split the single src/backbone.marionette.js file into multiple files for easier maintenance
+
+* Marionette.Async:
+ * Added `Marionette.Async` add-on which provides support for rendering and retrieving templates asynchronously
+
+* Marionette.View:
+ * **BREAKING** Renamed the `getTemplateSelector` method to `getTemplate`
+ * Call `unbindAll` to unbind all bound events, later in the close process, so the `close` event can be listened to
+
+* ItemView:
+ * **BREAKING** The `template` attribute no longer allows you to specify a function that returns a jQuery selector. Override `getTemplate` to do this.
+ * **BREAKING** The `renderHtml` method has been removed from the ItemView
+ * **BREAKING** Async support removed
+
+* CollectionView:
+ * **BREAKING** Async support removed
+ * Now supports optional `emptyView` attribute, to specify what view to render when no items exist in the collection
+ * Fixed a memory leak for closed item views
+ * ItemView is now guaranteed to have it's "onRender" and "onShow" methods called, when rendering the collection and when adding a new item to the collection / rendering the new item view
+ * Calls an `onItemAdded` method when adding an item/item view, just prior to rendering the item view
+ * Can now specify an `itemViewOptions` object literal on your collection view definition, and the data will be passed to each itemView instance as part of the itemView's options
+ * The `appendHtml` method receives a third argument of the itemView's "index" for sorted collections
+
+* CompositeView:
+ * **BREAKING** When a CompositeView's collection is reset, only the collection will be re-rendered. It will no longe re-render the composite's template/model, just the collection.
+ * **BREAKING** Async support removed
+ * (see change list for `CollectionView`)
+
+* Layout:
+ * **BREAKING** Regions specified within a layout are now available immediately after creating a layout instance
+ * **BREAKING** Re-rendering a layout will close all regions and reset them to the new DOM elements that were rendered
+ * **BREAKING** Layouts no longer have a `.vent` event aggregator hanging off them
+ * **BREAKING** Async support removed
+
+* Region:
+ * **BREAKING** Removed the ability to send a second parameter to a regions' "show" method
+ * **BREAKING** Changed the implementation of `Region` to allow easier overriding of how the new view is added to the DOM
+ * **BREAKING** Async support removed
+
+* TemplateCache:
+ * **BREAKING** Moved TemplateCache to object instances instead of single object literal
+ * **BREAKING** Moved the `loadTemplate` and `compileTemplate` to `TemplateCache.prototype`
+ * **BREAKING** `TemplateCache.get` no longer accepts a callback method. It always returns jQuery promise
+
+* Renderer:
+ * **BREAKING** Removed the `renderHtml` method
+ * Rendering a pre-compiled template function is now much easier - just override the `Renderer.render` method.
+
+* Modules:
+ * **BREAKING** Modules must be defined on an instance of a Marionette.Application, and cannot be defined from another module directly
+ * **BREAKING** Modules no longer allow you to return a custom module object from the module definition function
+ * **BREAKING** Modules no longer allow you to add initializers to them
+ * **BREAKING** Modules no longer have a `.vent` event aggregator hanging off them
+ * Extracted `Marionette.Module` in to it's own constructor function to be used as modules, instead of Marionette.Application
+ * Modules allow you to pass in any arbirary arguments, after the module definition function, and they will be supplied to the module definition function
+ * The `this` argument in a module definition function is now the module itself
+
+* Callbacks:
+ * **BREAKING** Switched the order of parameters for the `run` method to `args, context`
+
+* BindTo:
+ * The unbinding of an event now considers the `context` parameter when unbinding, allowing multiple handers to be bound to the same event from the same object, and unbinding only one of them
+
+### v0.8.4 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.8.3...v0.8.4)
+
+* Fixed: A call to `.module` will correctly pass the `Application` instance from which `.module` was called, as the second parameter of the module definition function
+
+### v0.8.3 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.8.2...v0.8.3)
+
+* Module definitions can be split across multiple files and/or multiple calls to define the module
+
+### v0.8.2 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.8.1...v0.8.2)
+
+* Views now have the ability to define `triggers` which will convert a DOM event in to a `view.trigger` event
+
+### v0.8.1 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.8.0...v0.8.1)
+
+* Module definition functions will only be applied to the last module in the . chain
+
+### v0.8.0 [view commit logs](https://github.com/marionettejs/backbone.marionette/compare/v0.7.6...v0.8.0)
+
+* Added modules and sub-modules through the Application object
+
+### v0.7.6
+
+* An `itemView` instance as part of a Collection View or Composite View, will have it's events bubbled up through the parent view, prepended with "itemview:" as the event name
+
+### v0.7.5
+
+* The `onBefore` method of ItemView can now return a deferred object
+* Code cleanup for rendering methods
+
+### v0.7.4
+
+* Fixed issue with `unbindAll` in BindTo, that was skipping some items
+
+### v0.7.3
+
+* The `bindTo` method on the `EventAggregator` now returns a binding configuration object
+* Automatic mixing in of `templateMethods` as template / view helper methods, in views that use the `serializeData` function
+* A friendlier error message will be thrown from an appRouter if a route is configured with a method that does not exist on the controller
+
+### v0.7.2
+
+* Extracted `compileTemplate` method in TemplateCache for clarity and easier modification
+* ItemView will wait until `onRender` has completed before triggering other rendered events
+* Region now supports an `onShow` method, when defining a custom region
+* Moved the default `serializeData` method to the base Marionette.View
+* CompositeView now calls the `serializeData` method to get the model's data for the view
+* `BindTo` changes:
+ * The `bindTo` method returns a "binding" object so that it can be unbound easily
+ * Now has an `unbindFrom` method that will unbind a binding object
+
+### v0.7.1
+
+* ItemView now has a `renderHtml` method that can be overriden to render the item view's data
+* Region now supports an `initialize` function when extending a region to your own object type
+* CollectionView correctly defers until all children are rendered
+* Underscore templates are cached as pre-compiled templates, instead of re-compiling them on every render
+* Updating AMD support to also work with CommonJS / NodeJS
+* Correctiong build to include header / license info for all output files
+* Pass JSLint with no warnings (run w/ Anvil.js build process)
+* Removed GZip release files, as they were broken anyways
+
+### v0.7.0
+
+* **BREAKING**: The `renderTemplate` method has moved from the `ItemView` prototype on to the `Renderer` object
+* **BREAKING**: The `appendHtml` method of the `CollectionView` now takes `collectionView, itemView` as the arguments, instead of `el, html`
+* Added `Marionette.View` object, to contain a few basic parts of every Marionette view
+* Added `Marionette.Renderer` object, to handle template rendering
+* Views correctly trigger the "close" events before unbinding event subscribers
+* Additional `CollectionView` changes:
+ * Extracted `getItemView` method to retrieve the `itemView` type, either from `this.itemView` or `this.options.itemView`
+ * Extracted `buildItemView` method to build each item's view
+ * Renamed `removeChildView` to `removeItemView` to make the language consistent
+ * Triggers "item:added" event after each item has been added
+ * Triggers "item:removed" event after an item has been removed
+* `CompositeView` changes:
+ * No longer takes a `modelView`. Now directly renders the `template` specified
+ * Defaults to a recurive structure, where `itemView` is the current composite view type
+* A `Region` will trigger a `show` event from any view that it shows
+* Added common "render" event to all the view types
+* Updated to Backbone v0.9.2
+* Updated to jQuery v1.7.2
+* AMD / RequireJS compliant version is provided
+* Now using [Anvil.js](https://github.com/arobson/anvil.js) for builds
+
+#### v0.6.4
+
+* CollectionView and CompositeView can render without a collection
+
+#### v0.6.3
+
+* `ItemView` changes
+ * Calls a `beforeRender` and `beforeClose` method on the view, if it exists
+ * Triggers a `item:before:render` event, just prior to rendering
+ * Triggers a `item:before:close` and `item:closed` events, around the view's `close` method
+* `CollectionView` changes
+ * Calls a `beforeRender` and `beforeClose` method on the view, if it exists
+ * Triggers a `collection:before:render` event before rendering
+ * Triggers a `collection:before:close` and `collection:closed` event, surrounding closing of the view
+* The `CollectionView` and `CompositeView` now close child views before closing itself
+
+#### v0.6.2
+
+* **BREAKING:** The `CollectionView` no longer has a `reRender` method. Call `render` instead
+* **BREAKING:** The `TemplateCache.get` method now returns a plain string instead of a jQuery selector object
+* Fixed a bug with closing and then re-using a Layout with defined regions
+* Fixed a potential race condition for loading / caching templates where a template would be loaded multiple times instead of just once
+
+#### v0.6.1
+
+* Fixed the composite view so that it renders the collection correctly when the collection is "reset"
+* Fixed the composite view so that it re-renders correctly
+* Fixed various deferred usages to only return promises, instead of the full deferred object
+
+#### v0.6.0
+
+* **BREAKING:** Renamed `LayoutManager` to `Layout`
+* **BREAKING:** Renamed `RegionManager` to `Region`
+* **BREAKING:** Renamed `TemplateManager` to `TemplateCache`
+
+* **Layout**
+ * **BREAKING:** `Layout.render` no longer returns the view itself, now returns a jQuery deferred object
+ * The `.vent` attribute is now available in the `initializer` method
+ * Ensures that regions select the `$el` within the Layout's `$el` instead of globally on the page
+ * Initialize the regions before the layout, allowing access to the regions in the `onRender` method of the layout
+ * Close the Layout's regions before closing the layout itself
+
+* **CompositeView**
+ * **BREAKING:** `CompositeView.render` no longer returns the view itself, now returns a jQuery deffered object
+ * Will only render the collection once. You can call `renderCollection` explicitly to re-render the entire collection
+ * Will only render the model view once. You can call `renderModel` explicitly to re-render the model
+ * Correctly close and dispose of the model view
+ * Triggers various events during rendering of model view and collection view
+ * Calls 'onRender' method of composite view, if it exists
+
+* **ItemView**
+ * **BREAKING:** `ItemView.render` no longer returns the view itself, now returns a jQuery deferred object
+ * Optimization to only call `.toJSON` on either model or collection, not both
+ * Trigger "item:rendered" method after rendering (in addition to calling onRender method of the view)
+
+* **CollectionView**
+ * **BREAKING:** `CollectionView.render` no longer returns the view itself, now returns a jQuery deferred object
+ * Trigger "collection:rendered" method after rendering (in addition to calling onRender method)
+
+* Large updates to the readme/documentation
+* Heavy use of `jQuery.Deferred()` and `jQuery.when/then` to better support asynchronous templates and rendering
+
+#### v0.5.2
+
+* **BREAKING:** Renamed `CompositeRegion` to `LayoutManager`
+* Aliased CompsiteRegion to LayoutManager for backwards compatibility
+* Bug fix for correctly initializing LayoutManager with specified options in constructor
+
+#### v0.5.1
+
+* Controller methods fired from an `AppRouter` are now called with `this` set to the controller, instead of the router
+* Fixed a bug in the CompositeView where the list wouldn't render when passing in a populated collection
+
+#### v0.5.0
+
+* **BREAKING:** Extraced `CompositeView` out of the collection view
+* Added `CompositeView` for managing leaf-branch/composite model structures
+* Added `CompositeRegion` for managing nested views and nested region managers
+* Added `attachView` method to `RegionManager` to attach existing view without rendering / replacing
+* Specify how to attach HTML to DOM in region manager's `show` method
+
+#### v0.4.8
+
+* Don't re-render an ItemView when the view's model "change" event is triggered
+
+#### v0.4.7
+
+* Allow `RegionManager` to be instantiated with an `el` specified in the options
+* Change how RegionManagers are added to an Application instance, to reduce memory usage from extraneous types
+
+#### v0.4.6
+
+* AppRouter can have it's `controller` specified directly in the router definition or in the construction function call
+* Extracted `Marionette.EventAggregator` out in to it's own explicit object
+
+#### v0.4.5
+
+* CollectionView closes existing child views before re-rendering itself, when "reset"
+event of collection is triggered
+* CollectionView now has "initialEvents" method which configures it's initial events
+* ItemView now has "initialEvents" method which configures it's initial events
+
+#### v0.4.4
+
+* CollectionView renders itself when the view's collection "reset" event is fired
+* ItemView renders itself when the view's model "change" event is fired
+* ItemView renders itself when the view's collection "reset" event is fired
+
+#### v0.4.3
+
+* Fixed bug with RegionManagers trying to select element before DOM is ready, to lazy-select the element on first use of `show`
+
+#### v0.4.2
+
+* **BREAKING:** Removed the `setOptions` method from the `Callbacks` object
+* Refactored `Callbacks` object to use a jQuery Deferred instead of my own code
+* Fixed template manager's `clear` so it properly clears a single template, when only one is specified
+* Refactored the `RegionManager` code to support several new features
+ * now support returning a jQuery deferred object from a view's `render` method
+ * now have a `close` method that you can call to close the current view
+ * now trigger a "view:show" and "view:close" event
+ * correctly remove reference to previous views, allowing garbage collection of the view
+ * now support the `bindTo` and `unbindAll` methods, for binding/unbinding region manager events
+
+#### v0.4.1
+
+* Minor fix to context of template manager callback, to fix issue w/ async template loading
+
+#### v0.4.0
+
+* **BREAKING:** Rewrote the template manager to be async-template loading friendly
+* **BREAKING:** Dropping support for Backbone v0.5.3 and below
+* Added `Marionette.Callbacks` to manage a collection of callbacks in an async-friendly way
+* Guarantee the execution of app initializer functions, even if they are added after the app
+has been started.
+* App triggers "start" event after initializers and initializer events
+* Updated to Backbone v0.9.1
+
+#### v0.3.1
+
+* Make region managers initialize immediately when calling `app.addRegions`
+
+#### v0.3.0
+
+* **BREAKING:** `view.el` for `ItemView` and `CollectionView` is no longer a jQuery selector object. Use `view.$el` instead
+* **BREAKING:** `regionManger.el` is no longer a jQuery selector object. Use `regionManager.$el` instead
+* Updated to use Backbone v0.9.0
+* Updated to use Underscore v1.3.1
+* Removed default `itemView` from the `CollectionView` definition
+* `CollectionView` now explicitly checks for an `itemView` defined on it, and throws an error if it's not found
+
+#### v0.2.6
+
+* Bind the context (`this`) of application initializer functions to the application object
+
+#### v0.2.5
+
+* Added `AppRouter`, to reduce boilerplate routers down to simple configuration
+* `CollectionView` can be treated as a composite view, rendering an `model` and a `collection` of models
+* Now works with either jQuery, Zepto, or enter.js
+* `ItemView` will throw an error is no template is specified
+
+#### v0.2.4
+
+* Return `this` (the view itself) from `ItemView` and `CollectionView` `render` method
+* Call `onRender` after the `CollectionView` has rendered itself
+
+#### v0.2.3
+
+* Fixed global variable leaks
+* Removed declared, but unused variables
+
+#### v0.2.2
+
+* Fixed binding events in the collection view to use `bindTo` (#6)
+* Updated specs for collection view
+* Documentation fixes (#7)
+
+#### v0.2.1
+
+* Added `TemplateManager` to cache templates
+* CollectionView binds to add/remove and updates rendering appropriately
+* ItemView uses `TemplateManager` for template retrieval
+* ItemView and CollectionView set `this.el = $(this.el)` in constructor
+
+#### v0.2.0
+
+* Added `ItemView`
+* Added `CollectionView`
+* Added `BindTo`
+* Simplified the way `extend` is pulled from Backbone
+
+#### v0.1.0
+
+* Initial release
+* Created documentation
+* Generated annotated source code
diff --git a/js/vendor/backbone.marionette/lib/backbone.marionette.js b/js/vendor/backbone.marionette/lib/backbone.marionette.js
new file mode 100644
index 000000000..3f9a9bfd4
--- /dev/null
+++ b/js/vendor/backbone.marionette/lib/backbone.marionette.js
@@ -0,0 +1,3330 @@
+// MarionetteJS (Backbone.Marionette)
+// ----------------------------------
+// v3.1.0
+//
+// Copyright (c)2016 Derick Bailey, Muted Solutions, LLC.
+// Distributed under MIT license
+//
+// http://marionettejs.com
+
+
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('backbone'), require('underscore'), require('backbone.radio')) :
+ typeof define === 'function' && define.amd ? define(['backbone', 'underscore', 'backbone.radio'], factory) :
+ (global.Marionette = global['Mn'] = factory(global.Backbone,global._,global.Backbone.Radio));
+}(this, function (Backbone,_,Radio) { 'use strict';
+
+ Backbone = 'default' in Backbone ? Backbone['default'] : Backbone;
+ _ = 'default' in _ ? _['default'] : _;
+ Radio = 'default' in Radio ? Radio['default'] : Radio;
+
+ var version = "3.1.0";
+
+ //Internal utility for creating context style global utils
+ var proxy = function proxy(method) {
+ return function (context) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ return method.apply(context, args);
+ };
+ };
+
+ // Borrow the Backbone `extend` method so we can use it as needed
+ var extend = Backbone.Model.extend;
+
+ var deprecate = function deprecate(message, test) {
+ if (_.isObject(message)) {
+ message = message.prev + ' is going to be removed in the future. ' + 'Please use ' + message.next + ' instead.' + (message.url ? ' See: ' + message.url : '');
+ }
+
+ if (!Marionette.DEV_MODE) {
+ return;
+ }
+
+ if ((test === undefined || !test) && !deprecate._cache[message]) {
+ deprecate._warn('Deprecation warning: ' + message);
+ deprecate._cache[message] = true;
+ }
+ };
+
+ deprecate._console = typeof console !== 'undefined' ? console : {};
+ deprecate._warn = function () {
+ var warn = deprecate._console.warn || deprecate._console.log || _.noop;
+ return warn.apply(deprecate._console, arguments);
+ };
+ deprecate._cache = {};
+
+ // Determine if `el` is a child of the document
+ var isNodeAttached = function isNodeAttached(el) {
+ return Backbone.$.contains(document.documentElement, el);
+ };
+
+ // Merge `keys` from `options` onto `this`
+ var mergeOptions = function mergeOptions(options, keys) {
+ var _this = this;
+
+ if (!options) {
+ return;
+ }
+
+ _.each(keys, function (key) {
+ var option = options[key];
+ if (option !== undefined) {
+ _this[key] = option;
+ }
+ });
+ };
+
+ // Marionette.getOption
+ // --------------------
+
+ // Retrieve an object, function or other value from the
+ // object or its `options`, with `options` taking precedence.
+ var getOption = function getOption(optionName) {
+ if (!optionName) {
+ return;
+ }
+ if (this.options && this.options[optionName] !== undefined) {
+ return this.options[optionName];
+ } else {
+ return this[optionName];
+ }
+ };
+
+ // Marionette.normalizeMethods
+ // ----------------------
+
+ // Pass in a mapping of events => functions or function names
+ // and return a mapping of events => functions
+ var normalizeMethods = function normalizeMethods(hash) {
+ var _this = this;
+
+ return _.reduce(hash, function (normalizedHash, method, name) {
+ if (!_.isFunction(method)) {
+ method = _this[method];
+ }
+ if (method) {
+ normalizedHash[name] = method;
+ }
+ return normalizedHash;
+ }, {});
+ };
+
+ // split the event name on the ":"
+ var splitter = /(^|:)(\w)/gi;
+
+ // take the event section ("section1:section2:section3")
+ // and turn it in to uppercase name onSection1Section2Section3
+ function getEventName(match, prefix, eventName) {
+ return eventName.toUpperCase();
+ }
+
+ var getOnMethodName = _.memoize(function (event) {
+ return 'on' + event.replace(splitter, getEventName);
+ });
+
+ // Trigger an event and/or a corresponding method name. Examples:
+ //
+ // `this.triggerMethod("foo")` will trigger the "foo" event and
+ // call the "onFoo" method.
+ //
+ // `this.triggerMethod("foo:bar")` will trigger the "foo:bar" event and
+ // call the "onFooBar" method.
+ function triggerMethod(event) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ // get the method name from the event name
+ var methodName = getOnMethodName(event);
+ var method = getOption.call(this, methodName);
+ var result = void 0;
+
+ // call the onMethodName if it exists
+ if (_.isFunction(method)) {
+ // pass all args, except the event name
+ result = method.apply(this, args);
+ }
+
+ // trigger the event
+ this.trigger.apply(this, arguments);
+
+ return result;
+ }
+
+ // triggerMethodOn invokes triggerMethod on a specific context
+ //
+ // e.g. `Marionette.triggerMethodOn(view, 'show')`
+ // will trigger a "show" event or invoke onShow the view.
+ function triggerMethodOn(context) {
+ for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+ args[_key2 - 1] = arguments[_key2];
+ }
+
+ if (_.isFunction(context.triggerMethod)) {
+ return context.triggerMethod.apply(context, args);
+ }
+
+ return triggerMethod.apply(context, args);
+ }
+
+ // Trigger method on children unless a pure Backbone.View
+ function triggerMethodChildren(view, event, shouldTrigger) {
+ if (!view._getImmediateChildren) {
+ return;
+ }
+ _.each(view._getImmediateChildren(), function (child) {
+ if (!shouldTrigger(child)) {
+ return;
+ }
+ triggerMethodOn(child, event, child);
+ });
+ }
+
+ function shouldTriggerAttach(view) {
+ return !view._isAttached;
+ }
+
+ function shouldAttach(view) {
+ if (!shouldTriggerAttach(view)) {
+ return false;
+ }
+ view._isAttached = true;
+ return true;
+ }
+
+ function shouldTriggerDetach(view) {
+ return view._isAttached;
+ }
+
+ function shouldDetach(view) {
+ if (!shouldTriggerDetach(view)) {
+ return false;
+ }
+ view._isAttached = false;
+ return true;
+ }
+
+ function triggerDOMRefresh(view) {
+ if (view._isAttached && view._isRendered) {
+ triggerMethodOn(view, 'dom:refresh', view);
+ }
+ }
+
+ function handleBeforeAttach() {
+ triggerMethodChildren(this, 'before:attach', shouldTriggerAttach);
+ }
+
+ function handleAttach() {
+ triggerMethodChildren(this, 'attach', shouldAttach);
+ triggerDOMRefresh(this);
+ }
+
+ function handleBeforeDetach() {
+ triggerMethodChildren(this, 'before:detach', shouldTriggerDetach);
+ }
+
+ function handleDetach() {
+ triggerMethodChildren(this, 'detach', shouldDetach);
+ }
+
+ function handleRender() {
+ triggerDOMRefresh(this);
+ }
+
+ // Monitor a view's state, propagating attach/detach events to children and firing dom:refresh
+ // whenever a rendered view is attached or an attached view is rendered.
+ function monitorViewEvents(view) {
+ if (view._areViewEventsMonitored) {
+ return;
+ }
+
+ view._areViewEventsMonitored = true;
+
+ view.on({
+ 'before:attach': handleBeforeAttach,
+ 'attach': handleAttach,
+ 'before:detach': handleBeforeDetach,
+ 'detach': handleDetach,
+ 'render': handleRender
+ });
+ }
+
+ var errorProps = ['description', 'fileName', 'lineNumber', 'name', 'message', 'number'];
+
+ var MarionetteError = extend.call(Error, {
+ urlRoot: 'http://marionettejs.com/docs/v' + version + '/',
+
+ constructor: function constructor(message, options) {
+ if (_.isObject(message)) {
+ options = message;
+ message = options.message;
+ } else if (!options) {
+ options = {};
+ }
+
+ var error = Error.call(this, message);
+ _.extend(this, _.pick(error, errorProps), _.pick(options, errorProps));
+
+ this.captureStackTrace();
+
+ if (options.url) {
+ this.url = this.urlRoot + options.url;
+ }
+ },
+ captureStackTrace: function captureStackTrace() {
+ if (Error.captureStackTrace) {
+ Error.captureStackTrace(this, MarionetteError);
+ }
+ },
+ toString: function toString() {
+ return this.name + ': ' + this.message + (this.url ? ' See: ' + this.url : '');
+ }
+ });
+
+ MarionetteError.extend = extend;
+
+ // Bind/unbind the event to handlers specified as a string of
+ // handler names on the target object
+ function bindFromStrings(target, entity, evt, methods, actionName) {
+ var methodNames = methods.split(/\s+/);
+
+ _.each(methodNames, function (methodName) {
+ var method = target[methodName];
+ if (!method) {
+ throw new MarionetteError('Method "' + methodName + '" was configured as an event handler, but does not exist.');
+ }
+
+ target[actionName](entity, evt, method);
+ });
+ }
+
+ // generic looping function
+ function iterateEvents(target, entity, bindings, actionName) {
+ if (!entity || !bindings) {
+ return;
+ }
+
+ // type-check bindings
+ if (!_.isObject(bindings)) {
+ throw new MarionetteError({
+ message: 'Bindings must be an object.',
+ url: 'marionette.functions.html#marionettebindevents'
+ });
+ }
+
+ // iterate the bindings and bind/unbind them
+ _.each(bindings, function (method, evt) {
+
+ // allow for a list of method names as a string
+ if (_.isString(method)) {
+ bindFromStrings(target, entity, evt, method, actionName);
+ return;
+ }
+
+ target[actionName](entity, evt, method);
+ });
+ }
+
+ function bindEvents(entity, bindings) {
+ iterateEvents(this, entity, bindings, 'listenTo');
+ return this;
+ }
+
+ function unbindEvents(entity, bindings) {
+ iterateEvents(this, entity, bindings, 'stopListening');
+ return this;
+ }
+
+ function iterateReplies(target, channel, bindings, actionName) {
+ if (!channel || !bindings) {
+ return;
+ }
+
+ // type-check bindings
+ if (!_.isObject(bindings)) {
+ throw new MarionetteError({
+ message: 'Bindings must be an object.',
+ url: 'marionette.functions.html#marionettebindrequests'
+ });
+ }
+
+ var normalizedRadioRequests = normalizeMethods.call(target, bindings);
+
+ channel[actionName](normalizedRadioRequests, target);
+ }
+
+ function bindRequests(channel, bindings) {
+ iterateReplies(this, channel, bindings, 'reply');
+ return this;
+ }
+
+ function unbindRequests(channel, bindings) {
+ iterateReplies(this, channel, bindings, 'stopReplying');
+ return this;
+ }
+
+ // Internal utility for setting options consistently across Mn
+ var setOptions = function setOptions() {
+ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+
+ this.options = _.extend.apply(_, [{}, _.result(this, 'options')].concat(args));
+ };
+
+ var CommonMixin = {
+
+ // Imports the "normalizeMethods" to transform hashes of
+ // events=>function references/names to a hash of events=>function references
+ normalizeMethods: normalizeMethods,
+
+ _setOptions: setOptions,
+
+ // A handy way to merge passed-in options onto the instance
+ mergeOptions: mergeOptions,
+
+ // Enable getting options from this or this.options by name.
+ getOption: getOption,
+
+ // Enable binding view's events from another entity.
+ bindEvents: bindEvents,
+
+ // Enable unbinding view's events from another entity.
+ unbindEvents: unbindEvents
+ };
+
+ // MixinOptions
+ // - channelName
+ // - radioEvents
+ // - radioRequests
+
+ var RadioMixin = {
+ _initRadio: function _initRadio() {
+ var channelName = _.result(this, 'channelName');
+
+ if (!channelName) {
+ return;
+ }
+
+ /* istanbul ignore next */
+ if (!Radio) {
+ throw new MarionetteError({
+ name: 'BackboneRadioMissing',
+ message: 'The dependency "backbone.radio" is missing.'
+ });
+ }
+
+ var channel = this._channel = Radio.channel(channelName);
+
+ var radioEvents = _.result(this, 'radioEvents');
+ this.bindEvents(channel, radioEvents);
+
+ var radioRequests = _.result(this, 'radioRequests');
+ this.bindRequests(channel, radioRequests);
+
+ this.on('destroy', this._destroyRadio);
+ },
+ _destroyRadio: function _destroyRadio() {
+ this._channel.stopReplying(null, null, this);
+ },
+ getChannel: function getChannel() {
+ return this._channel;
+ },
+
+
+ // Proxy `bindEvents`
+ bindEvents: bindEvents,
+
+ // Proxy `unbindEvents`
+ unbindEvents: unbindEvents,
+
+ // Proxy `bindRequests`
+ bindRequests: bindRequests,
+
+ // Proxy `unbindRequests`
+ unbindRequests: unbindRequests
+
+ };
+
+ var ClassOptions = ['channelName', 'radioEvents', 'radioRequests'];
+
+ // A Base Class that other Classes should descend from.
+ // Object borrows many conventions and utilities from Backbone.
+ var MarionetteObject = function MarionetteObject(options) {
+ this._setOptions(options);
+ this.mergeOptions(options, ClassOptions);
+ this.cid = _.uniqueId(this.cidPrefix);
+ this._initRadio();
+ this.initialize.apply(this, arguments);
+ };
+
+ MarionetteObject.extend = extend;
+
+ // Object Methods
+ // --------------
+
+ // Ensure it can trigger events with Backbone.Events
+ _.extend(MarionetteObject.prototype, Backbone.Events, CommonMixin, RadioMixin, {
+ cidPrefix: 'mno',
+
+ // for parity with Marionette.AbstractView lifecyle
+ _isDestroyed: false,
+
+ isDestroyed: function isDestroyed() {
+ return this._isDestroyed;
+ },
+
+
+ //this is a noop method intended to be overridden by classes that extend from this base
+ initialize: function initialize() {},
+ destroy: function destroy() {
+ if (this._isDestroyed) {
+ return this;
+ }
+
+ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+
+ this.triggerMethod.apply(this, ['before:destroy', this].concat(args));
+
+ this._isDestroyed = true;
+ this.triggerMethod.apply(this, ['destroy', this].concat(args));
+ this.stopListening();
+
+ return this;
+ },
+
+
+ triggerMethod: triggerMethod
+ });
+
+ // Manage templates stored in `<script>` blocks,
+ // caching them for faster access.
+ var TemplateCache = function TemplateCache(templateId) {
+ this.templateId = templateId;
+ };
+
+ // TemplateCache object-level methods. Manage the template
+ // caches from these method calls instead of creating
+ // your own TemplateCache instances
+ _.extend(TemplateCache, {
+ templateCaches: {},
+
+ // Get the specified template by id. Either
+ // retrieves the cached version, or loads it
+ // from the DOM.
+ get: function get(templateId, options) {
+ var cachedTemplate = this.templateCaches[templateId];
+
+ if (!cachedTemplate) {
+ cachedTemplate = new TemplateCache(templateId);
+ this.templateCaches[templateId] = cachedTemplate;
+ }
+
+ return cachedTemplate.load(options);
+ },
+
+
+ // Clear templates from the cache. If no arguments
+ // are specified, clears all templates:
+ // `clear()`
+ //
+ // If arguments are specified, clears each of the
+ // specified templates from the cache:
+ // `clear("#t1", "#t2", "...")`
+ clear: function clear() {
+ var i = void 0;
+
+ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+
+ var length = args.length;
+
+ if (length > 0) {
+ for (i = 0; i < length; i++) {
+ delete this.templateCaches[args[i]];
+ }
+ } else {
+ this.templateCaches = {};
+ }
+ }
+ });
+
+ // TemplateCache instance methods, allowing each
+ // template cache object to manage its own state
+ // and know whether or not it has been loaded
+ _.extend(TemplateCache.prototype, {
+
+ // Internal method to load the template
+ load: function load(options) {
+ // Guard clause to prevent loading this template more than once
+ if (this.compiledTemplate) {
+ return this.compiledTemplate;
+ }
+
+ // Load the template and compile it
+ var template = this.loadTemplate(this.templateId, options);
+ this.compiledTemplate = this.compileTemplate(template, options);
+
+ return this.compiledTemplate;
+ },
+
+
+ // Load a template from the DOM, by default. Override
+ // this method to provide your own template retrieval
+ // For asynchronous loading with AMD/RequireJS, consider
+ // using a template-loader plugin as described here:
+ // https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs
+ loadTemplate: function loadTemplate(templateId, options) {
+ var $template = Backbone.$(templateId);
+
+ if (!$template.length) {
+ throw new MarionetteError({
+ name: 'NoTemplateError',
+ message: 'Could not find template: "' + templateId + '"'
+ });
+ }
+ return $template.html();
+ },
+
+
+ // Pre-compile the template before caching it. Override
+ // this method if you do not need to pre-compile a template
+ // (JST / RequireJS for example) or if you want to change
+ // the template engine used (Handebars, etc).
+ compileTemplate: function compileTemplate(rawTemplate, options) {
+ return _.template(rawTemplate, options);
+ }
+ });
+
+ var _invoke = _.invokeMap || _.invoke;
+
+ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
+
+ // MixinOptions
+ // - behaviors
+
+ // Takes care of getting the behavior class
+ // given options and a key.
+ // If a user passes in options.behaviorClass
+ // default to using that.
+ // If a user passes in a Behavior Class directly, use that
+ // Otherwise delegate the lookup to the users `behaviorsLookup` implementation.
+ function getBehaviorClass(options, key) {
+ if (options.behaviorClass) {
+ return options.behaviorClass;
+ //treat functions as a Behavior constructor
+ } else if (_.isFunction(options)) {
+ return options;
+ }
+
+ // behaviorsLookup can be either a flat object or a method
+ if (_.isFunction(Marionette.Behaviors.behaviorsLookup)) {
+ return Marionette.Behaviors.behaviorsLookup(options, key)[key];
+ }
+
+ return Marionette.Behaviors.behaviorsLookup[key];
+ }
+
+ // Iterate over the behaviors object, for each behavior
+ // instantiate it and get its grouped behaviors.
+ // This accepts a list of behaviors in either an object or array form
+ function parseBehaviors(view, behaviors) {
+ return _.chain(behaviors).map(function (options, key) {
+ var BehaviorClass = getBehaviorClass(options, key);
+ //if we're passed a class directly instead of an object
+ var _options = options === BehaviorClass ? {} : options;
+ var behavior = new BehaviorClass(_options, view);
+ var nestedBehaviors = parseBehaviors(view, _.result(behavior, 'behaviors'));
+
+ return [behavior].concat(nestedBehaviors);
+ }).flatten().value();
+ }
+
+ var BehaviorsMixin = {
+ _initBehaviors: function _initBehaviors() {
+ var behaviors = _.result(this, 'behaviors');
+
+ // Behaviors defined on a view can be a flat object literal
+ // or it can be a function that returns an object.
+ this._behaviors = _.isObject(behaviors) ? parseBehaviors(this, behaviors) : {};
+ },
+ _getBehaviorTriggers: function _getBehaviorTriggers() {
+ var triggers = _invoke(this._behaviors, 'getTriggers');
+ return _.extend.apply(_, [{}].concat(_toConsumableArray(triggers)));
+ },
+ _getBehaviorEvents: function _getBehaviorEvents() {
+ var events = _invoke(this._behaviors, 'getEvents');
+ return _.extend.apply(_, [{}].concat(_toConsumableArray(events)));
+ },
+
+
+ // proxy behavior $el to the view's $el.
+ _proxyBehaviorViewProperties: function _proxyBehaviorViewProperties() {
+ _invoke(this._behaviors, 'proxyViewProperties');
+ },
+
+
+ // delegate modelEvents and collectionEvents
+ _delegateBehaviorEntityEvents: function _delegateBehaviorEntityEvents() {
+ _invoke(this._behaviors, 'delegateEntityEvents');
+ },
+
+
+ // undelegate modelEvents and collectionEvents
+ _undelegateBehaviorEntityEvents: function _undelegateBehaviorEntityEvents() {
+ _invoke(this._behaviors, 'undelegateEntityEvents');
+ },
+ _destroyBehaviors: function _destroyBehaviors(args) {
+ // Call destroy on each behavior after
+ // destroying the view.
+ // This unbinds event listeners
+ // that behaviors have registered for.
+ _invoke.apply(undefined, [this._behaviors, 'destroy'].concat(_toConsumableArray(args)));
+ },
+ _bindBehaviorUIElements: function _bindBehaviorUIElements() {
+ _invoke(this._behaviors, 'bindUIElements');
+ },
+ _unbindBehaviorUIElements: function _unbindBehaviorUIElements() {
+ _invoke(this._behaviors, 'unbindUIElements');
+ },
+ _triggerEventOnBehaviors: function _triggerEventOnBehaviors() {
+ var behaviors = this._behaviors;
+ // Use good ol' for as this is a very hot function
+ for (var i = 0, length = behaviors && behaviors.length; i < length; i++) {
+ triggerMethod.apply(behaviors[i], arguments);
+ }
+ }
+ };
+
+ // MixinOptions
+ // - collectionEvents
+ // - modelEvents
+
+ var DelegateEntityEventsMixin = {
+ // Handle `modelEvents`, and `collectionEvents` configuration
+ _delegateEntityEvents: function _delegateEntityEvents(model, collection) {
+ this._undelegateEntityEvents(model, collection);
+
+ var modelEvents = _.result(this, 'modelEvents');
+ bindEvents.call(this, model, modelEvents);
+
+ var collectionEvents = _.result(this, 'collectionEvents');
+ bindEvents.call(this, collection, collectionEvents);
+ },
+ _undelegateEntityEvents: function _undelegateEntityEvents(model, collection) {
+ var modelEvents = _.result(this, 'modelEvents');
+ unbindEvents.call(this, model, modelEvents);
+
+ var collectionEvents = _.result(this, 'collectionEvents');
+ unbindEvents.call(this, collection, collectionEvents);
+ }
+ };
+
+ // Borrow event splitter from Backbone
+ var delegateEventSplitter = /^(\S+)\s*(.*)$/;
+
+ function uniqueName(eventName, selector) {
+ return [eventName + _.uniqueId('.evt'), selector].join(' ');
+ }
+
+ // Set event name to be namespaced using a unique index
+ // to generate a non colliding event namespace
+ // http://api.jquery.com/event.namespace/
+ var getUniqueEventName = function getUniqueEventName(eventName) {
+ var match = eventName.match(delegateEventSplitter);
+ return uniqueName(match[1], match[2]);
+ };
+
+ // Internal method to create an event handler for a given `triggerDef` like
+ // 'click:foo'
+ function buildViewTrigger(view, triggerDef) {
+ if (_.isString(triggerDef)) {
+ triggerDef = { event: triggerDef };
+ }
+
+ var eventName = triggerDef.event;
+ var shouldPreventDefault = triggerDef.preventDefault !== false;
+ var shouldStopPropagation = triggerDef.stopPropagation !== false;
+
+ return function (e) {
+ if (shouldPreventDefault) {
+ e.preventDefault();
+ }
+
+ if (shouldStopPropagation) {
+ e.stopPropagation();
+ }
+
+ view.triggerMethod(eventName, view);
+ };
+ }
+
+ var TriggersMixin = {
+
+ // Configure `triggers` to forward DOM events to view
+ // events. `triggers: {"click .foo": "do:foo"}`
+ _getViewTriggers: function _getViewTriggers(view, triggers) {
+ // Configure the triggers, prevent default
+ // action and stop propagation of DOM events
+ return _.reduce(triggers, function (events, value, key) {
+ key = getUniqueEventName(key);
+ events[key] = buildViewTrigger(view, value);
+ return events;
+ }, {});
+ }
+ };
+
+ // allows for the use of the @ui. syntax within
+ // a given key for triggers and events
+ // swaps the @ui with the associated selector.
+ // Returns a new, non-mutated, parsed events hash.
+ var _normalizeUIKeys = function _normalizeUIKeys(hash, ui) {
+ return _.reduce(hash, function (memo, val, key) {
+ var normalizedKey = _normalizeUIString(key, ui);
+ memo[normalizedKey] = val;
+ return memo;
+ }, {});
+ };
+
+ // utility method for parsing @ui. syntax strings
+ // into associated selector
+ var _normalizeUIString = function _normalizeUIString(uiString, ui) {
+ return uiString.replace(/@ui\.[a-zA-Z-_$0-9]*/g, function (r) {
+ return ui[r.slice(4)];
+ });
+ };
+
+ // allows for the use of the @ui. syntax within
+ // a given value for regions
+ // swaps the @ui with the associated selector
+ var _normalizeUIValues = function _normalizeUIValues(hash, ui, properties) {
+ _.each(hash, function (val, key) {
+ if (_.isString(val)) {
+ hash[key] = _normalizeUIString(val, ui);
+ } else if (_.isObject(val) && _.isArray(properties)) {
+ _.extend(val, _normalizeUIValues(_.pick(val, properties), ui));
+ /* Value is an object, and we got an array of embedded property names to normalize. */
+ _.each(properties, function (property) {
+ var propertyVal = val[property];
+ if (_.isString(propertyVal)) {
+ val[property] = _normalizeUIString(propertyVal, ui);
+ }
+ });
+ }
+ });
+ return hash;
+ };
+
+ var UIMixin = {
+
+ // normalize the keys of passed hash with the views `ui` selectors.
+ // `{"@ui.foo": "bar"}`
+ normalizeUIKeys: function normalizeUIKeys(hash) {
+ var uiBindings = this._getUIBindings();
+ return _normalizeUIKeys(hash, uiBindings);
+ },
+
+
+ // normalize the passed string with the views `ui` selectors.
+ // `"@ui.bar"`
+ normalizeUIString: function normalizeUIString(uiString) {
+ var uiBindings = this._getUIBindings();
+ return _normalizeUIString(uiString, uiBindings);
+ },
+
+
+ // normalize the values of passed hash with the views `ui` selectors.
+ // `{foo: "@ui.bar"}`
+ normalizeUIValues: function normalizeUIValues(hash, properties) {
+ var uiBindings = this._getUIBindings();
+ return _normalizeUIValues(hash, uiBindings, properties);
+ },
+ _getUIBindings: function _getUIBindings() {
+ var uiBindings = _.result(this, '_uiBindings');
+ var ui = _.result(this, 'ui');
+ return uiBindings || ui;
+ },
+
+
+ // This method binds the elements specified in the "ui" hash inside the view's code with
+ // the associated jQuery selectors.
+ _bindUIElements: function _bindUIElements() {
+ var _this = this;
+
+ if (!this.ui) {
+ return;
+ }
+
+ // store the ui hash in _uiBindings so they can be reset later
+ // and so re-rendering the view will be able to find the bindings
+ if (!this._uiBindings) {
+ this._uiBindings = this.ui;
+ }
+
+ // get the bindings result, as a function or otherwise
+ var bindings = _.result(this, '_uiBindings');
+
+ // empty the ui so we don't have anything to start with
+ this._ui = {};
+
+ // bind each of the selectors
+ _.each(bindings, function (selector, key) {
+ _this._ui[key] = _this.$(selector);
+ });
+
+ this.ui = this._ui;
+ },
+ _unbindUIElements: function _unbindUIElements() {
+ var _this2 = this;
+
+ if (!this.ui || !this._uiBindings) {
+ return;
+ }
+
+ // delete all of the existing ui bindings
+ _.each(this.ui, function ($el, name) {
+ delete _this2.ui[name];
+ });
+
+ // reset the ui element to the original bindings configuration
+ this.ui = this._uiBindings;
+ delete this._uiBindings;
+ delete this._ui;
+ },
+ _getUI: function _getUI(name) {
+ return this._ui[name];
+ }
+ };
+
+ // MixinOptions
+ // - behaviors
+ // - childViewEventPrefix
+ // - childViewEvents
+ // - childViewTriggers
+ // - collectionEvents
+ // - modelEvents
+ // - triggers
+ // - ui
+
+
+ var ViewMixin = {
+ supportsRenderLifecycle: true,
+ supportsDestroyLifecycle: true,
+
+ _isDestroyed: false,
+
+ isDestroyed: function isDestroyed() {
+ return !!this._isDestroyed;
+ },
+
+
+ _isRendered: false,
+
+ isRendered: function isRendered() {
+ return !!this._isRendered;
+ },
+
+
+ _isAttached: false,
+
+ isAttached: function isAttached() {
+ return !!this._isAttached;
+ },
+
+
+ // Overriding Backbone.View's `delegateEvents` to handle
+ // `events` and `triggers`
+ delegateEvents: function delegateEvents(eventsArg) {
+
+ this._proxyBehaviorViewProperties();
+ this._buildEventProxies();
+
+ var viewEvents = this._getEvents(eventsArg);
+
+ if (typeof eventsArg === 'undefined') {
+ this.events = viewEvents;
+ }
+
+ var combinedEvents = _.extend({}, this._getBehaviorEvents(), viewEvents, this._getBehaviorTriggers(), this.getTriggers());
+
+ Backbone.View.prototype.delegateEvents.call(this, combinedEvents);
+
+ return this;
+ },
+ _getEvents: function _getEvents(eventsArg) {
+ var events = eventsArg || this.events;
+
+ if (_.isFunction(events)) {
+ return this.normalizeUIKeys(events.call(this));
+ }
+
+ return this.normalizeUIKeys(events);
+ },
+
+
+ // Configure `triggers` to forward DOM events to view
+ // events. `triggers: {"click .foo": "do:foo"}`
+ getTriggers: function getTriggers() {
+ if (!this.triggers) {
+ return;
+ }
+
+ // Allow `triggers` to be configured as a function
+ var triggers = this.normalizeUIKeys(_.result(this, 'triggers'));
+
+ // Configure the triggers, prevent default
+ // action and stop propagation of DOM events
+ return this._getViewTriggers(this, triggers);
+ },
+
+
+ // Handle `modelEvents`, and `collectionEvents` configuration
+ delegateEntityEvents: function delegateEntityEvents() {
+ this._delegateEntityEvents(this.model, this.collection);
+
+ // bind each behaviors model and collection events
+ this._delegateBehaviorEntityEvents();
+
+ return this;
+ },
+
+
+ // Handle unbinding `modelEvents`, and `collectionEvents` configuration
+ undelegateEntityEvents: function undelegateEntityEvents() {
+ this._undelegateEntityEvents(this.model, this.collection);
+
+ // unbind each behaviors model and collection events
+ this._undelegateBehaviorEntityEvents();
+
+ return this;
+ },
+
+
+ // Internal helper method to verify whether the view hasn't been destroyed
+ _ensureViewIsIntact: function _ensureViewIsIntact() {
+ if (this._isDestroyed) {
+ throw new MarionetteError({
+ name: 'ViewDestroyedError',
+ message: 'View (cid: "' + this.cid + '") has already been destroyed and cannot be used.'
+ });
+ }
+ },
+
+
+ // Handle destroying the view and its children.
+ destroy: function destroy() {
+ if (this._isDestroyed) {
+ return this;
+ }
+ var shouldTriggerDetach = !!this._isAttached;
+
+ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+
+ this.triggerMethod.apply(this, ['before:destroy', this].concat(args));
+ if (shouldTriggerDetach) {
+ this.triggerMethod('before:detach', this);
+ }
+
+ // unbind UI elements
+ this.unbindUIElements();
+
+ // remove the view from the DOM
+ // https://github.com/jashkenas/backbone/blob/1.2.3/backbone.js#L1235
+ this._removeElement();
+
+ if (shouldTriggerDetach) {
+ this._isAttached = false;
+ this.triggerMethod('detach', this);
+ }
+
+ // remove children after the remove to prevent extra paints
+ this._removeChildren();
+
+ this._destroyBehaviors(args);
+
+ this._isDestroyed = true;
+ this._isRendered = false;
+ this.triggerMethod.apply(this, ['destroy', this].concat(args));
+
+ this.stopListening();
+
+ return this;
+ },
+ bindUIElements: function bindUIElements() {
+ this._bindUIElements();
+ this._bindBehaviorUIElements();
+
+ return this;
+ },
+
+
+ // This method unbinds the elements specified in the "ui" hash
+ unbindUIElements: function unbindUIElements() {
+ this._unbindUIElements();
+ this._unbindBehaviorUIElements();
+
+ return this;
+ },
+ getUI: function getUI(name) {
+ this._ensureViewIsIntact();
+ return this._getUI(name);
+ },
+
+
+ // used as the prefix for child view events
+ // that are forwarded through the layoutview
+ childViewEventPrefix: 'childview',
+
+ // import the `triggerMethod` to trigger events with corresponding
+ // methods if the method exists
+ triggerMethod: function triggerMethod$$() {
+ var ret = triggerMethod.apply(this, arguments);
+
+ this._triggerEventOnBehaviors.apply(this, arguments);
+ this._triggerEventOnParentLayout.apply(this, arguments);
+
+ return ret;
+ },
+
+
+ // Cache `childViewEvents` and `childViewTriggers`
+ _buildEventProxies: function _buildEventProxies() {
+ this._childViewEvents = _.result(this, 'childViewEvents');
+ this._childViewTriggers = _.result(this, 'childViewTriggers');
+ },
+ _triggerEventOnParentLayout: function _triggerEventOnParentLayout() {
+ var layoutView = this._parentView();
+ if (!layoutView) {
+ return;
+ }
+
+ layoutView._childViewEventHandler.apply(layoutView, arguments);
+ },
+
+
+ // Walk the _parent tree until we find a view (if one exists).
+ // Returns the parent view hierarchically closest to this view.
+ _parentView: function _parentView() {
+ var parent = this._parent;
+
+ while (parent) {
+ if (parent instanceof View) {
+ return parent;
+ }
+ parent = parent._parent;
+ }
+ },
+ _childViewEventHandler: function _childViewEventHandler(eventName) {
+ var childViewEvents = this.normalizeMethods(this._childViewEvents);
+
+ // call collectionView childViewEvent if defined
+
+ for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+ args[_key2 - 1] = arguments[_key2];
+ }
+
+ if (typeof childViewEvents !== 'undefined' && _.isFunction(childViewEvents[eventName])) {
+ childViewEvents[eventName].apply(this, args);
+ }
+
+ // use the parent view's proxyEvent handlers
+ var childViewTriggers = this._childViewTriggers;
+
+ // Call the event with the proxy name on the parent layout
+ if (childViewTriggers && _.isString(childViewTriggers[eventName])) {
+ this.triggerMethod.apply(this, [childViewTriggers[eventName]].concat(args));
+ }
+
+ var prefix = _.result(this, 'childViewEventPrefix');
+
+ if (prefix !== false) {
+ var childEventName = prefix + ':' + eventName;
+
+ this.triggerMethod.apply(this, [childEventName].concat(args));
+ }
+ }
+ };
+
+ _.extend(ViewMixin, BehaviorsMixin, CommonMixin, DelegateEntityEventsMixin, TriggersMixin, UIMixin);
+
+ function destroyBackboneView(view) {
+ if (!view.supportsDestroyLifecycle) {
+ triggerMethodOn(view, 'before:destroy', view);
+ }
+
+ var shouldTriggerDetach = !!view._isAttached;
+
+ if (shouldTriggerDetach) {
+ triggerMethodOn(view, 'before:detach', view);
+ }
+
+ view.remove();
+
+ if (shouldTriggerDetach) {
+ view._isAttached = false;
+ triggerMethodOn(view, 'detach', view);
+ }
+
+ view._isDestroyed = true;
+
+ if (!view.supportsDestroyLifecycle) {
+ triggerMethodOn(view, 'destroy', view);
+ }
+ }
+
+ var ClassOptions$2 = ['allowMissingEl', 'parentEl', 'replaceElement'];
+
+ var Region = MarionetteObject.extend({
+ cidPrefix: 'mnr',
+ replaceElement: false,
+ _isReplaced: false,
+
+ constructor: function constructor(options) {
+ this._setOptions(options);
+
+ this.mergeOptions(options, ClassOptions$2);
+
+ // getOption necessary because options.el may be passed as undefined
+ this._initEl = this.el = this.getOption('el');
+
+ // Handle when this.el is passed in as a $ wrapped element.
+ this.el = this.el instanceof Backbone.$ ? this.el[0] : this.el;
+
+ if (!this.el) {
+ throw new MarionetteError({
+ name: 'NoElError',
+ message: 'An "el" must be specified for a region.'
+ });
+ }
+
+ this.$el = this.getEl(this.el);
+ MarionetteObject.call(this, options);
+ },
+
+
+ // Displays a backbone view instance inside of the region. Handles calling the `render`
+ // method for you. Reads content directly from the `el` attribute. The `preventDestroy`
+ // option can be used to prevent a view from the old view being destroyed on show.
+ show: function show(view, options) {
+ if (!this._ensureElement(options)) {
+ return;
+ }
+ this._ensureView(view);
+ if (view === this.currentView) {
+ return this;
+ }
+
+ this.triggerMethod('before:show', this, view, options);
+
+ monitorViewEvents(view);
+
+ this.empty(options);
+
+ // We need to listen for if a view is destroyed in a way other than through the region.
+ // If this happens we need to remove the reference to the currentView since once a view
+ // has been destroyed we can not reuse it.
+ view.on('destroy', this._empty, this);
+
+ // Make this region the view's parent.
+ // It's important that this parent binding happens before rendering so that any events
+ // the child may trigger during render can also be triggered on the child's ancestor views.
+ view._parent = this;
+
+ this._renderView(view);
+
+ this._attachView(view, options);
+
+ this.triggerMethod('show', this, view, options);
+ return this;
+ },
+ _renderView: function _renderView(view) {
+ if (view._isRendered) {
+ return;
+ }
+
+ if (!view.supportsRenderLifecycle) {
+ triggerMethodOn(view, 'before:render', view);
+ }
+
+ view.render();
+
+ if (!view.supportsRenderLifecycle) {
+ view._isRendered = true;
+ triggerMethodOn(view, 'render', view);
+ }
+ },
+ _attachView: function _attachView(view) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+ var shouldTriggerAttach = !view._isAttached && isNodeAttached(this.el);
+ var shouldReplaceEl = typeof options.replaceElement === 'undefined' ? !!_.result(this, 'replaceElement') : !!options.replaceElement;
+
+ if (shouldTriggerAttach) {
+ triggerMethodOn(view, 'before:attach', view);
+ }
+
+ if (shouldReplaceEl) {
+ this._replaceEl(view);
+ } else {
+ this.attachHtml(view);
+ }
+
+ if (shouldTriggerAttach) {
+ view._isAttached = true;
+ triggerMethodOn(view, 'attach', view);
+ }
+
+ this.currentView = view;
+ },
+ _ensureElement: function _ensureElement() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+
+ if (!_.isObject(this.el)) {
+ this.$el = this.getEl(this.el);
+ this.el = this.$el[0];
+ }
+
+ if (!this.$el || this.$el.length === 0) {
+ var allowMissingEl = typeof options.allowMissingEl === 'undefined' ? !!_.result(this, 'allowMissingEl') : !!options.allowMissingEl;
+
+ if (allowMissingEl) {
+ return false;
+ } else {
+ throw new MarionetteError('An "el" must exist in DOM for this region ' + this.cid);
+ }
+ }
+ return true;
+ },
+ _ensureView: function _ensureView(view) {
+ if (!view) {
+ throw new MarionetteError({
+ name: 'ViewNotValid',
+ message: 'The view passed is undefined and therefore invalid. You must pass a view instance to show.'
+ });
+ }
+
+ if (view._isDestroyed) {
+ throw new MarionetteError({
+ name: 'ViewDestroyedError',
+ message: 'View (cid: "' + view.cid + '") has already been destroyed and cannot be used.'
+ });
+ }
+ },
+
+
+ // Override this method to change how the region finds the DOM element that it manages. Return
+ // a jQuery selector object scoped to a provided parent el or the document if none exists.
+ getEl: function getEl(el) {
+ return Backbone.$(el, _.result(this, 'parentEl'));
+ },
+ _replaceEl: function _replaceEl(view) {
+ // always restore the el to ensure the regions el is present before replacing
+ this._restoreEl();
+
+ var parent = this.el.parentNode;
+
+ parent.replaceChild(view.el, this.el);
+ this._isReplaced = true;
+ },
+
+
+ // Restore the region's element in the DOM.
+ _restoreEl: function _restoreEl() {
+ // There is nothing to replace
+ if (!this._isReplaced) {
+ return;
+ }
+
+ var view = this.currentView;
+
+ if (!view) {
+ return;
+ }
+
+ var parent = view.el.parentNode;
+
+ if (!parent) {
+ return;
+ }
+
+ parent.replaceChild(this.el, view.el);
+ this._isReplaced = false;
+ },
+
+
+ // Check to see if the region's el was replaced.
+ isReplaced: function isReplaced() {
+ return !!this._isReplaced;
+ },
+
+
+ // Override this method to change how the new view is appended to the `$el` that the
+ // region is managing
+ attachHtml: function attachHtml(view) {
+ this.el.appendChild(view.el);
+ },
+
+
+ // Destroy the current view, if there is one. If there is no current view, it does
+ // nothing and returns immediately.
+ empty: function empty() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { allowMissingEl: true };
+
+ var view = this.currentView;
+
+ // If there is no view in the region we should only detach current html
+ if (!view) {
+ if (this._ensureElement(options)) {
+ this.detachHtml();
+ }
+ return this;
+ }
+
+ var shouldDestroy = !options.preventDestroy;
+
+ if (!shouldDestroy) {
+ deprecate('The preventDestroy option is deprecated. Use Region#detachView');
+ }
+
+ this._empty(view, shouldDestroy);
+ return this;
+ },
+ _empty: function _empty(view, shouldDestroy) {
+ view.off('destroy', this._empty, this);
+ this.triggerMethod('before:empty', this, view);
+
+ this._restoreEl();
+
+ delete this.currentView;
+
+ if (!view._isDestroyed) {
+ this._removeView(view, shouldDestroy);
+ delete view._parent;
+ }
+
+ this.triggerMethod('empty', this, view);
+ },
+ _removeView: function _removeView(view, shouldDestroy) {
+ if (!shouldDestroy) {
+ this._detachView(view);
+ return;
+ }
+
+ if (view.destroy) {
+ view.destroy();
+ } else {
+ destroyBackboneView(view);
+ }
+ },
+ detachView: function detachView() {
+ var view = this.currentView;
+
+ if (!view) {
+ return;
+ }
+
+ this._empty(view);
+
+ return view;
+ },
+ _detachView: function _detachView(view) {
+ var shouldTriggerDetach = !!view._isAttached;
+ if (shouldTriggerDetach) {
+ triggerMethodOn(view, 'before:detach', view);
+ }
+
+ this.detachHtml();
+
+ if (shouldTriggerDetach) {
+ view._isAttached = false;
+ triggerMethodOn(view, 'detach', view);
+ }
+ },
+
+
+ // Override this method to change how the region detaches current content
+ detachHtml: function detachHtml() {
+ this.$el.contents().detach();
+ },
+
+
+ // Checks whether a view is currently present within the region. Returns `true` if there is
+ // and `false` if no view is present.
+ hasView: function hasView() {
+ return !!this.currentView;
+ },
+
+
+ // Reset the region by destroying any existing view and clearing out the cached `$el`.
+ // The next time a view is shown via this region, the region will re-query the DOM for
+ // the region's `el`.
+ reset: function reset(options) {
+ this.empty(options);
+
+ if (this.$el) {
+ this.el = this._initEl;
+ }
+
+ delete this.$el;
+ return this;
+ },
+ destroy: function destroy(options) {
+ this.reset(options);
+ return MarionetteObject.prototype.destroy.apply(this, arguments);
+ }
+ });
+
+ // return the region instance from the definition
+ function buildRegion (definition, defaults) {
+ if (definition instanceof Region) {
+ return definition;
+ }
+
+ return buildRegionFromDefinition(definition, defaults);
+ }
+
+ function buildRegionFromDefinition(definition, defaults) {
+ var opts = _.extend({}, defaults);
+
+ if (_.isString(definition)) {
+ _.extend(opts, { el: definition });
+
+ return buildRegionFromObject(opts);
+ }
+
+ if (_.isFunction(definition)) {
+ _.extend(opts, { regionClass: definition });
+
+ return buildRegionFromObject(opts);
+ }
+
+ if (_.isObject(definition)) {
+ if (definition.selector) {
+ deprecate('The selector option on a Region definition object is deprecated. Use el to pass a selector string');
+ }
+
+ _.extend(opts, { el: definition.selector }, definition);
+
+ return buildRegionFromObject(opts);
+ }
+
+ throw new MarionetteError({
+ message: 'Improper region configuration type.',
+ url: 'marionette.region.html#region-configuration-types'
+ });
+ }
+
+ function buildRegionFromObject(definition) {
+ var RegionClass = definition.regionClass;
+
+ var options = _.omit(definition, 'regionClass');
+
+ return new RegionClass(options);
+ }
+
+ // MixinOptions
+ // - regions
+ // - regionClass
+
+ var RegionsMixin = {
+ regionClass: Region,
+
+ // Internal method to initialize the regions that have been defined in a
+ // `regions` attribute on this View.
+ _initRegions: function _initRegions() {
+
+ // init regions hash
+ this.regions = this.regions || {};
+ this._regions = {};
+
+ this.addRegions(_.result(this, 'regions'));
+ },
+
+
+ // Internal method to re-initialize all of the regions by updating
+ // the `el` that they point to
+ _reInitRegions: function _reInitRegions() {
+ _invoke(this._regions, 'reset');
+ },
+
+
+ // Add a single region, by name, to the View
+ addRegion: function addRegion(name, definition) {
+ var regions = {};
+ regions[name] = definition;
+ return this.addRegions(regions)[name];
+ },
+
+
+ // Add multiple regions as a {name: definition, name2: def2} object literal
+ addRegions: function addRegions(regions) {
+ // If there's nothing to add, stop here.
+ if (_.isEmpty(regions)) {
+ return;
+ }
+
+ // Normalize region selectors hash to allow
+ // a user to use the @ui. syntax.
+ regions = this.normalizeUIValues(regions, ['selector', 'el']);
+
+ // Add the regions definitions to the regions property
+ this.regions = _.extend({}, this.regions, regions);
+
+ return this._addRegions(regions);
+ },
+
+
+ // internal method to build and add regions
+ _addRegions: function _addRegions(regionDefinitions) {
+ var _this = this;
+
+ var defaults = {
+ regionClass: this.regionClass,
+ parentEl: _.partial(_.result, this, 'el')
+ };
+
+ return _.reduce(regionDefinitions, function (regions, definition, name) {
+ regions[name] = buildRegion(definition, defaults);
+ _this._addRegion(regions[name], name);
+ return regions;
+ }, {});
+ },
+ _addRegion: function _addRegion(region, name) {
+ this.triggerMethod('before:add:region', this, name, region);
+
+ region._parent = this;
+
+ this._regions[name] = region;
+
+ this.triggerMethod('add:region', this, name, region);
+ },
+
+
+ // Remove a single region from the View, by name
+ removeRegion: function removeRegion(name) {
+ var region = this._regions[name];
+
+ this._removeRegion(region, name);
+
+ return region;
+ },
+
+
+ // Remove all regions from the View
+ removeRegions: function removeRegions() {
+ var regions = this.getRegions();
+
+ _.each(this._regions, _.bind(this._removeRegion, this));
+
+ return regions;
+ },
+ _removeRegion: function _removeRegion(region, name) {
+ this.triggerMethod('before:remove:region', this, name, region);
+
+ region.destroy();
+
+ delete this.regions[name];
+ delete this._regions[name];
+
+ this.triggerMethod('remove:region', this, name, region);
+ },
+
+
+ // Empty all regions in the region manager, but
+ // leave them attached
+ emptyRegions: function emptyRegions() {
+ var regions = this.getRegions();
+ _invoke(regions, 'empty');
+ return regions;
+ },
+
+
+ // Checks to see if view contains region
+ // Accepts the region name
+ // hasRegion('main')
+ hasRegion: function hasRegion(name) {
+ return !!this.getRegion(name);
+ },
+
+
+ // Provides access to regions
+ // Accepts the region name
+ // getRegion('main')
+ getRegion: function getRegion(name) {
+ return this._regions[name];
+ },
+
+
+ // Get all regions
+ getRegions: function getRegions() {
+ return _.clone(this._regions);
+ },
+ showChildView: function showChildView(name, view) {
+ var region = this.getRegion(name);
+
+ for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
+ args[_key - 2] = arguments[_key];
+ }
+
+ return region.show.apply(region, [view].concat(args));
+ },
+ detachChildView: function detachChildView(name) {
+ return this.getRegion(name).detachView();
+ },
+ getChildView: function getChildView(name) {
+ return this.getRegion(name).currentView;
+ }
+ };
+
+ // Render a template with data by passing in the template
+ // selector and the data to render.
+ var Renderer = {
+
+ // Render a template with data. The `template` parameter is
+ // passed to the `TemplateCache` object to retrieve the
+ // template function. Override this method to provide your own
+ // custom rendering and template handling for all of Marionette.
+ render: function render(template, data) {
+ if (!template) {
+ throw new MarionetteError({
+ name: 'TemplateNotFoundError',
+ message: 'Cannot render the template since its false, null or undefined.'
+ });
+ }
+
+ var templateFunc = _.isFunction(template) ? template : TemplateCache.get(template);
+
+ return templateFunc(data);
+ }
+ };
+
+ var ClassOptions$1 = ['behaviors', 'childViewEventPrefix', 'childViewEvents', 'childViewTriggers', 'collectionEvents', 'events', 'modelEvents', 'regionClass', 'regions', 'template', 'templateContext', 'triggers', 'ui'];
+
+ // The standard view. Includes view events, automatic rendering
+ // of Underscore templates, nested views, and more.
+ var View = Backbone.View.extend({
+ constructor: function constructor(options) {
+ this.render = _.bind(this.render, this);
+
+ this._setOptions(options);
+
+ this.mergeOptions(options, ClassOptions$1);
+
+ monitorViewEvents(this);
+
+ this._initBehaviors();
+ this._initRegions();
+
+ var args = Array.prototype.slice.call(arguments);
+ args[0] = this.options;
+ Backbone.View.prototype.constructor.apply(this, args);
+
+ this.delegateEntityEvents();
+ },
+
+
+ // Serialize the view's model *or* collection, if
+ // it exists, for the template
+ serializeData: function serializeData() {
+ if (!this.model && !this.collection) {
+ return {};
+ }
+
+ // If we have a model, we serialize that
+ if (this.model) {
+ return this.serializeModel();
+ }
+
+ // Otherwise, we serialize the collection,
+ // making it available under the `items` property
+ return {
+ items: this.serializeCollection()
+ };
+ },
+
+
+ // Prepares the special `model` property of a view
+ // for being displayed in the template. By default
+ // we simply clone the attributes. Override this if
+ // you need a custom transformation for your view's model
+ serializeModel: function serializeModel() {
+ if (!this.model) {
+ return {};
+ }
+ return _.clone(this.model.attributes);
+ },
+
+
+ // Serialize a collection by cloning each of
+ // its model's attributes
+ serializeCollection: function serializeCollection() {
+ if (!this.collection) {
+ return {};
+ }
+ return this.collection.map(function (model) {
+ return _.clone(model.attributes);
+ });
+ },
+
+
+ // Overriding Backbone.View's `setElement` to handle
+ // if an el was previously defined. If so, the view might be
+ // rendered or attached on setElement.
+ setElement: function setElement() {
+ var hasEl = !!this.el;
+
+ Backbone.View.prototype.setElement.apply(this, arguments);
+
+ if (hasEl) {
+ this._isRendered = !!this.$el.length;
+ this._isAttached = isNodeAttached(this.el);
+ }
+
+ if (this._isRendered) {
+ this.bindUIElements();
+ }
+
+ return this;
+ },
+
+
+ // Render the view, defaulting to underscore.js templates.
+ // You can override this in your view definition to provide
+ // a very specific rendering for your view. In general, though,
+ // you should override the `Marionette.Renderer` object to
+ // change how Marionette renders views.
+ // Subsequent renders after the first will re-render all nested
+ // views.
+ render: function render() {
+ this._ensureViewIsIntact();
+
+ this.triggerMethod('before:render', this);
+
+ // If this is not the first render call, then we need to
+ // re-initialize the `el` for each region
+ if (this._isRendered) {
+ this._reInitRegions();
+ }
+
+ this._renderTemplate();
+ this.bindUIElements();
+
+ this._isRendered = true;
+ this.triggerMethod('render', this);
+
+ return this;
+ },
+
+
+ // Internal method to render the template with the serialized data
+ // and template context via the `Marionette.Renderer` object.
+ _renderTemplate: function _renderTemplate() {
+ var template = this.getTemplate();
+
+ // Allow template-less views
+ if (template === false) {
+ return;
+ }
+
+ // Add in entity data and template context
+ var data = this.mixinTemplateContext(this.serializeData());
+
+ // Render and add to el
+ var html = Renderer.render(template, data, this);
+ this.attachElContent(html);
+ },
+
+
+ // Get the template for this view
+ // instance. You can set a `template` attribute in the view
+ // definition or pass a `template: "whatever"` parameter in
+ // to the constructor options.
+ getTemplate: function getTemplate() {
+ return this.template;
+ },
+
+
+ // Mix in template context methods. Looks for a
+ // `templateContext` attribute, which can either be an
+ // object literal, or a function that returns an object
+ // literal. All methods and attributes from this object
+ // are copies to the object passed in.
+ mixinTemplateContext: function mixinTemplateContext() {
+ var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+
+ var templateContext = _.result(this, 'templateContext');
+ return _.extend(target, templateContext);
+ },
+
+
+ // Attaches the content of a given view.
+ // This method can be overridden to optimize rendering,
+ // or to render in a non standard way.
+ //
+ // For example, using `innerHTML` instead of `$el.html`
+ //
+ // ```js
+ // attachElContent(html) {
+ // this.el.innerHTML = html;
+ // return this;
+ // }
+ // ```
+ attachElContent: function attachElContent(html) {
+ this.$el.html(html);
+
+ return this;
+ },
+
+
+ // called by ViewMixin destroy
+ _removeChildren: function _removeChildren() {
+ this.removeRegions();
+ },
+ _getImmediateChildren: function _getImmediateChildren() {
+ return _.chain(this.getRegions()).map('currentView').compact().value();
+ }
+ });
+
+ _.extend(View.prototype, ViewMixin, RegionsMixin);
+
+ var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter', 'select', 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke', 'toArray', 'first', 'initial', 'rest', 'last', 'without', 'isEmpty', 'pluck', 'reduce'];
+
+ var emulateCollection = function emulateCollection(object, listProperty) {
+ _.each(methods, function (method) {
+ object[method] = function () {
+ var list = _.values(_.result(this, listProperty));
+ var args = [list].concat(_.toArray(arguments));
+ return _[method].apply(_, args);
+ };
+ });
+ };
+
+ // Provide a container to store, retrieve and
+ // shut down child views.
+ var Container = function Container(views) {
+ this._views = {};
+ this._indexByModel = {};
+ this._indexByCustom = {};
+ this._updateLength();
+
+ _.each(views, _.bind(this.add, this));
+ };
+
+ emulateCollection(Container.prototype, '_views');
+
+ // Container Methods
+ // -----------------
+
+ _.extend(Container.prototype, {
+
+ // Add a view to this container. Stores the view
+ // by `cid` and makes it searchable by the model
+ // cid (and model itself). Optionally specify
+ // a custom key to store an retrieve the view.
+ add: function add(view, customIndex) {
+ return this._add(view, customIndex)._updateLength();
+ },
+
+
+ // To be used when avoiding call _updateLength
+ // When you are done adding all your new views
+ // call _updateLength
+ _add: function _add(view, customIndex) {
+ var viewCid = view.cid;
+
+ // store the view
+ this._views[viewCid] = view;
+
+ // index it by model
+ if (view.model) {
+ this._indexByModel[view.model.cid] = viewCid;
+ }
+
+ // index by custom
+ if (customIndex) {
+ this._indexByCustom[customIndex] = viewCid;
+ }
+
+ return this;
+ },
+
+
+ // Find a view by the model that was attached to
+ // it. Uses the model's `cid` to find it.
+ findByModel: function findByModel(model) {
+ return this.findByModelCid(model.cid);
+ },
+
+
+ // Find a view by the `cid` of the model that was attached to
+ // it. Uses the model's `cid` to find the view `cid` and
+ // retrieve the view using it.
+ findByModelCid: function findByModelCid(modelCid) {
+ var viewCid = this._indexByModel[modelCid];
+ return this.findByCid(viewCid);
+ },
+
+
+ // Find a view by a custom indexer.
+ findByCustom: function findByCustom(index) {
+ var viewCid = this._indexByCustom[index];
+ return this.findByCid(viewCid);
+ },
+
+
+ // Find by index. This is not guaranteed to be a
+ // stable index.
+ findByIndex: function findByIndex(index) {
+ return _.values(this._views)[index];
+ },
+
+
+ // retrieve a view by its `cid` directly
+ findByCid: function findByCid(cid) {
+ return this._views[cid];
+ },
+
+
+ // Remove a view
+ remove: function remove(view) {
+ return this._remove(view)._updateLength();
+ },
+
+
+ // To be used when avoiding call _updateLength
+ // When you are done adding all your new views
+ // call _updateLength
+ _remove: function _remove(view) {
+ var viewCid = view.cid;
+
+ // delete model index
+ if (view.model) {
+ delete this._indexByModel[view.model.cid];
+ }
+
+ // delete custom index
+ _.some(this._indexByCustom, _.bind(function (cid, key) {
+ if (cid === viewCid) {
+ delete this._indexByCustom[key];
+ return true;
+ }
+ }, this));
+
+ // remove the view from the container
+ delete this._views[viewCid];
+
+ return this;
+ },
+
+
+ // Update the `.length` attribute on this container
+ _updateLength: function _updateLength() {
+ this.length = _.size(this._views);
+
+ return this;
+ }
+ });
+
+ var ClassOptions$3 = ['behaviors', 'childView', 'childViewEventPrefix', 'childViewEvents', 'childViewOptions', 'childViewTriggers', 'collectionEvents', 'events', 'filter', 'emptyView', 'emptyViewOptions', 'modelEvents', 'reorderOnSort', 'sort', 'triggers', 'ui', 'viewComparator'];
+
+ // A view that iterates over a Backbone.Collection
+ // and renders an individual child view for each model.
+ var CollectionView = Backbone.View.extend({
+
+ // flag for maintaining the sorted order of the collection
+ sort: true,
+
+ // constructor
+ // option to pass `{sort: false}` to prevent the `CollectionView` from
+ // maintaining the sorted order of the collection.
+ // This will fallback onto appending childView's to the end.
+ //
+ // option to pass `{viewComparator: compFunction()}` to allow the `CollectionView`
+ // to use a custom sort order for the collection.
+ constructor: function constructor(options) {
+ this.render = _.bind(this.render, this);
+
+ this._setOptions(options);
+
+ this.mergeOptions(options, ClassOptions$3);
+
+ monitorViewEvents(this);
+
+ this._initBehaviors();
+ this.once('render', this._initialEvents);
+ this._initChildViewStorage();
+ this._bufferedChildren = [];
+
+ var args = Array.prototype.slice.call(arguments);
+ args[0] = this.options;
+ Backbone.View.prototype.constructor.apply(this, args);
+
+ this.delegateEntityEvents();
+ },
+
+
+ // Instead of inserting elements one by one into the page, it's much more performant to insert
+ // elements into a document fragment and then insert that document fragment into the page
+ _startBuffering: function _startBuffering() {
+ this._isBuffering = true;
+ },
+ _endBuffering: function _endBuffering() {
+ var shouldTriggerAttach = !!this._isAttached;
+ var triggerOnChildren = shouldTriggerAttach ? this._getImmediateChildren() : [];
+
+ this._isBuffering = false;
+
+ _.each(triggerOnChildren, function (child) {
+ triggerMethodOn(child, 'before:attach', child);
+ });
+
+ this.attachBuffer(this, this._createBuffer());
+
+ _.each(triggerOnChildren, function (child) {
+ child._isAttached = true;
+ triggerMethodOn(child, 'attach', child);
+ });
+
+ this._bufferedChildren = [];
+ },
+ _getImmediateChildren: function _getImmediateChildren() {
+ return _.values(this.children._views);
+ },
+
+
+ // Configured the initial events that the collection view binds to.
+ _initialEvents: function _initialEvents() {
+ if (this.collection) {
+ this.listenTo(this.collection, 'add', this._onCollectionAdd);
+ this.listenTo(this.collection, 'update', this._onCollectionUpdate);
+ this.listenTo(this.collection, 'reset', this.render);
+
+ if (this.sort) {
+ this.listenTo(this.collection, 'sort', this._sortViews);
+ }
+ }
+ },
+
+
+ // Handle a child added to the collection
+ _onCollectionAdd: function _onCollectionAdd(child, collection, opts) {
+ // `index` is present when adding with `at` since BB 1.2; indexOf fallback for < 1.2
+ var index = opts.at !== undefined && (opts.index || collection.indexOf(child));
+
+ // When filtered or when there is no initial index, calculate index.
+ if (this.filter || index === false) {
+ index = _.indexOf(this._filteredSortedModels(index), child);
+ }
+
+ if (this._shouldAddChild(child, index)) {
+ this._destroyEmptyView();
+ this._addChild(child, index);
+ }
+ },
+
+
+ // Handle collection update model removals
+ _onCollectionUpdate: function _onCollectionUpdate(collection, options) {
+ var changes = options.changes;
+ this._removeChildModels(changes.removed);
+ },
+
+
+ // Remove the child views and destroy them.
+ // This function also updates the indices of later views
+ // in the collection in order to keep the children in sync with the collection.
+ // "models" is an array of models and the corresponding views
+ // will be removed and destroyed from the CollectionView
+ _removeChildModels: function _removeChildModels(models) {
+ var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+ var checkEmpty = _ref.checkEmpty;
+
+ var shouldCheckEmpty = checkEmpty !== false;
+
+ // Used to determine where to update the remaining
+ // sibling view indices after these views are removed.
+ var removedViews = this._getRemovedViews(models);
+
+ if (!removedViews.length) {
+ return;
+ }
+
+ this.children._updateLength();
+
+ // decrement the index of views after this one
+ this._updateIndices(removedViews, false);
+
+ if (shouldCheckEmpty) {
+ this._checkEmpty();
+ }
+ },
+
+
+ // Returns the views that will be used for re-indexing
+ // through CollectionView#_updateIndices.
+ _getRemovedViews: function _getRemovedViews(models) {
+ var _this = this;
+
+ // Returning a view means something was removed.
+ return _.reduce(models, function (removingViews, model) {
+ var view = _this.children.findByModel(model);
+
+ if (!view || view._isDestroyed) {
+ return removingViews;
+ }
+
+ _this._removeChildView(view);
+
+ removingViews.push(view);
+
+ return removingViews;
+ }, []);
+ },
+ _findGreatestIndexedView: function _findGreatestIndexedView(views) {
+
+ return _.reduce(views, function (greatestIndexedView, view) {
+ // Even if the index is `undefined`, a view will get returned.
+ if (!greatestIndexedView || greatestIndexedView._index < view._index) {
+ return view;
+ }
+
+ return greatestIndexedView;
+ }, undefined);
+ },
+ _removeChildView: function _removeChildView(view) {
+ this.triggerMethod('before:remove:child', this, view);
+
+ this.children._remove(view);
+ if (view.destroy) {
+ view.destroy();
+ } else {
+ destroyBackboneView(view);
+ }
+
+ delete view._parent;
+ this.stopListening(view);
+ this.triggerMethod('remove:child', this, view);
+ },
+
+
+ // Overriding Backbone.View's `setElement` to handle
+ // if an el was previously defined. If so, the view might be
+ // attached on setElement.
+ setElement: function setElement() {
+ var hasEl = !!this.el;
+
+ Backbone.View.prototype.setElement.apply(this, arguments);
+
+ if (hasEl) {
+ this._isAttached = isNodeAttached(this.el);
+ }
+
+ return this;
+ },
+
+
+ // Render children views. Override this method to provide your own implementation of a
+ // render function for the collection view.
+ render: function render() {
+ this._ensureViewIsIntact();
+ this.triggerMethod('before:render', this);
+ this._renderChildren();
+ this._isRendered = true;
+ this.triggerMethod('render', this);
+ return this;
+ },
+
+
+ // An efficient rendering used for filtering. Instead of modifying the whole DOM for the
+ // collection view, we are only adding or removing the related childrenViews.
+ setFilter: function setFilter(filter) {
+ var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+ var preventRender = _ref2.preventRender;
+
+ var canBeRendered = this._isRendered && !this._isDestroyed;
+ var filterChanged = this.filter !== filter;
+ var shouldRender = canBeRendered && filterChanged && !preventRender;
+
+ if (shouldRender) {
+ var previousModels = this._filteredSortedModels();
+ this.filter = filter;
+ var models = this._filteredSortedModels();
+ this._applyModelDeltas(models, previousModels);
+ } else {
+ this.filter = filter;
+ }
+
+ return this;
+ },
+
+
+ // `removeFilter` is actually an alias for removing filters.
+ removeFilter: function removeFilter(options) {
+ return this.setFilter(null, options);
+ },
+
+
+ // Calculate and apply difference by cid between `models` and `previousModels`.
+ _applyModelDeltas: function _applyModelDeltas(models, previousModels) {
+ var _this2 = this;
+
+ var currentIds = {};
+ _.each(models, function (model, index) {
+ var addedChildNotExists = !_this2.children.findByModel(model);
+ if (addedChildNotExists) {
+ _this2._onCollectionAdd(model, _this2.collection, { at: index });
+ }
+ currentIds[model.cid] = true;
+ });
+
+ var removeModels = _.filter(previousModels, function (prevModel) {
+ return !currentIds[prevModel.cid] && _this2.children.findByModel(prevModel);
+ });
+
+ this._removeChildModels(removeModels);
+ },
+
+
+ // Reorder DOM after sorting. When your element's rendering do not use their index,
+ // you can pass reorderOnSort: true to only reorder the DOM after a sort instead of
+ // rendering all the collectionView.
+ reorder: function reorder() {
+ var _this3 = this;
+
+ var children = this.children;
+ var models = this._filteredSortedModels();
+
+ if (!models.length && this._showingEmptyView) {
+ return this;
+ }
+
+ var anyModelsAdded = _.some(models, function (model) {
+ return !children.findByModel(model);
+ });
+
+ // If there are any new models added due to filtering we need to add child views,
+ // so render as normal.
+ if (anyModelsAdded) {
+ this.render();
+ } else {
+ (function () {
+
+ var filteredOutModels = [];
+
+ // Get the DOM nodes in the same order as the models and
+ // find the model that were children before but aren't in this new order.
+ var elsToReorder = children.reduce(function (viewEls, view) {
+ var index = _.indexOf(models, view.model);
+
+ if (index === -1) {
+ filteredOutModels.push(view.model);
+ return viewEls;
+ }
+
+ view._index = index;
+
+ viewEls[index] = view.el;
+
+ return viewEls;
+ }, new Array(models.length));
+
+ _this3.triggerMethod('before:reorder', _this3);
+
+ // Since append moves elements that are already in the DOM, appending the elements
+ // will effectively reorder them.
+ _this3._appendReorderedChildren(elsToReorder);
+
+ // remove any views that have been filtered out
+ _this3._removeChildModels(filteredOutModels);
+
+ _this3.triggerMethod('reorder', _this3);
+ })();
+ }
+ return this;
+ },
+
+
+ // Render view after sorting. Override this method to change how the view renders
+ // after a `sort` on the collection.
+ resortView: function resortView() {
+ if (this.reorderOnSort) {
+ this.reorder();
+ } else {
+ this._renderChildren();
+ }
+ return this;
+ },
+
+
+ // Internal method. This checks for any changes in the order of the collection.
+ // If the index of any view doesn't match, it will render.
+ _sortViews: function _sortViews() {
+ var _this4 = this;
+
+ var models = this._filteredSortedModels();
+
+ // check for any changes in sort order of views
+ var orderChanged = _.find(models, function (item, index) {
+ var view = _this4.children.findByModel(item);
+ return !view || view._index !== index;
+ });
+
+ if (orderChanged) {
+ this.resortView();
+ }
+ },
+
+
+ // Internal reference to what index a `emptyView` is.
+ _emptyViewIndex: -1,
+
+ // Internal method. Separated so that CompositeView can append to the childViewContainer
+ // if necessary
+ _appendReorderedChildren: function _appendReorderedChildren(children) {
+ this.$el.append(children);
+ },
+
+
+ // Internal method. Separated so that CompositeView can have more control over events
+ // being triggered, around the rendering process
+ _renderChildren: function _renderChildren() {
+ if (this._isRendered) {
+ this._destroyEmptyView();
+ this._destroyChildren({ checkEmpty: false });
+ }
+
+ var models = this._filteredSortedModels();
+ if (this.isEmpty({ processedModels: models })) {
+ this._showEmptyView();
+ } else {
+ this.triggerMethod('before:render:children', this);
+ this._startBuffering();
+ this._showCollection(models);
+ this._endBuffering();
+ this.triggerMethod('render:children', this);
+ }
+ },
+ _createView: function _createView(model, index) {
+ var ChildView = this._getChildView(model);
+ var childViewOptions = this._getChildViewOptions(model, index);
+ var view = this.buildChildView(model, ChildView, childViewOptions);
+ return view;
+ },
+ _setupChildView: function _setupChildView(view, index) {
+ view._parent = this;
+
+ monitorViewEvents(view);
+
+ // set up the child view event forwarding
+ this._proxyChildEvents(view);
+
+ if (this.sort) {
+ view._index = index;
+ }
+ },
+
+
+ // Internal method to loop through collection and show each child view.
+ _showCollection: function _showCollection(models) {
+ _.each(models, _.bind(this._addChild, this));
+ this.children._updateLength();
+ },
+
+
+ // Allow the collection to be sorted by a custom view comparator
+ _filteredSortedModels: function _filteredSortedModels(addedAt) {
+ if (!this.collection || !this.collection.length) {
+ return [];
+ }
+
+ var viewComparator = this.getViewComparator();
+ var models = this.collection.models;
+ addedAt = Math.min(Math.max(addedAt, 0), models.length - 1);
+
+ if (viewComparator) {
+ var addedModel = void 0;
+ // Preserve `at` location, even for a sorted view
+ if (addedAt) {
+ addedModel = models[addedAt];
+ models = models.slice(0, addedAt).concat(models.slice(addedAt + 1));
+ }
+ models = this._sortModelsBy(models, viewComparator);
+ if (addedModel) {
+ models.splice(addedAt, 0, addedModel);
+ }
+ }
+
+ // Filter after sorting in case the filter uses the index
+ models = this._filterModels(models);
+
+ return models;
+ },
+ getViewComparator: function getViewComparator() {
+ return this.viewComparator;
+ },
+
+
+ // Filter an array of models, if a filter exists
+ _filterModels: function _filterModels(models) {
+ var _this5 = this;
+
+ if (this.filter) {
+ models = _.filter(models, function (model, index) {
+ return _this5._shouldAddChild(model, index);
+ });
+ }
+ return models;
+ },
+ _sortModelsBy: function _sortModelsBy(models, comparator) {
+ if (typeof comparator === 'string') {
+ return _.sortBy(models, function (model) {
+ return model.get(comparator);
+ });
+ } else if (comparator.length === 1) {
+ return _.sortBy(models, _.bind(comparator, this));
+ } else {
+ return models.sort(_.bind(comparator, this));
+ }
+ },
+
+
+ // Internal method to show an empty view in place of a collection of child views,
+ // when the collection is empty
+ _showEmptyView: function _showEmptyView() {
+ var EmptyView = this._getEmptyView();
+
+ if (EmptyView && !this._showingEmptyView) {
+ this._showingEmptyView = true;
+
+ var model = new Backbone.Model();
+ var emptyViewOptions = this.emptyViewOptions || this.childViewOptions;
+ if (_.isFunction(emptyViewOptions)) {
+ emptyViewOptions = emptyViewOptions.call(this, model, this._emptyViewIndex);
+ }
+
+ var view = this.buildChildView(model, EmptyView, emptyViewOptions);
+
+ this.triggerMethod('before:render:empty', this, view);
+ this.addChildView(view, 0);
+ this.triggerMethod('render:empty', this, view);
+ }
+ },
+
+
+ // Internal method to destroy an existing emptyView instance if one exists. Called when
+ // a collection view has been rendered empty, and then a child is added to the collection.
+ _destroyEmptyView: function _destroyEmptyView() {
+ if (this._showingEmptyView) {
+ this.triggerMethod('before:remove:empty', this);
+
+ this._destroyChildren();
+ delete this._showingEmptyView;
+
+ this.triggerMethod('remove:empty', this);
+ }
+ },
+
+
+ // Retrieve the empty view class
+ _getEmptyView: function _getEmptyView() {
+ var emptyView = this.emptyView;
+
+ if (!emptyView) {
+ return;
+ }
+
+ return this._getView(emptyView);
+ },
+
+
+ // Retrieve the `childView` class
+ // The `childView` property can be either a view class or a function that
+ // returns a view class. If it is a function, it will receive the model that
+ // will be passed to the view instance (created from the returned view class)
+ _getChildView: function _getChildView(child) {
+ var childView = this.childView;
+
+ if (!childView) {
+ throw new MarionetteError({
+ name: 'NoChildViewError',
+ message: 'A "childView" must be specified'
+ });
+ }
+
+ childView = this._getView(childView, child);
+
+ if (!childView) {
+ throw new MarionetteError({
+ name: 'InvalidChildViewError',
+ message: '"childView" must be a view class or a function that returns a view class'
+ });
+ }
+
+ return childView;
+ },
+
+
+ // First check if the `view` is a view class (the common case)
+ // Then check if it's a function (which we assume that returns a view class)
+ _getView: function _getView(view, child) {
+ if (view.prototype instanceof Backbone.View || view === Backbone.View) {
+ return view;
+ } else if (_.isFunction(view)) {
+ return view.call(this, child);
+ }
+ },
+
+
+ // Internal method for building and adding a child view
+ _addChild: function _addChild(child, index) {
+ var view = this._createView(child, index);
+ this.addChildView(view, index);
+
+ return view;
+ },
+ _getChildViewOptions: function _getChildViewOptions(child, index) {
+ if (_.isFunction(this.childViewOptions)) {
+ return this.childViewOptions(child, index);
+ }
+
+ return this.childViewOptions;
+ },
+
+
+ // Render the child's view and add it to the HTML for the collection view at a given index.
+ // This will also update the indices of later views in the collection in order to keep the
+ // children in sync with the collection.
+ addChildView: function addChildView(view, index) {
+ this.triggerMethod('before:add:child', this, view);
+ this._setupChildView(view, index);
+
+ // Store the child view itself so we can properly remove and/or destroy it later
+ if (this._isBuffering) {
+ // Add to children, but don't update children's length.
+ this.children._add(view);
+ } else {
+ // increment indices of views after this one
+ this._updateIndices(view, true);
+ this.children.add(view);
+ }
+
+ this._renderView(view);
+
+ this._attachView(view, index);
+
+ this.triggerMethod('add:child', this, view);
+
+ return view;
+ },
+
+
+ // Internal method. This decrements or increments the indices of views after the added/removed
+ // view to keep in sync with the collection.
+ _updateIndices: function _updateIndices(views, increment) {
+ if (!this.sort) {
+ return;
+ }
+
+ var view = _.isArray(views) ? this._findGreatestIndexedView(views) : views;
+
+ // update the indexes of views after this one
+ this.children.each(function (laterView) {
+ if (laterView._index >= view._index) {
+ laterView._index += increment ? 1 : -1;
+ }
+ });
+ },
+ _renderView: function _renderView(view) {
+ if (view._isRendered) {
+ return;
+ }
+
+ if (!view.supportsRenderLifecycle) {
+ triggerMethodOn(view, 'before:render', view);
+ }
+
+ view.render();
+
+ if (!view.supportsRenderLifecycle) {
+ view._isRendered = true;
+ triggerMethodOn(view, 'render', view);
+ }
+ },
+ _attachView: function _attachView(view, index) {
+ // Only trigger attach if already attached and not buffering,
+ // otherwise _endBuffering() or Region#show() handles this.
+ var shouldTriggerAttach = !view._isAttached && !this._isBuffering && this._isAttached;
+
+ if (shouldTriggerAttach) {
+ triggerMethodOn(view, 'before:attach', view);
+ }
+
+ this.attachHtml(this, view, index);
+
+ if (shouldTriggerAttach) {
+ view._isAttached = true;
+ triggerMethodOn(view, 'attach', view);
+ }
+ },
+
+
+ // Build a `childView` for a model in the collection.
+ buildChildView: function buildChildView(child, ChildViewClass, childViewOptions) {
+ var options = _.extend({ model: child }, childViewOptions);
+ return new ChildViewClass(options);
+ },
+
+
+ // Remove the child view and destroy it. This function also updates the indices of later views
+ // in the collection in order to keep the children in sync with the collection.
+ removeChildView: function removeChildView(view) {
+ if (!view || view._isDestroyed) {
+ return view;
+ }
+
+ this._removeChildView(view);
+ this.children._updateLength();
+ // decrement the index of views after this one
+ this._updateIndices(view, false);
+ return view;
+ },
+
+
+ // check if the collection is empty or optionally whether an array of pre-processed models is empty
+ isEmpty: function isEmpty(options) {
+ var models = void 0;
+ if (_.result(options, 'processedModels')) {
+ models = options.processedModels;
+ } else {
+ models = this.collection ? this.collection.models : [];
+ models = this._filterModels(models);
+ }
+ return models.length === 0;
+ },
+
+
+ // If empty, show the empty view
+ _checkEmpty: function _checkEmpty() {
+ if (this.isEmpty()) {
+ this._showEmptyView();
+ }
+ },
+
+
+ // You might need to override this if you've overridden attachHtml
+ attachBuffer: function attachBuffer(collectionView, buffer) {
+ collectionView.$el.append(buffer);
+ },
+
+
+ // Create a fragment buffer from the currently buffered children
+ _createBuffer: function _createBuffer() {
+ var elBuffer = document.createDocumentFragment();
+ _.each(this._bufferedChildren, function (b) {
+ elBuffer.appendChild(b.el);
+ });
+ return elBuffer;
+ },
+
+
+ // Append the HTML to the collection's `el`. Override this method to do something other
+ // than `.append`.
+ attachHtml: function attachHtml(collectionView, childView, index) {
+ if (collectionView._isBuffering) {
+ // buffering happens on reset events and initial renders
+ // in order to reduce the number of inserts into the
+ // document, which are expensive.
+ collectionView._bufferedChildren.splice(index, 0, childView);
+ } else {
+ // If we've already rendered the main collection, append
+ // the new child into the correct order if we need to. Otherwise
+ // append to the end.
+ if (!collectionView._insertBefore(childView, index)) {
+ collectionView._insertAfter(childView);
+ }
+ }
+ },
+
+
+ // Internal method. Check whether we need to insert the view into the correct position.
+ _insertBefore: function _insertBefore(childView, index) {
+ var currentView = void 0;
+ var findPosition = this.sort && index < this.children.length - 1;
+ if (findPosition) {
+ // Find the view after this one
+ currentView = this.children.find(function (view) {
+ return view._index === index + 1;
+ });
+ }
+
+ if (currentView) {
+ currentView.$el.before(childView.el);
+ return true;
+ }
+
+ return false;
+ },
+
+
+ // Internal method. Append a view to the end of the $el
+ _insertAfter: function _insertAfter(childView) {
+ this.$el.append(childView.el);
+ },
+
+
+ // Internal method to set up the `children` object for storing all of the child views
+ _initChildViewStorage: function _initChildViewStorage() {
+ this.children = new Container();
+ },
+
+
+ // called by ViewMixin destroy
+ _removeChildren: function _removeChildren() {
+ this._destroyChildren({ checkEmpty: false });
+ },
+
+
+ // Destroy the child views that this collection view is holding on to, if any
+ _destroyChildren: function _destroyChildren(options) {
+ if (!this.children.length) {
+ return;
+ }
+
+ this.triggerMethod('before:destroy:children', this);
+ var childModels = this.children.map('model');
+ this._removeChildModels(childModels, options);
+ this.triggerMethod('destroy:children', this);
+ },
+
+
+ // Return true if the given child should be shown. Return false otherwise.
+ // The filter will be passed (child, index, collection), where
+ // 'child' is the given model
+ // 'index' is the index of that model in the collection
+ // 'collection' is the collection referenced by this CollectionView
+ _shouldAddChild: function _shouldAddChild(child, index) {
+ var filter = this.filter;
+ return !_.isFunction(filter) || filter.call(this, child, index, this.collection);
+ },
+
+
+ // Set up the child view event forwarding. Uses a "childview:" prefix in front of all forwarded events.
+ _proxyChildEvents: function _proxyChildEvents(view) {
+ this.listenTo(view, 'all', this._childViewEventHandler);
+ }
+ });
+
+ _.extend(CollectionView.prototype, ViewMixin);
+
+ var ClassOptions$4 = ['childViewContainer', 'template', 'templateContext'];
+
+ // Used for rendering a branch-leaf, hierarchical structure.
+ // Extends directly from CollectionView
+ // @deprecated
+ var CompositeView = CollectionView.extend({
+
+ // Setting up the inheritance chain which allows changes to
+ // Marionette.CollectionView.prototype.constructor which allows overriding
+ // option to pass '{sort: false}' to prevent the CompositeView from
+ // maintaining the sorted order of the collection.
+ // This will fallback onto appending childView's to the end.
+ constructor: function constructor(options) {
+ deprecate('CompositeView is deprecated. Convert to View at your earliest convenience');
+
+ this.mergeOptions(options, ClassOptions$4);
+
+ CollectionView.prototype.constructor.apply(this, arguments);
+ },
+
+
+ // Configured the initial events that the composite view
+ // binds to. Override this method to prevent the initial
+ // events, or to add your own initial events.
+ _initialEvents: function _initialEvents() {
+
+ // Bind only after composite view is rendered to avoid adding child views
+ // to nonexistent childViewContainer
+
+ if (this.collection) {
+ this.listenTo(this.collection, 'add', this._onCollectionAdd);
+ this.listenTo(this.collection, 'update', this._onCollectionUpdate);
+ this.listenTo(this.collection, 'reset', this.renderChildren);
+
+ if (this.sort) {
+ this.listenTo(this.collection, 'sort', this._sortViews);
+ }
+ }
+ },
+
+
+ // Retrieve the `childView` to be used when rendering each of
+ // the items in the collection. The default is to return
+ // `this.childView` or Marionette.CompositeView if no `childView`
+ // has been defined. As happens in CollectionView, `childView` can
+ // be a function (which should return a view class).
+ _getChildView: function _getChildView(child) {
+ var childView = this.childView;
+
+ // for CompositeView, if `childView` is not specified, we'll get the same
+ // composite view class rendered for each child in the collection
+ // then check if the `childView` is a view class (the common case)
+ // finally check if it's a function (which we assume that returns a view class)
+ if (!childView) {
+ return this.constructor;
+ }
+
+ childView = this._getView(childView, child);
+
+ if (!childView) {
+ throw new MarionetteError({
+ name: 'InvalidChildViewError',
+ message: '"childView" must be a view class or a function that returns a view class'
+ });
+ }
+
+ return childView;
+ },
+
+
+ // Return the serialized model
+ serializeData: function serializeData() {
+ return this.serializeModel();
+ },
+
+
+ // Renders the model and the collection.
+ render: function render() {
+ this._ensureViewIsIntact();
+ this._isRendering = true;
+ this.resetChildViewContainer();
+
+ this.triggerMethod('before:render', this);
+
+ this._renderTemplate();
+ this.bindUIElements();
+ this.renderChildren();
+
+ this._isRendering = false;
+ this._isRendered = true;
+ this.triggerMethod('render', this);
+ return this;
+ },
+ renderChildren: function renderChildren() {
+ if (this._isRendered || this._isRendering) {
+ CollectionView.prototype._renderChildren.call(this);
+ }
+ },
+
+
+ // You might need to override this if you've overridden attachHtml
+ attachBuffer: function attachBuffer(compositeView, buffer) {
+ var $container = this.getChildViewContainer(compositeView);
+ $container.append(buffer);
+ },
+
+
+ // Internal method. Append a view to the end of the $el.
+ // Overidden from CollectionView to ensure view is appended to
+ // childViewContainer
+ _insertAfter: function _insertAfter(childView) {
+ var $container = this.getChildViewContainer(this, childView);
+ $container.append(childView.el);
+ },
+
+
+ // Internal method. Append reordered childView'.
+ // Overidden from CollectionView to ensure reordered views
+ // are appended to childViewContainer
+ _appendReorderedChildren: function _appendReorderedChildren(children) {
+ var $container = this.getChildViewContainer(this);
+ $container.append(children);
+ },
+
+
+ // Internal method to ensure an `$childViewContainer` exists, for the
+ // `attachHtml` method to use.
+ getChildViewContainer: function getChildViewContainer(containerView, childView) {
+ if (!!containerView.$childViewContainer) {
+ return containerView.$childViewContainer;
+ }
+
+ var container = void 0;
+ var childViewContainer = containerView.childViewContainer;
+ if (childViewContainer) {
+
+ var selector = _.result(containerView, 'childViewContainer');
+
+ if (selector.charAt(0) === '@' && containerView.ui) {
+ container = containerView.ui[selector.substr(4)];
+ } else {
+ container = containerView.$(selector);
+ }
+
+ if (container.length <= 0) {
+ throw new MarionetteError({
+ name: 'ChildViewContainerMissingError',
+ message: 'The specified "childViewContainer" was not found: ' + containerView.childViewContainer
+ });
+ }
+ } else {
+ container = containerView.$el;
+ }
+
+ containerView.$childViewContainer = container;
+ return container;
+ },
+
+
+ // Internal method to reset the `$childViewContainer` on render
+ resetChildViewContainer: function resetChildViewContainer() {
+ if (this.$childViewContainer) {
+ this.$childViewContainer = undefined;
+ }
+ }
+ });
+
+ // To prevent duplication but allow the best View organization
+ // Certain View methods are mixed directly into the deprecated CompositeView
+ var MixinFromView = _.pick(View.prototype, 'serializeModel', 'getTemplate', '_renderTemplate', 'mixinTemplateContext', 'attachElContent');
+ _.extend(CompositeView.prototype, MixinFromView);
+
+ var ClassOptions$5 = ['collectionEvents', 'events', 'modelEvents', 'triggers', 'ui'];
+
+ var Behavior = MarionetteObject.extend({
+ cidPrefix: 'mnb',
+
+ constructor: function constructor(options, view) {
+ // Setup reference to the view.
+ // this comes in handle when a behavior
+ // wants to directly talk up the chain
+ // to the view.
+ this.view = view;
+ this.defaults = _.clone(_.result(this, 'defaults', {}));
+ this._setOptions(this.defaults, options);
+ this.mergeOptions(this.options, ClassOptions$5);
+
+ // Construct an internal UI hash using
+ // the behaviors UI hash and then the view UI hash.
+ // This allows the user to use UI hash elements
+ // defined in the parent view as well as those
+ // defined in the given behavior.
+ // This order will help the reuse and share of a behavior
+ // between multiple views, while letting a view override a
+ // selector under an UI key.
+ this.ui = _.extend({}, _.result(this, 'ui'), _.result(view, 'ui'));
+
+ MarionetteObject.apply(this, arguments);
+ },
+
+
+ // proxy behavior $ method to the view
+ // this is useful for doing jquery DOM lookups
+ // scoped to behaviors view.
+ $: function $() {
+ return this.view.$.apply(this.view, arguments);
+ },
+
+
+ // Stops the behavior from listening to events.
+ // Overrides Object#destroy to prevent additional events from being triggered.
+ destroy: function destroy() {
+ this.stopListening();
+
+ return this;
+ },
+ proxyViewProperties: function proxyViewProperties() {
+ this.$el = this.view.$el;
+ this.el = this.view.el;
+
+ return this;
+ },
+ bindUIElements: function bindUIElements() {
+ this._bindUIElements();
+
+ return this;
+ },
+ unbindUIElements: function unbindUIElements() {
+ this._unbindUIElements();
+
+ return this;
+ },
+ getUI: function getUI(name) {
+ this.view._ensureViewIsIntact();
+ return this._getUI(name);
+ },
+
+
+ // Handle `modelEvents`, and `collectionEvents` configuration
+ delegateEntityEvents: function delegateEntityEvents() {
+ this._delegateEntityEvents(this.view.model, this.view.collection);
+
+ return this;
+ },
+ undelegateEntityEvents: function undelegateEntityEvents() {
+ this._undelegateEntityEvents(this.view.model, this.view.collection);
+
+ return this;
+ },
+ getEvents: function getEvents() {
+ var _this = this;
+
+ // Normalize behavior events hash to allow
+ // a user to use the @ui. syntax.
+ var behaviorEvents = this.normalizeUIKeys(_.result(this, 'events'));
+
+ // binds the handler to the behavior and builds a unique eventName
+ return _.reduce(behaviorEvents, function (events, behaviorHandler, key) {
+ if (!_.isFunction(behaviorHandler)) {
+ behaviorHandler = _this[behaviorHandler];
+ }
+ if (!behaviorHandler) {
+ return;
+ }
+ key = getUniqueEventName(key);
+ events[key] = _.bind(behaviorHandler, _this);
+ return events;
+ }, {});
+ },
+
+
+ // Internal method to build all trigger handlers for a given behavior
+ getTriggers: function getTriggers() {
+ if (!this.triggers) {
+ return;
+ }
+
+ // Normalize behavior triggers hash to allow
+ // a user to use the @ui. syntax.
+ var behaviorTriggers = this.normalizeUIKeys(_.result(this, 'triggers'));
+
+ return this._getViewTriggers(this.view, behaviorTriggers);
+ }
+ });
+
+ _.extend(Behavior.prototype, DelegateEntityEventsMixin, TriggersMixin, UIMixin);
+
+ var ClassOptions$6 = ['region', 'regionClass'];
+
+ // A container for a Marionette application.
+ var Application = MarionetteObject.extend({
+ cidPrefix: 'mna',
+
+ constructor: function constructor(options) {
+ this._setOptions(options);
+
+ this.mergeOptions(options, ClassOptions$6);
+
+ this._initRegion();
+
+ MarionetteObject.prototype.constructor.apply(this, arguments);
+ },
+
+
+ regionClass: Region,
+
+ _initRegion: function _initRegion() {
+ var region = this.region;
+
+ if (!region) {
+ return;
+ }
+
+ var defaults = {
+ regionClass: this.regionClass
+ };
+
+ this._region = buildRegion(region, defaults);
+ },
+ getRegion: function getRegion() {
+ return this._region;
+ },
+ showView: function showView(view) {
+ var region = this.getRegion();
+
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ return region.show.apply(region, [view].concat(args));
+ },
+ getView: function getView() {
+ return this.getRegion().currentView;
+ },
+
+
+ // kick off all of the application's processes.
+ start: function start(options) {
+ this.triggerMethod('before:start', this, options);
+ this.triggerMethod('start', this, options);
+ return this;
+ }
+ });
+
+ var ClassOptions$7 = ['appRoutes', 'controller'];
+
+ var AppRouter = Backbone.Router.extend({
+ constructor: function constructor(options) {
+ this._setOptions(options);
+
+ this.mergeOptions(options, ClassOptions$7);
+
+ Backbone.Router.apply(this, arguments);
+
+ var appRoutes = this.appRoutes;
+ var controller = this._getController();
+ this.processAppRoutes(controller, appRoutes);
+ this.on('route', this._processOnRoute, this);
+ },
+
+
+ // Similar to route method on a Backbone Router but
+ // method is called on the controller
+ appRoute: function appRoute(route, methodName) {
+ var controller = this._getController();
+ this._addAppRoute(controller, route, methodName);
+ return this;
+ },
+
+
+ // process the route event and trigger the onRoute
+ // method call, if it exists
+ _processOnRoute: function _processOnRoute(routeName, routeArgs) {
+ // make sure an onRoute before trying to call it
+ if (_.isFunction(this.onRoute)) {
+ // find the path that matches the current route
+ var routePath = _.invert(this.appRoutes)[routeName];
+ this.onRoute(routeName, routePath, routeArgs);
+ }
+ },
+
+
+ // Internal method to process the `appRoutes` for the
+ // router, and turn them in to routes that trigger the
+ // specified method on the specified `controller`.
+ processAppRoutes: function processAppRoutes(controller, appRoutes) {
+ var _this = this;
+
+ if (!appRoutes) {
+ return this;
+ }
+
+ var routeNames = _.keys(appRoutes).reverse(); // Backbone requires reverted order of routes
+
+ _.each(routeNames, function (route) {
+ _this._addAppRoute(controller, route, appRoutes[route]);
+ });
+
+ return this;
+ },
+ _getController: function _getController() {
+ return this.controller;
+ },
+ _addAppRoute: function _addAppRoute(controller, route, methodName) {
+ var method = controller[methodName];
+
+ if (!method) {
+ throw new MarionetteError('Method "' + methodName + '" was not found on the controller');
+ }
+
+ this.route(route, methodName, _.bind(method, controller));
+ },
+
+
+ triggerMethod: triggerMethod
+ });
+
+ _.extend(AppRouter.prototype, CommonMixin);
+
+ // Placeholder method to be extended by the user.
+ // The method should define the object that stores the behaviors.
+ // i.e.
+ //
+ // ```js
+ // Marionette.Behaviors.behaviorsLookup: function() {
+ // return App.Behaviors
+ // }
+ // ```
+ function behaviorsLookup() {
+ throw new MarionetteError({
+ message: 'You must define where your behaviors are stored.',
+ url: 'marionette.behaviors.md#behaviorslookup'
+ });
+ }
+
+ // Add Feature flags here
+ // e.g. 'class' => false
+ var FEATURES = {};
+
+ function isEnabled(name) {
+ return !!FEATURES[name];
+ }
+
+ function setEnabled(name, state) {
+ return FEATURES[name] = state;
+ }
+
+ var previousMarionette = Backbone.Marionette;
+ var Marionette = Backbone.Marionette = {};
+
+ // This allows you to run multiple instances of Marionette on the same
+ // webapp. After loading the new version, call `noConflict()` to
+ // get a reference to it. At the same time the old version will be
+ // returned to Backbone.Marionette.
+ Marionette.noConflict = function () {
+ Backbone.Marionette = previousMarionette;
+ return this;
+ };
+
+ // Utilities
+ Marionette.bindEvents = proxy(bindEvents);
+ Marionette.unbindEvents = proxy(unbindEvents);
+ Marionette.bindRequests = proxy(bindRequests);
+ Marionette.unbindRequests = proxy(unbindRequests);
+ Marionette.mergeOptions = proxy(mergeOptions);
+ Marionette.getOption = proxy(getOption);
+ Marionette.normalizeMethods = proxy(normalizeMethods);
+ Marionette.extend = extend;
+ Marionette.isNodeAttached = isNodeAttached;
+ Marionette.deprecate = deprecate;
+ Marionette.triggerMethod = proxy(triggerMethod);
+ Marionette.triggerMethodOn = triggerMethodOn;
+ Marionette.isEnabled = isEnabled;
+ Marionette.setEnabled = setEnabled;
+ Marionette.monitorViewEvents = monitorViewEvents;
+
+ Marionette.Behaviors = {};
+ Marionette.Behaviors.behaviorsLookup = behaviorsLookup;
+
+ // Classes
+ Marionette.Application = Application;
+ Marionette.AppRouter = AppRouter;
+ Marionette.Renderer = Renderer;
+ Marionette.TemplateCache = TemplateCache;
+ Marionette.View = View;
+ Marionette.CollectionView = CollectionView;
+ Marionette.CompositeView = CompositeView;
+ Marionette.Behavior = Behavior;
+ Marionette.Region = Region;
+ Marionette.Error = MarionetteError;
+ Marionette.Object = MarionetteObject;
+
+ // Configuration
+ Marionette.DEV_MODE = false;
+ Marionette.FEATURES = FEATURES;
+ Marionette.VERSION = version;
+
+ return Marionette;
+
+}));
+
+//# sourceMappingURL=backbone.marionette.js.map
diff --git a/js/vendor/backbone.marionette/lib/backbone.marionette.js.map b/js/vendor/backbone.marionette/lib/backbone.marionette.js.map
new file mode 100644
index 000000000..b526be2bd
--- /dev/null
+++ b/js/vendor/backbone.marionette/lib/backbone.marionette.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"backbone.marionette.js","sources":["src/utils/proxy.js","src/utils/extend.js","src/utils/deprecate.js","src/common/is-node-attached.js","src/common/merge-options.js","src/common/get-option.js","src/common/normalize-methods.js","src/common/trigger-method.js","src/common/monitor-view-events.js","src/error.js","src/common/bind-events.js","src/common/bind-requests.js","src/utils/set-options.js","src/mixins/common.js","src/mixins/radio.js","src/object.js","src/template-cache.js","src/utils/invoke.js","src/mixins/behaviors.js","src/mixins/delegate-entity-events.js","src/utils/get-unique-event-name.js","src/mixins/triggers.js","src/mixins/ui.js","src/mixins/view.js","src/utils/destroy-backbone-view.js","src/region.js","src/common/build-region.js","src/mixins/regions.js","src/config/renderer.js","src/view.js","src/utils/emulate-collection.js","src/child-view-container.js","src/collection-view.js","src/composite-view.js","src/behavior.js","src/application.js","src/app-router.js","src/config/behaviors-lookup.js","src/config/features.js","src/backbone.marionette.js"],"sourcesContent":["//Internal utility for creating context style global utils\nconst proxy = function(method) {\n return function(context, ...args) {\n return method.apply(context, args);\n };\n};\n\nexport default proxy;\n","// Marionette.extend\n// -----------------\n\nimport Backbone from 'backbone';\n\n// Borrow the Backbone `extend` method so we can use it as needed\nconst extend = Backbone.Model.extend;\n\nexport default extend;\n","/* global console */\n\nimport _ from 'underscore';\n\nimport Marionette from '../backbone.marionette';\n\nconst deprecate = function(message, test) {\n if (_.isObject(message)) {\n message = (\n message.prev + ' is going to be removed in the future. ' +\n 'Please use ' + message.next + ' instead.' +\n (message.url ? ' See: ' + message.url : '')\n );\n }\n\n if (!Marionette.DEV_MODE) {\n return;\n }\n\n if ((test === undefined || !test) && !deprecate._cache[message]) {\n deprecate._warn('Deprecation warning: ' + message);\n deprecate._cache[message] = true;\n }\n};\n\ndeprecate._console = typeof console !== 'undefined' ? console : {};\ndeprecate._warn = function() {\n const warn = deprecate._console.warn || deprecate._console.log || _.noop;\n return warn.apply(deprecate._console, arguments);\n};\ndeprecate._cache = {};\n\nexport default deprecate;\n","// Marionette.isNodeAttached\n// -------------------------\n\nimport Backbone from 'backbone';\n\n// Determine if `el` is a child of the document\nconst isNodeAttached = function(el) {\n return Backbone.$.contains(document.documentElement, el);\n};\n\nexport default isNodeAttached;\n","import _ from 'underscore';\n\n// Merge `keys` from `options` onto `this`\nconst mergeOptions = function(options, keys) {\n if (!options) { return; }\n\n _.each(keys, (key) => {\n const option = options[key];\n if (option !== undefined) {\n this[key] = option;\n }\n });\n};\n\nexport default mergeOptions;\n","// Marionette.getOption\n// --------------------\n\n// Retrieve an object, function or other value from the\n// object or its `options`, with `options` taking precedence.\nconst getOption = function(optionName) {\n if (!optionName) { return; }\n if (this.options && (this.options[optionName] !== undefined)) {\n return this.options[optionName];\n } else {\n return this[optionName];\n }\n};\n\nexport default getOption;\n","import _ from 'underscore';\n\n// Marionette.normalizeMethods\n// ----------------------\n\n// Pass in a mapping of events => functions or function names\n// and return a mapping of events => functions\nconst normalizeMethods = function(hash) {\n return _.reduce(hash, (normalizedHash, method, name) => {\n if (!_.isFunction(method)) {\n method = this[method];\n }\n if (method) {\n normalizedHash[name] = method;\n }\n return normalizedHash;\n }, {});\n};\n\nexport default normalizeMethods;\n","// Trigger Method\n// --------------\n\nimport _ from 'underscore';\nimport getOption from './get-option';\n\n// split the event name on the \":\"\nconst splitter = /(^|:)(\\w)/gi;\n\n// take the event section (\"section1:section2:section3\")\n// and turn it in to uppercase name onSection1Section2Section3\nfunction getEventName(match, prefix, eventName) {\n return eventName.toUpperCase();\n}\n\nconst getOnMethodName = _.memoize(function(event) {\n return 'on' + event.replace(splitter, getEventName);\n});\n\n// Trigger an event and/or a corresponding method name. Examples:\n//\n// `this.triggerMethod(\"foo\")` will trigger the \"foo\" event and\n// call the \"onFoo\" method.\n//\n// `this.triggerMethod(\"foo:bar\")` will trigger the \"foo:bar\" event and\n// call the \"onFooBar\" method.\nexport function triggerMethod(event, ...args) {\n // get the method name from the event name\n const methodName = getOnMethodName(event);\n const method = getOption.call(this, methodName);\n let result;\n\n // call the onMethodName if it exists\n if (_.isFunction(method)) {\n // pass all args, except the event name\n result = method.apply(this, args);\n }\n\n // trigger the event\n this.trigger.apply(this, arguments);\n\n return result;\n}\n\n// triggerMethodOn invokes triggerMethod on a specific context\n//\n// e.g. `Marionette.triggerMethodOn(view, 'show')`\n// will trigger a \"show\" event or invoke onShow the view.\nexport function triggerMethodOn(context, ...args) {\n if (_.isFunction(context.triggerMethod)) {\n return context.triggerMethod.apply(context, args);\n }\n\n return triggerMethod.apply(context, args);\n}\n","// DOM Refresh\n// -----------\n\nimport _ from 'underscore';\nimport { triggerMethodOn } from './trigger-method';\n\n// Trigger method on children unless a pure Backbone.View\nfunction triggerMethodChildren(view, event, shouldTrigger) {\n if (!view._getImmediateChildren) { return; }\n _.each(view._getImmediateChildren(), child => {\n if (!shouldTrigger(child)) { return; }\n triggerMethodOn(child, event, child);\n });\n}\n\nfunction shouldTriggerAttach(view) {\n return !view._isAttached;\n}\n\nfunction shouldAttach(view) {\n if (!shouldTriggerAttach(view)) { return false; }\n view._isAttached = true;\n return true;\n}\n\nfunction shouldTriggerDetach(view) {\n return view._isAttached;\n}\n\nfunction shouldDetach(view) {\n if (!shouldTriggerDetach(view)) { return false; }\n view._isAttached = false;\n return true;\n}\n\nfunction triggerDOMRefresh(view) {\n if (view._isAttached && view._isRendered) {\n triggerMethodOn(view, 'dom:refresh', view);\n }\n}\n\nfunction handleBeforeAttach() {\n triggerMethodChildren(this, 'before:attach', shouldTriggerAttach);\n}\n\nfunction handleAttach() {\n triggerMethodChildren(this, 'attach', shouldAttach);\n triggerDOMRefresh(this);\n}\n\nfunction handleBeforeDetach() {\n triggerMethodChildren(this, 'before:detach', shouldTriggerDetach);\n}\n\nfunction handleDetach() {\n triggerMethodChildren(this, 'detach', shouldDetach);\n}\n\nfunction handleRender() {\n triggerDOMRefresh(this);\n}\n\n// Monitor a view's state, propagating attach/detach events to children and firing dom:refresh\n// whenever a rendered view is attached or an attached view is rendered.\nfunction monitorViewEvents(view) {\n if (view._areViewEventsMonitored) { return; }\n\n view._areViewEventsMonitored = true;\n\n view.on({\n 'before:attach': handleBeforeAttach,\n 'attach': handleAttach,\n 'before:detach': handleBeforeDetach,\n 'detach': handleDetach,\n 'render': handleRender\n });\n}\n\nexport default monitorViewEvents;\n","// Error\n// -----\n\nimport _ from 'underscore';\nimport extend from './utils/extend';\nimport {version} from '../package.json';\n\nconst errorProps = ['description', 'fileName', 'lineNumber', 'name', 'message', 'number'];\n\nconst MarionetteError = extend.call(Error, {\n urlRoot: `http://marionettejs.com/docs/v${version}/`,\n\n constructor(message, options) {\n if (_.isObject(message)) {\n options = message;\n message = options.message;\n } else if (!options) {\n options = {};\n }\n\n const error = Error.call(this, message);\n _.extend(this, _.pick(error, errorProps), _.pick(options, errorProps));\n\n this.captureStackTrace();\n\n if (options.url) {\n this.url = this.urlRoot + options.url;\n }\n },\n\n captureStackTrace() {\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, MarionetteError);\n }\n },\n\n toString() {\n return this.name + ': ' + this.message + (this.url ? ' See: ' + this.url : '');\n }\n});\n\nMarionetteError.extend = extend;\n\nexport default MarionetteError;\n","// Bind Entity Events & Unbind Entity Events\n// -----------------------------------------\n//\n// These methods are used to bind/unbind a backbone \"entity\" (e.g. collection/model)\n// to methods on a target object.\n//\n// The first parameter, `target`, must have the Backbone.Events module mixed in.\n//\n// The second parameter is the `entity` (Backbone.Model, Backbone.Collection or\n// any object that has Backbone.Events mixed in) to bind the events from.\n//\n// The third parameter is a hash of { \"event:name\": \"eventHandler\" }\n// configuration. Multiple handlers can be separated by a space. A\n// function can be supplied instead of a string handler name.\n\nimport _ from 'underscore';\nimport MarionetteError from '../error';\n\n// Bind/unbind the event to handlers specified as a string of\n// handler names on the target object\nfunction bindFromStrings(target, entity, evt, methods, actionName) {\n const methodNames = methods.split(/\\s+/);\n\n _.each(methodNames, function(methodName) {\n const method = target[methodName];\n if (!method) {\n throw new MarionetteError(`Method \"${methodName}\" was configured as an event handler, but does not exist.`);\n }\n\n target[actionName](entity, evt, method);\n });\n}\n\n// generic looping function\nfunction iterateEvents(target, entity, bindings, actionName) {\n if (!entity || !bindings) { return; }\n\n // type-check bindings\n if (!_.isObject(bindings)) {\n throw new MarionetteError({\n message: 'Bindings must be an object.',\n url: 'marionette.functions.html#marionettebindevents'\n });\n }\n\n // iterate the bindings and bind/unbind them\n _.each(bindings, function(method, evt) {\n\n // allow for a list of method names as a string\n if (_.isString(method)) {\n bindFromStrings(target, entity, evt, method, actionName);\n return;\n }\n\n target[actionName](entity, evt, method);\n });\n}\n\nfunction bindEvents(entity, bindings) {\n iterateEvents(this, entity, bindings, 'listenTo');\n return this;\n}\n\nfunction unbindEvents(entity, bindings) {\n iterateEvents(this, entity, bindings, 'stopListening');\n return this;\n}\n\n// Export Public API\nexport {\n bindEvents,\n unbindEvents\n};\n","// Bind/Unbind Radio Requests\n// -----------------------------------------\n//\n// These methods are used to bind/unbind a backbone.radio request\n// to methods on a target object.\n//\n// The first parameter, `target`, will set the context of the reply method\n//\n// The second parameter is the `Radio.channel` to bind the reply to.\n//\n// The third parameter is a hash of { \"request:name\": \"replyHandler\" }\n// configuration. A function can be supplied instead of a string handler name.\n\nimport _ from 'underscore';\nimport normalizeMethods from './normalize-methods';\nimport MarionetteError from '../error';\n\nfunction iterateReplies(target, channel, bindings, actionName) {\n if (!channel || !bindings) { return; }\n\n // type-check bindings\n if (!_.isObject(bindings)) {\n throw new MarionetteError({\n message: 'Bindings must be an object.',\n url: 'marionette.functions.html#marionettebindrequests'\n });\n }\n\n const normalizedRadioRequests = normalizeMethods.call(target, bindings);\n\n channel[actionName](normalizedRadioRequests, target);\n}\n\nfunction bindRequests(channel, bindings) {\n iterateReplies(this, channel, bindings, 'reply');\n return this;\n}\n\nfunction unbindRequests(channel, bindings) {\n iterateReplies(this, channel, bindings, 'stopReplying');\n return this;\n}\n\nexport {\n bindRequests,\n unbindRequests\n};\n","import _ from 'underscore';\n\n// Internal utility for setting options consistently across Mn\nconst setOptions = function(...args) {\n this.options = _.extend({}, _.result(this, 'options'), ...args);\n};\n\nexport default setOptions;\n","import _setOptions from '../utils/set-options';\nimport getOption from '../common/get-option';\nimport mergeOptions from '../common/merge-options';\nimport normalizeMethods from '../common/normalize-methods';\nimport {\n bindEvents,\n unbindEvents\n} from '../common/bind-events';\n\nexport default {\n\n // Imports the \"normalizeMethods\" to transform hashes of\n // events=>function references/names to a hash of events=>function references\n normalizeMethods: normalizeMethods,\n\n _setOptions: _setOptions,\n\n // A handy way to merge passed-in options onto the instance\n mergeOptions: mergeOptions,\n\n // Enable getting options from this or this.options by name.\n getOption: getOption,\n\n // Enable binding view's events from another entity.\n bindEvents: bindEvents,\n\n // Enable unbinding view's events from another entity.\n unbindEvents: unbindEvents\n};\n","import _ from 'underscore';\nimport Radio from 'backbone.radio';\n\nimport {\n bindRequests,\n unbindRequests\n} from '../common/bind-requests';\n\nimport {\n bindEvents,\n unbindEvents\n} from '../common/bind-events';\n\nimport MarionetteError from '../error';\n\n// MixinOptions\n// - channelName\n// - radioEvents\n// - radioRequests\n\nexport default {\n\n _initRadio() {\n const channelName = _.result(this, 'channelName');\n\n if (!channelName) {\n return;\n }\n\n /* istanbul ignore next */\n if (!Radio) {\n throw new MarionetteError({\n name: 'BackboneRadioMissing',\n message: 'The dependency \"backbone.radio\" is missing.'\n });\n }\n\n const channel = this._channel = Radio.channel(channelName);\n\n const radioEvents = _.result(this, 'radioEvents');\n this.bindEvents(channel, radioEvents);\n\n const radioRequests = _.result(this, 'radioRequests');\n this.bindRequests(channel, radioRequests);\n\n this.on('destroy', this._destroyRadio);\n },\n\n _destroyRadio() {\n this._channel.stopReplying(null, null, this);\n },\n\n getChannel() {\n return this._channel;\n },\n\n // Proxy `bindEvents`\n bindEvents: bindEvents,\n\n // Proxy `unbindEvents`\n unbindEvents: unbindEvents,\n\n // Proxy `bindRequests`\n bindRequests: bindRequests,\n\n // Proxy `unbindRequests`\n unbindRequests: unbindRequests\n\n};\n","// Object\n// ------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport extend from './utils/extend';\nimport { triggerMethod } from './common/trigger-method';\nimport CommonMixin from './mixins/common';\nimport RadioMixin from './mixins/radio';\n\nconst ClassOptions = [\n 'channelName',\n 'radioEvents',\n 'radioRequests'\n];\n\n// A Base Class that other Classes should descend from.\n// Object borrows many conventions and utilities from Backbone.\nconst MarionetteObject = function(options) {\n this._setOptions(options);\n this.mergeOptions(options, ClassOptions);\n this.cid = _.uniqueId(this.cidPrefix);\n this._initRadio();\n this.initialize.apply(this, arguments);\n};\n\nMarionetteObject.extend = extend;\n\n// Object Methods\n// --------------\n\n// Ensure it can trigger events with Backbone.Events\n_.extend(MarionetteObject.prototype, Backbone.Events, CommonMixin, RadioMixin, {\n cidPrefix: 'mno',\n\n // for parity with Marionette.AbstractView lifecyle\n _isDestroyed: false,\n\n isDestroyed() {\n return this._isDestroyed;\n },\n\n //this is a noop method intended to be overridden by classes that extend from this base\n initialize() {},\n\n destroy(...args) {\n if (this._isDestroyed) { return this; }\n\n this.triggerMethod('before:destroy', this, ...args);\n\n this._isDestroyed = true;\n this.triggerMethod('destroy', this, ...args);\n this.stopListening();\n\n return this;\n },\n\n triggerMethod: triggerMethod\n});\n\nexport default MarionetteObject;\n","// Template Cache\n// --------------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport MarionetteError from './error';\n\n// Manage templates stored in `<script>` blocks,\n// caching them for faster access.\nconst TemplateCache = function(templateId) {\n this.templateId = templateId;\n};\n\n// TemplateCache object-level methods. Manage the template\n// caches from these method calls instead of creating\n// your own TemplateCache instances\n_.extend(TemplateCache, {\n templateCaches: {},\n\n // Get the specified template by id. Either\n // retrieves the cached version, or loads it\n // from the DOM.\n get(templateId, options) {\n let cachedTemplate = this.templateCaches[templateId];\n\n if (!cachedTemplate) {\n cachedTemplate = new TemplateCache(templateId);\n this.templateCaches[templateId] = cachedTemplate;\n }\n\n return cachedTemplate.load(options);\n },\n\n // Clear templates from the cache. If no arguments\n // are specified, clears all templates:\n // `clear()`\n //\n // If arguments are specified, clears each of the\n // specified templates from the cache:\n // `clear(\"#t1\", \"#t2\", \"...\")`\n clear(...args) {\n let i;\n const length = args.length;\n\n if (length > 0) {\n for (i = 0; i < length; i++) {\n delete this.templateCaches[args[i]];\n }\n } else {\n this.templateCaches = {};\n }\n }\n});\n\n// TemplateCache instance methods, allowing each\n// template cache object to manage its own state\n// and know whether or not it has been loaded\n_.extend(TemplateCache.prototype, {\n\n // Internal method to load the template\n load(options) {\n // Guard clause to prevent loading this template more than once\n if (this.compiledTemplate) {\n return this.compiledTemplate;\n }\n\n // Load the template and compile it\n const template = this.loadTemplate(this.templateId, options);\n this.compiledTemplate = this.compileTemplate(template, options);\n\n return this.compiledTemplate;\n },\n\n // Load a template from the DOM, by default. Override\n // this method to provide your own template retrieval\n // For asynchronous loading with AMD/RequireJS, consider\n // using a template-loader plugin as described here:\n // https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs\n loadTemplate(templateId, options) {\n const $template = Backbone.$(templateId);\n\n if (!$template.length) {\n throw new MarionetteError({\n name: 'NoTemplateError',\n message: `Could not find template: \"${templateId}\"`\n });\n }\n return $template.html();\n },\n\n // Pre-compile the template before caching it. Override\n // this method if you do not need to pre-compile a template\n // (JST / RequireJS for example) or if you want to change\n // the template engine used (Handebars, etc).\n compileTemplate(rawTemplate, options) {\n return _.template(rawTemplate, options);\n }\n});\n\nexport default TemplateCache;\n","// Implementation of the invoke method (http://underscorejs.org/#invoke) with support for\n// lodash v3, v4, and underscore.js\nimport _ from 'underscore';\n\nexport default _.invokeMap || _.invoke;\n","import _ from 'underscore';\nimport _invoke from '../utils/invoke';\nimport { triggerMethod } from '../common/trigger-method';\nimport Marionette from '../backbone.marionette';\n\n// MixinOptions\n// - behaviors\n\n// Takes care of getting the behavior class\n// given options and a key.\n// If a user passes in options.behaviorClass\n// default to using that.\n// If a user passes in a Behavior Class directly, use that\n// Otherwise delegate the lookup to the users `behaviorsLookup` implementation.\nfunction getBehaviorClass(options, key) {\n if (options.behaviorClass) {\n return options.behaviorClass;\n //treat functions as a Behavior constructor\n } else if (_.isFunction(options)) {\n return options;\n }\n\n // behaviorsLookup can be either a flat object or a method\n if (_.isFunction(Marionette.Behaviors.behaviorsLookup)) {\n return Marionette.Behaviors.behaviorsLookup(options, key)[key];\n }\n\n return Marionette.Behaviors.behaviorsLookup[key];\n}\n\n// Iterate over the behaviors object, for each behavior\n// instantiate it and get its grouped behaviors.\n// This accepts a list of behaviors in either an object or array form\nfunction parseBehaviors(view, behaviors) {\n return _.chain(behaviors).map(function(options, key) {\n const BehaviorClass = getBehaviorClass(options, key);\n //if we're passed a class directly instead of an object\n const _options = options === BehaviorClass ? {} : options;\n const behavior = new BehaviorClass(_options, view);\n const nestedBehaviors = parseBehaviors(view, _.result(behavior, 'behaviors'));\n\n return [behavior].concat(nestedBehaviors);\n }).flatten().value();\n}\n\nexport default {\n _initBehaviors() {\n const behaviors = _.result(this, 'behaviors');\n\n // Behaviors defined on a view can be a flat object literal\n // or it can be a function that returns an object.\n this._behaviors = _.isObject(behaviors) ? parseBehaviors(this, behaviors) : {};\n },\n\n _getBehaviorTriggers() {\n const triggers = _invoke(this._behaviors, 'getTriggers');\n return _.extend({}, ...triggers);\n },\n\n _getBehaviorEvents() {\n const events = _invoke(this._behaviors, 'getEvents');\n return _.extend({}, ...events);\n },\n\n // proxy behavior $el to the view's $el.\n _proxyBehaviorViewProperties() {\n _invoke(this._behaviors, 'proxyViewProperties');\n },\n\n // delegate modelEvents and collectionEvents\n _delegateBehaviorEntityEvents() {\n _invoke(this._behaviors, 'delegateEntityEvents');\n },\n\n // undelegate modelEvents and collectionEvents\n _undelegateBehaviorEntityEvents() {\n _invoke(this._behaviors, 'undelegateEntityEvents');\n },\n\n _destroyBehaviors(args) {\n // Call destroy on each behavior after\n // destroying the view.\n // This unbinds event listeners\n // that behaviors have registered for.\n _invoke(this._behaviors, 'destroy', ...args);\n },\n\n _bindBehaviorUIElements() {\n _invoke(this._behaviors, 'bindUIElements');\n },\n\n _unbindBehaviorUIElements() {\n _invoke(this._behaviors, 'unbindUIElements');\n },\n\n _triggerEventOnBehaviors() {\n const behaviors = this._behaviors;\n // Use good ol' for as this is a very hot function\n for (let i = 0, length = behaviors && behaviors.length; i < length; i++) {\n triggerMethod.apply(behaviors[i], arguments);\n }\n }\n};\n","import _ from 'underscore';\n\nimport {\n bindEvents,\n unbindEvents\n} from '../common/bind-events';\n\n// MixinOptions\n// - collectionEvents\n// - modelEvents\n\nexport default {\n // Handle `modelEvents`, and `collectionEvents` configuration\n _delegateEntityEvents(model, collection) {\n this._undelegateEntityEvents(model, collection);\n\n const modelEvents = _.result(this, 'modelEvents');\n bindEvents.call(this, model, modelEvents);\n\n const collectionEvents = _.result(this, 'collectionEvents');\n bindEvents.call(this, collection, collectionEvents);\n },\n\n _undelegateEntityEvents(model, collection) {\n const modelEvents = _.result(this, 'modelEvents');\n unbindEvents.call(this, model, modelEvents);\n\n const collectionEvents = _.result(this, 'collectionEvents');\n unbindEvents.call(this, collection, collectionEvents);\n }\n};\n","import _ from 'underscore';\n\n// Borrow event splitter from Backbone\nconst delegateEventSplitter = /^(\\S+)\\s*(.*)$/;\n\nfunction uniqueName(eventName, selector) {\n return [eventName + _.uniqueId('.evt'), selector].join(' ');\n}\n\n// Set event name to be namespaced using a unique index\n// to generate a non colliding event namespace\n// http://api.jquery.com/event.namespace/\nconst getUniqueEventName = function(eventName) {\n const match = eventName.match(delegateEventSplitter);\n return uniqueName(match[1], match[2]);\n};\n\nexport default getUniqueEventName;\n","import _ from 'underscore';\nimport getUniqueEventName from '../utils/get-unique-event-name';\n\n// Internal method to create an event handler for a given `triggerDef` like\n// 'click:foo'\nfunction buildViewTrigger(view, triggerDef) {\n if (_.isString(triggerDef)) {\n triggerDef = {event: triggerDef};\n }\n\n const eventName = triggerDef.event;\n const shouldPreventDefault = triggerDef.preventDefault !== false;\n const shouldStopPropagation = triggerDef.stopPropagation !== false;\n\n return function(e) {\n if (shouldPreventDefault) {\n e.preventDefault();\n }\n\n if (shouldStopPropagation) {\n e.stopPropagation();\n }\n\n view.triggerMethod(eventName, view);\n };\n}\n\nexport default {\n\n // Configure `triggers` to forward DOM events to view\n // events. `triggers: {\"click .foo\": \"do:foo\"}`\n _getViewTriggers(view, triggers) {\n // Configure the triggers, prevent default\n // action and stop propagation of DOM events\n return _.reduce(triggers, (events, value, key) => {\n key = getUniqueEventName(key);\n events[key] = buildViewTrigger(view, value);\n return events;\n }, {});\n }\n\n};\n","import _ from 'underscore';\n// allows for the use of the @ui. syntax within\n// a given key for triggers and events\n// swaps the @ui with the associated selector.\n// Returns a new, non-mutated, parsed events hash.\nconst normalizeUIKeys = function(hash, ui) {\n return _.reduce(hash, (memo, val, key) => {\n const normalizedKey = normalizeUIString(key, ui);\n memo[normalizedKey] = val;\n return memo;\n }, {});\n};\n\n// utility method for parsing @ui. syntax strings\n// into associated selector\nconst normalizeUIString = function(uiString, ui) {\n return uiString.replace(/@ui\\.[a-zA-Z-_$0-9]*/g, (r) => {\n return ui[r.slice(4)];\n });\n};\n\n// allows for the use of the @ui. syntax within\n// a given value for regions\n// swaps the @ui with the associated selector\nconst normalizeUIValues = function(hash, ui, properties) {\n _.each(hash, (val, key) => {\n if (_.isString(val)) {\n hash[key] = normalizeUIString(val, ui);\n } else if (_.isObject(val) && _.isArray(properties)) {\n _.extend(val, normalizeUIValues(_.pick(val, properties), ui));\n /* Value is an object, and we got an array of embedded property names to normalize. */\n _.each(properties, (property) => {\n const propertyVal = val[property];\n if (_.isString(propertyVal)) {\n val[property] = normalizeUIString(propertyVal, ui);\n }\n });\n }\n });\n return hash;\n};\n\nexport default {\n\n // normalize the keys of passed hash with the views `ui` selectors.\n // `{\"@ui.foo\": \"bar\"}`\n normalizeUIKeys(hash) {\n const uiBindings = this._getUIBindings();\n return normalizeUIKeys(hash, uiBindings);\n },\n\n // normalize the passed string with the views `ui` selectors.\n // `\"@ui.bar\"`\n normalizeUIString(uiString) {\n const uiBindings = this._getUIBindings();\n return normalizeUIString(uiString, uiBindings);\n },\n\n // normalize the values of passed hash with the views `ui` selectors.\n // `{foo: \"@ui.bar\"}`\n normalizeUIValues(hash, properties) {\n const uiBindings = this._getUIBindings();\n return normalizeUIValues(hash, uiBindings, properties);\n },\n\n _getUIBindings() {\n const uiBindings = _.result(this, '_uiBindings');\n const ui = _.result(this, 'ui');\n return uiBindings || ui;\n },\n\n // This method binds the elements specified in the \"ui\" hash inside the view's code with\n // the associated jQuery selectors.\n _bindUIElements() {\n if (!this.ui) { return; }\n\n // store the ui hash in _uiBindings so they can be reset later\n // and so re-rendering the view will be able to find the bindings\n if (!this._uiBindings) {\n this._uiBindings = this.ui;\n }\n\n // get the bindings result, as a function or otherwise\n const bindings = _.result(this, '_uiBindings');\n\n // empty the ui so we don't have anything to start with\n this._ui = {};\n\n // bind each of the selectors\n _.each(bindings, (selector, key) => {\n this._ui[key] = this.$(selector);\n });\n\n this.ui = this._ui;\n },\n\n _unbindUIElements() {\n if (!this.ui || !this._uiBindings) { return; }\n\n // delete all of the existing ui bindings\n _.each(this.ui, ($el, name) => {\n delete this.ui[name];\n });\n\n // reset the ui element to the original bindings configuration\n this.ui = this._uiBindings;\n delete this._uiBindings;\n delete this._ui;\n },\n\n _getUI(name) {\n return this._ui[name];\n }\n};\n","// ViewMixin\n// ---------\n\nimport Backbone from 'backbone';\nimport _ from 'underscore';\nimport { triggerMethod } from '../common/trigger-method';\nimport BehaviorsMixin from './behaviors';\nimport CommonMixin from './common';\nimport DelegateEntityEventsMixin from './delegate-entity-events';\nimport TriggersMixin from './triggers';\nimport UIMixin from './ui';\nimport View from '../view';\nimport MarionetteError from '../error';\n\n// MixinOptions\n// - behaviors\n// - childViewEventPrefix\n// - childViewEvents\n// - childViewTriggers\n// - collectionEvents\n// - modelEvents\n// - triggers\n// - ui\n\n\nconst ViewMixin = {\n supportsRenderLifecycle: true,\n supportsDestroyLifecycle: true,\n\n _isDestroyed: false,\n\n isDestroyed() {\n return !!this._isDestroyed;\n },\n\n _isRendered: false,\n\n isRendered() {\n return !!this._isRendered;\n },\n\n _isAttached: false,\n\n isAttached() {\n return !!this._isAttached;\n },\n\n // Overriding Backbone.View's `delegateEvents` to handle\n // `events` and `triggers`\n delegateEvents(eventsArg) {\n\n this._proxyBehaviorViewProperties();\n this._buildEventProxies();\n\n const viewEvents = this._getEvents(eventsArg);\n\n if (typeof eventsArg === 'undefined') {\n this.events = viewEvents;\n }\n\n const combinedEvents = _.extend({},\n this._getBehaviorEvents(),\n viewEvents,\n this._getBehaviorTriggers(),\n this.getTriggers()\n );\n\n Backbone.View.prototype.delegateEvents.call(this, combinedEvents);\n\n return this;\n },\n\n _getEvents(eventsArg) {\n const events = eventsArg || this.events;\n\n if (_.isFunction(events)) {\n return this.normalizeUIKeys(events.call(this));\n }\n\n return this.normalizeUIKeys(events);\n },\n\n // Configure `triggers` to forward DOM events to view\n // events. `triggers: {\"click .foo\": \"do:foo\"}`\n getTriggers() {\n if (!this.triggers) { return; }\n\n // Allow `triggers` to be configured as a function\n const triggers = this.normalizeUIKeys(_.result(this, 'triggers'));\n\n // Configure the triggers, prevent default\n // action and stop propagation of DOM events\n return this._getViewTriggers(this, triggers);\n },\n\n // Handle `modelEvents`, and `collectionEvents` configuration\n delegateEntityEvents() {\n this._delegateEntityEvents(this.model, this.collection);\n\n // bind each behaviors model and collection events\n this._delegateBehaviorEntityEvents();\n\n return this;\n },\n\n // Handle unbinding `modelEvents`, and `collectionEvents` configuration\n undelegateEntityEvents() {\n this._undelegateEntityEvents(this.model, this.collection);\n\n // unbind each behaviors model and collection events\n this._undelegateBehaviorEntityEvents();\n\n return this;\n },\n\n // Internal helper method to verify whether the view hasn't been destroyed\n _ensureViewIsIntact() {\n if (this._isDestroyed) {\n throw new MarionetteError({\n name: 'ViewDestroyedError',\n message: `View (cid: \"${this.cid}\") has already been destroyed and cannot be used.`\n });\n }\n },\n\n // Handle destroying the view and its children.\n destroy(...args) {\n if (this._isDestroyed) { return this; }\n const shouldTriggerDetach = !!this._isAttached;\n\n this.triggerMethod('before:destroy', this, ...args);\n if (shouldTriggerDetach) {\n this.triggerMethod('before:detach', this);\n }\n\n // unbind UI elements\n this.unbindUIElements();\n\n // remove the view from the DOM\n // https://github.com/jashkenas/backbone/blob/1.2.3/backbone.js#L1235\n this._removeElement();\n\n if (shouldTriggerDetach) {\n this._isAttached = false;\n this.triggerMethod('detach', this);\n }\n\n // remove children after the remove to prevent extra paints\n this._removeChildren();\n\n this._destroyBehaviors(args);\n\n this._isDestroyed = true;\n this._isRendered = false;\n this.triggerMethod('destroy', this, ...args);\n\n this.stopListening();\n\n return this;\n },\n\n bindUIElements() {\n this._bindUIElements();\n this._bindBehaviorUIElements();\n\n return this;\n },\n\n // This method unbinds the elements specified in the \"ui\" hash\n unbindUIElements() {\n this._unbindUIElements();\n this._unbindBehaviorUIElements();\n\n return this;\n },\n\n getUI(name) {\n this._ensureViewIsIntact();\n return this._getUI(name);\n },\n\n // used as the prefix for child view events\n // that are forwarded through the layoutview\n childViewEventPrefix: 'childview',\n\n // import the `triggerMethod` to trigger events with corresponding\n // methods if the method exists\n triggerMethod() {\n const ret = triggerMethod.apply(this, arguments);\n\n this._triggerEventOnBehaviors.apply(this, arguments);\n this._triggerEventOnParentLayout.apply(this, arguments);\n\n return ret;\n },\n\n // Cache `childViewEvents` and `childViewTriggers`\n _buildEventProxies() {\n this._childViewEvents = _.result(this, 'childViewEvents');\n this._childViewTriggers = _.result(this, 'childViewTriggers');\n },\n\n _triggerEventOnParentLayout() {\n const layoutView = this._parentView();\n if (!layoutView) {\n return;\n }\n\n layoutView._childViewEventHandler.apply(layoutView, arguments);\n },\n\n // Walk the _parent tree until we find a view (if one exists).\n // Returns the parent view hierarchically closest to this view.\n _parentView() {\n let parent = this._parent;\n\n while (parent) {\n if (parent instanceof View) {\n return parent;\n }\n parent = parent._parent;\n }\n },\n\n _childViewEventHandler(eventName, ...args) {\n const childViewEvents = this.normalizeMethods(this._childViewEvents);\n\n // call collectionView childViewEvent if defined\n if (typeof childViewEvents !== 'undefined' && _.isFunction(childViewEvents[eventName])) {\n childViewEvents[eventName].apply(this, args);\n }\n\n // use the parent view's proxyEvent handlers\n const childViewTriggers = this._childViewTriggers;\n\n // Call the event with the proxy name on the parent layout\n if (childViewTriggers && _.isString(childViewTriggers[eventName])) {\n this.triggerMethod(childViewTriggers[eventName], ...args);\n }\n\n const prefix = _.result(this, 'childViewEventPrefix');\n\n if (prefix !== false) {\n const childEventName = prefix + ':' + eventName;\n\n this.triggerMethod(childEventName, ...args);\n }\n }\n};\n\n_.extend(ViewMixin, BehaviorsMixin, CommonMixin, DelegateEntityEventsMixin, TriggersMixin, UIMixin);\n\nexport default ViewMixin;\n","import { triggerMethodOn } from '../common/trigger-method';\n\nexport default function destroyBackboneView(view) {\n if (!view.supportsDestroyLifecycle) {\n triggerMethodOn(view, 'before:destroy', view);\n }\n\n const shouldTriggerDetach = !!view._isAttached;\n\n if (shouldTriggerDetach) {\n triggerMethodOn(view, 'before:detach', view);\n }\n\n view.remove();\n\n if (shouldTriggerDetach) {\n view._isAttached = false;\n triggerMethodOn(view, 'detach', view);\n }\n\n view._isDestroyed = true;\n\n if (!view.supportsDestroyLifecycle) {\n triggerMethodOn(view, 'destroy', view);\n }\n}\n","// Region\n// ------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport deprecate from './utils/deprecate';\nimport destroyBackboneView from './utils/destroy-backbone-view';\nimport monitorViewEvents from './common/monitor-view-events';\nimport isNodeAttached from './common/is-node-attached';\nimport { triggerMethodOn } from './common/trigger-method';\nimport MarionetteObject from './object';\nimport MarionetteError from './error';\n\nconst ClassOptions = [\n 'allowMissingEl',\n 'parentEl',\n 'replaceElement'\n];\n\nconst Region = MarionetteObject.extend({\n cidPrefix: 'mnr',\n replaceElement: false,\n _isReplaced: false,\n\n constructor(options) {\n this._setOptions(options);\n\n this.mergeOptions(options, ClassOptions);\n\n // getOption necessary because options.el may be passed as undefined\n this._initEl = this.el = this.getOption('el');\n\n // Handle when this.el is passed in as a $ wrapped element.\n this.el = this.el instanceof Backbone.$ ? this.el[0] : this.el;\n\n if (!this.el) {\n throw new MarionetteError({\n name: 'NoElError',\n message: 'An \"el\" must be specified for a region.'\n });\n }\n\n this.$el = this.getEl(this.el);\n MarionetteObject.call(this, options);\n },\n\n // Displays a backbone view instance inside of the region. Handles calling the `render`\n // method for you. Reads content directly from the `el` attribute. The `preventDestroy`\n // option can be used to prevent a view from the old view being destroyed on show.\n show(view, options) {\n if (!this._ensureElement(options)) {\n return;\n }\n this._ensureView(view);\n if (view === this.currentView) { return this; }\n\n this.triggerMethod('before:show', this, view, options);\n\n monitorViewEvents(view);\n\n this.empty(options);\n\n // We need to listen for if a view is destroyed in a way other than through the region.\n // If this happens we need to remove the reference to the currentView since once a view\n // has been destroyed we can not reuse it.\n view.on('destroy', this._empty, this);\n\n // Make this region the view's parent.\n // It's important that this parent binding happens before rendering so that any events\n // the child may trigger during render can also be triggered on the child's ancestor views.\n view._parent = this;\n\n this._renderView(view);\n\n this._attachView(view, options);\n\n this.triggerMethod('show', this, view, options);\n return this;\n },\n\n _renderView(view) {\n if (view._isRendered) {\n return;\n }\n\n if (!view.supportsRenderLifecycle) {\n triggerMethodOn(view, 'before:render', view);\n }\n\n view.render();\n\n if (!view.supportsRenderLifecycle) {\n view._isRendered = true;\n triggerMethodOn(view, 'render', view);\n }\n },\n\n _attachView(view, options = {}) {\n const shouldTriggerAttach = !view._isAttached && isNodeAttached(this.el);\n const shouldReplaceEl = typeof options.replaceElement === 'undefined' ? !!_.result(this, 'replaceElement') : !!options.replaceElement;\n\n if (shouldTriggerAttach) {\n triggerMethodOn(view, 'before:attach', view);\n }\n\n if (shouldReplaceEl) {\n this._replaceEl(view);\n } else {\n this.attachHtml(view);\n }\n\n if (shouldTriggerAttach) {\n view._isAttached = true;\n triggerMethodOn(view, 'attach', view);\n }\n\n this.currentView = view;\n },\n\n _ensureElement(options = {}) {\n if (!_.isObject(this.el)) {\n this.$el = this.getEl(this.el);\n this.el = this.$el[0];\n }\n\n if (!this.$el || this.$el.length === 0) {\n const allowMissingEl = typeof options.allowMissingEl === 'undefined' ? !!_.result(this, 'allowMissingEl') : !!options.allowMissingEl;\n\n if (allowMissingEl) {\n return false;\n } else {\n throw new MarionetteError(`An \"el\" must exist in DOM for this region ${this.cid}`);\n }\n }\n return true;\n },\n\n _ensureView(view) {\n if (!view) {\n throw new MarionetteError({\n name: 'ViewNotValid',\n message: 'The view passed is undefined and therefore invalid. You must pass a view instance to show.'\n });\n }\n\n if (view._isDestroyed) {\n throw new MarionetteError({\n name: 'ViewDestroyedError',\n message: `View (cid: \"${view.cid}\") has already been destroyed and cannot be used.`\n });\n }\n },\n\n // Override this method to change how the region finds the DOM element that it manages. Return\n // a jQuery selector object scoped to a provided parent el or the document if none exists.\n getEl(el) {\n return Backbone.$(el, _.result(this, 'parentEl'));\n },\n\n _replaceEl(view) {\n // always restore the el to ensure the regions el is present before replacing\n this._restoreEl();\n\n const parent = this.el.parentNode;\n\n parent.replaceChild(view.el, this.el);\n this._isReplaced = true;\n },\n\n // Restore the region's element in the DOM.\n _restoreEl() {\n // There is nothing to replace\n if (!this._isReplaced) {\n return;\n }\n\n const view = this.currentView;\n\n if (!view) {\n return;\n }\n\n const parent = view.el.parentNode;\n\n if (!parent) {\n return;\n }\n\n parent.replaceChild(this.el, view.el);\n this._isReplaced = false;\n },\n\n // Check to see if the region's el was replaced.\n isReplaced() {\n return !!this._isReplaced;\n },\n\n // Override this method to change how the new view is appended to the `$el` that the\n // region is managing\n attachHtml(view) {\n this.el.appendChild(view.el);\n },\n\n // Destroy the current view, if there is one. If there is no current view, it does\n // nothing and returns immediately.\n empty(options = { allowMissingEl: true }) {\n const view = this.currentView;\n\n // If there is no view in the region we should only detach current html\n if (!view) {\n if (this._ensureElement(options)) {\n this.detachHtml();\n }\n return this;\n }\n\n const shouldDestroy = !options.preventDestroy;\n\n if (!shouldDestroy) {\n deprecate('The preventDestroy option is deprecated. Use Region#detachView');\n }\n\n this._empty(view, shouldDestroy);\n return this;\n },\n\n _empty(view, shouldDestroy) {\n view.off('destroy', this._empty, this);\n this.triggerMethod('before:empty', this, view);\n\n this._restoreEl();\n\n delete this.currentView;\n\n if (!view._isDestroyed) {\n this._removeView(view, shouldDestroy);\n delete view._parent;\n }\n\n this.triggerMethod('empty', this, view);\n },\n\n _removeView(view, shouldDestroy) {\n if (!shouldDestroy) {\n this._detachView(view);\n return;\n }\n\n if (view.destroy) {\n view.destroy();\n } else {\n destroyBackboneView(view);\n }\n },\n\n detachView() {\n const view = this.currentView;\n\n if (!view) {\n return;\n }\n\n this._empty(view);\n\n return view;\n },\n\n _detachView(view) {\n const shouldTriggerDetach = !!view._isAttached;\n if (shouldTriggerDetach) {\n triggerMethodOn(view, 'before:detach', view);\n }\n\n this.detachHtml();\n\n if (shouldTriggerDetach) {\n view._isAttached = false;\n triggerMethodOn(view, 'detach', view);\n }\n },\n\n // Override this method to change how the region detaches current content\n detachHtml() {\n this.$el.contents().detach();\n },\n\n // Checks whether a view is currently present within the region. Returns `true` if there is\n // and `false` if no view is present.\n hasView() {\n return !!this.currentView;\n },\n\n // Reset the region by destroying any existing view and clearing out the cached `$el`.\n // The next time a view is shown via this region, the region will re-query the DOM for\n // the region's `el`.\n reset(options) {\n this.empty(options);\n\n if (this.$el) {\n this.el = this._initEl;\n }\n\n delete this.$el;\n return this;\n },\n\n destroy(options) {\n this.reset(options);\n return MarionetteObject.prototype.destroy.apply(this, arguments);\n }\n});\n\nexport default Region;\n","import _ from 'underscore';\nimport deprecate from '../utils/deprecate';\nimport MarionetteError from '../error';\nimport Region from '../region';\n\n// return the region instance from the definition\nexport default function(definition, defaults) {\n if (definition instanceof Region) {\n return definition;\n }\n\n return buildRegionFromDefinition(definition, defaults);\n}\n\nfunction buildRegionFromDefinition(definition, defaults) {\n const opts = _.extend({}, defaults);\n\n if (_.isString(definition)) {\n _.extend(opts, { el: definition });\n\n return buildRegionFromObject(opts);\n }\n\n if (_.isFunction(definition)) {\n _.extend(opts, { regionClass: definition });\n\n return buildRegionFromObject(opts);\n }\n\n if (_.isObject(definition)) {\n if (definition.selector) {\n deprecate('The selector option on a Region definition object is deprecated. Use el to pass a selector string');\n }\n\n _.extend(opts, { el: definition.selector }, definition);\n\n return buildRegionFromObject(opts);\n }\n\n throw new MarionetteError({\n message: 'Improper region configuration type.',\n url: 'marionette.region.html#region-configuration-types'\n });\n}\n\nfunction buildRegionFromObject(definition) {\n const RegionClass = definition.regionClass\n\n const options = _.omit(definition, 'regionClass');\n\n return new RegionClass(options);\n}\n","import _ from 'underscore';\nimport _invoke from '../utils/invoke';\nimport buildRegion from '../common/build-region';\nimport Region from '../region';\n\n// MixinOptions\n// - regions\n// - regionClass\n\nexport default {\n regionClass: Region,\n\n // Internal method to initialize the regions that have been defined in a\n // `regions` attribute on this View.\n _initRegions() {\n\n // init regions hash\n this.regions = this.regions || {};\n this._regions = {};\n\n this.addRegions(_.result(this, 'regions'));\n },\n\n // Internal method to re-initialize all of the regions by updating\n // the `el` that they point to\n _reInitRegions() {\n _invoke(this._regions, 'reset');\n },\n\n // Add a single region, by name, to the View\n addRegion(name, definition) {\n const regions = {};\n regions[name] = definition;\n return this.addRegions(regions)[name];\n },\n\n // Add multiple regions as a {name: definition, name2: def2} object literal\n addRegions(regions) {\n // If there's nothing to add, stop here.\n if (_.isEmpty(regions)) {\n return;\n }\n\n // Normalize region selectors hash to allow\n // a user to use the @ui. syntax.\n regions = this.normalizeUIValues(regions, ['selector', 'el']);\n\n // Add the regions definitions to the regions property\n this.regions = _.extend({}, this.regions, regions);\n\n return this._addRegions(regions);\n },\n\n // internal method to build and add regions\n _addRegions(regionDefinitions) {\n const defaults = {\n regionClass: this.regionClass,\n parentEl: _.partial(_.result, this, 'el')\n };\n\n return _.reduce(regionDefinitions, (regions, definition, name) => {\n regions[name] = buildRegion(definition, defaults);\n this._addRegion(regions[name], name);\n return regions;\n }, {});\n },\n\n _addRegion(region, name) {\n this.triggerMethod('before:add:region', this, name, region);\n\n region._parent = this;\n\n this._regions[name] = region;\n\n this.triggerMethod('add:region', this, name, region);\n },\n\n // Remove a single region from the View, by name\n removeRegion(name) {\n const region = this._regions[name];\n\n this._removeRegion(region, name);\n\n return region;\n },\n\n // Remove all regions from the View\n removeRegions() {\n const regions = this.getRegions();\n\n _.each(this._regions, _.bind(this._removeRegion, this));\n\n return regions;\n },\n\n _removeRegion(region, name) {\n this.triggerMethod('before:remove:region', this, name, region);\n\n region.destroy();\n\n delete this.regions[name];\n delete this._regions[name];\n\n this.triggerMethod('remove:region', this, name, region);\n },\n\n // Empty all regions in the region manager, but\n // leave them attached\n emptyRegions() {\n const regions = this.getRegions();\n _invoke(regions, 'empty');\n return regions;\n },\n\n // Checks to see if view contains region\n // Accepts the region name\n // hasRegion('main')\n hasRegion(name) {\n return !!this.getRegion(name);\n },\n\n // Provides access to regions\n // Accepts the region name\n // getRegion('main')\n getRegion(name) {\n return this._regions[name];\n },\n\n // Get all regions\n getRegions() {\n return _.clone(this._regions);\n },\n\n showChildView(name, view, ...args) {\n const region = this.getRegion(name);\n return region.show(view, ...args);\n },\n\n detachChildView(name) {\n return this.getRegion(name).detachView();\n },\n\n getChildView(name) {\n return this.getRegion(name).currentView;\n }\n\n};\n","// Renderer\n// --------\n\nimport _ from 'underscore';\nimport MarionetteError from '../error';\nimport TemplateCache from '../template-cache';\n\n// Render a template with data by passing in the template\n// selector and the data to render.\nconst Renderer = {\n\n // Render a template with data. The `template` parameter is\n // passed to the `TemplateCache` object to retrieve the\n // template function. Override this method to provide your own\n // custom rendering and template handling for all of Marionette.\n render(template, data) {\n if (!template) {\n throw new MarionetteError({\n name: 'TemplateNotFoundError',\n message: 'Cannot render the template since its false, null or undefined.'\n });\n }\n\n const templateFunc = _.isFunction(template) ? template : TemplateCache.get(template);\n\n return templateFunc(data);\n }\n};\n\nexport default Renderer;\n","// View\n// ---------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport isNodeAttached from './common/is-node-attached';\nimport monitorViewEvents from './common/monitor-view-events';\nimport ViewMixin from './mixins/view';\nimport RegionsMixin from './mixins/regions';\nimport Renderer from './config/renderer';\n\nconst ClassOptions = [\n 'behaviors',\n 'childViewEventPrefix',\n 'childViewEvents',\n 'childViewTriggers',\n 'collectionEvents',\n 'events',\n 'modelEvents',\n 'regionClass',\n 'regions',\n 'template',\n 'templateContext',\n 'triggers',\n 'ui'\n];\n\n// The standard view. Includes view events, automatic rendering\n// of Underscore templates, nested views, and more.\nconst View = Backbone.View.extend({\n\n constructor(options) {\n this.render = _.bind(this.render, this);\n\n this._setOptions(options);\n\n this.mergeOptions(options, ClassOptions);\n\n monitorViewEvents(this);\n\n this._initBehaviors();\n this._initRegions();\n\n const args = Array.prototype.slice.call(arguments);\n args[0] = this.options;\n Backbone.View.prototype.constructor.apply(this, args);\n\n this.delegateEntityEvents();\n },\n\n // Serialize the view's model *or* collection, if\n // it exists, for the template\n serializeData() {\n if (!this.model && !this.collection) {\n return {};\n }\n\n // If we have a model, we serialize that\n if (this.model) {\n return this.serializeModel();\n }\n\n // Otherwise, we serialize the collection,\n // making it available under the `items` property\n return {\n items: this.serializeCollection()\n };\n },\n\n // Prepares the special `model` property of a view\n // for being displayed in the template. By default\n // we simply clone the attributes. Override this if\n // you need a custom transformation for your view's model\n serializeModel() {\n if (!this.model) { return {}; }\n return _.clone(this.model.attributes);\n },\n\n // Serialize a collection by cloning each of\n // its model's attributes\n serializeCollection() {\n if (!this.collection) { return {}; }\n return this.collection.map(function(model) { return _.clone(model.attributes); });\n },\n\n // Overriding Backbone.View's `setElement` to handle\n // if an el was previously defined. If so, the view might be\n // rendered or attached on setElement.\n setElement() {\n const hasEl = !!this.el;\n\n Backbone.View.prototype.setElement.apply(this, arguments);\n\n if (hasEl) {\n this._isRendered = !!this.$el.length;\n this._isAttached = isNodeAttached(this.el);\n }\n\n if (this._isRendered) {\n this.bindUIElements();\n }\n\n return this;\n },\n\n // Render the view, defaulting to underscore.js templates.\n // You can override this in your view definition to provide\n // a very specific rendering for your view. In general, though,\n // you should override the `Marionette.Renderer` object to\n // change how Marionette renders views.\n // Subsequent renders after the first will re-render all nested\n // views.\n render() {\n this._ensureViewIsIntact();\n\n this.triggerMethod('before:render', this);\n\n // If this is not the first render call, then we need to\n // re-initialize the `el` for each region\n if (this._isRendered) {\n this._reInitRegions();\n }\n\n this._renderTemplate();\n this.bindUIElements();\n\n this._isRendered = true;\n this.triggerMethod('render', this);\n\n return this;\n },\n\n // Internal method to render the template with the serialized data\n // and template context via the `Marionette.Renderer` object.\n _renderTemplate() {\n const template = this.getTemplate();\n\n // Allow template-less views\n if (template === false) {\n return;\n }\n\n // Add in entity data and template context\n const data = this.mixinTemplateContext(this.serializeData());\n\n // Render and add to el\n const html = Renderer.render(template, data, this);\n this.attachElContent(html);\n },\n\n // Get the template for this view\n // instance. You can set a `template` attribute in the view\n // definition or pass a `template: \"whatever\"` parameter in\n // to the constructor options.\n getTemplate() {\n return this.template;\n },\n\n // Mix in template context methods. Looks for a\n // `templateContext` attribute, which can either be an\n // object literal, or a function that returns an object\n // literal. All methods and attributes from this object\n // are copies to the object passed in.\n mixinTemplateContext(target = {}) {\n const templateContext = _.result(this, 'templateContext');\n return _.extend(target, templateContext);\n },\n\n // Attaches the content of a given view.\n // This method can be overridden to optimize rendering,\n // or to render in a non standard way.\n //\n // For example, using `innerHTML` instead of `$el.html`\n //\n // ```js\n // attachElContent(html) {\n // this.el.innerHTML = html;\n // return this;\n // }\n // ```\n attachElContent(html) {\n this.$el.html(html);\n\n return this;\n },\n\n // called by ViewMixin destroy\n _removeChildren() {\n this.removeRegions();\n },\n\n _getImmediateChildren() {\n return _.chain(this.getRegions())\n .map('currentView')\n .compact()\n .value();\n }\n});\n\n_.extend(View.prototype, ViewMixin, RegionsMixin);\n\nexport default View;\n","// Mix in methods from Underscore, for iteration, and other\n// collection related features.\n// Borrowing this code from Backbone.Collection:\n// https://github.com/jashkenas/backbone/blob/1.1.2/backbone.js#L962\n\nimport _ from 'underscore';\n\nconst methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',\n 'select', 'reject', 'every', 'all', 'some', 'any', 'include',\n 'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',\n 'last', 'without', 'isEmpty', 'pluck', 'reduce'];\n\nconst emulateCollection = function(object, listProperty) {\n _.each(methods, function(method) {\n object[method] = function() {\n const list = _.values(_.result(this, listProperty));\n const args = [list].concat(_.toArray(arguments));\n return _[method].apply(_, args);\n };\n });\n};\n\nexport default emulateCollection;\n","import _ from 'underscore';\nimport emulateCollection from './utils/emulate-collection';\n\n// Provide a container to store, retrieve and\n// shut down child views.\nconst Container = function(views) {\n this._views = {};\n this._indexByModel = {};\n this._indexByCustom = {};\n this._updateLength();\n\n _.each(views, _.bind(this.add, this));\n};\n\nemulateCollection(Container.prototype, '_views');\n\n// Container Methods\n// -----------------\n\n_.extend(Container.prototype, {\n\n // Add a view to this container. Stores the view\n // by `cid` and makes it searchable by the model\n // cid (and model itself). Optionally specify\n // a custom key to store an retrieve the view.\n add(view, customIndex) {\n return this._add(view, customIndex)._updateLength();\n },\n\n // To be used when avoiding call _updateLength\n // When you are done adding all your new views\n // call _updateLength\n _add(view, customIndex) {\n const viewCid = view.cid;\n\n // store the view\n this._views[viewCid] = view;\n\n // index it by model\n if (view.model) {\n this._indexByModel[view.model.cid] = viewCid;\n }\n\n // index by custom\n if (customIndex) {\n this._indexByCustom[customIndex] = viewCid;\n }\n\n return this;\n },\n\n // Find a view by the model that was attached to\n // it. Uses the model's `cid` to find it.\n findByModel(model) {\n return this.findByModelCid(model.cid);\n },\n\n // Find a view by the `cid` of the model that was attached to\n // it. Uses the model's `cid` to find the view `cid` and\n // retrieve the view using it.\n findByModelCid(modelCid) {\n const viewCid = this._indexByModel[modelCid];\n return this.findByCid(viewCid);\n },\n\n // Find a view by a custom indexer.\n findByCustom(index) {\n const viewCid = this._indexByCustom[index];\n return this.findByCid(viewCid);\n },\n\n // Find by index. This is not guaranteed to be a\n // stable index.\n findByIndex(index) {\n return _.values(this._views)[index];\n },\n\n // retrieve a view by its `cid` directly\n findByCid(cid) {\n return this._views[cid];\n },\n\n // Remove a view\n remove(view) {\n return this._remove(view)._updateLength();\n },\n\n // To be used when avoiding call _updateLength\n // When you are done adding all your new views\n // call _updateLength\n _remove(view) {\n const viewCid = view.cid;\n\n // delete model index\n if (view.model) {\n delete this._indexByModel[view.model.cid];\n }\n\n // delete custom index\n _.some(this._indexByCustom, _.bind(function(cid, key) {\n if (cid === viewCid) {\n delete this._indexByCustom[key];\n return true;\n }\n }, this));\n\n // remove the view from the container\n delete this._views[viewCid];\n\n return this;\n },\n\n // Update the `.length` attribute on this container\n _updateLength() {\n this.length = _.size(this._views);\n\n return this;\n }\n});\n\nexport default Container;\n","// Collection View\n// ---------------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport destroyBackboneView from './utils/destroy-backbone-view';\nimport isNodeAttached from './common/is-node-attached';\nimport monitorViewEvents from './common/monitor-view-events';\nimport { triggerMethodOn } from './common/trigger-method';\nimport ChildViewContainer from './child-view-container';\nimport MarionetteError from './error';\nimport ViewMixin from './mixins/view';\n\nconst ClassOptions = [\n 'behaviors',\n 'childView',\n 'childViewEventPrefix',\n 'childViewEvents',\n 'childViewOptions',\n 'childViewTriggers',\n 'collectionEvents',\n 'events',\n 'filter',\n 'emptyView',\n 'emptyViewOptions',\n 'modelEvents',\n 'reorderOnSort',\n 'sort',\n 'triggers',\n 'ui',\n 'viewComparator'\n];\n\n// A view that iterates over a Backbone.Collection\n// and renders an individual child view for each model.\nconst CollectionView = Backbone.View.extend({\n\n // flag for maintaining the sorted order of the collection\n sort: true,\n\n // constructor\n // option to pass `{sort: false}` to prevent the `CollectionView` from\n // maintaining the sorted order of the collection.\n // This will fallback onto appending childView's to the end.\n //\n // option to pass `{viewComparator: compFunction()}` to allow the `CollectionView`\n // to use a custom sort order for the collection.\n constructor(options) {\n this.render = _.bind(this.render, this);\n\n this._setOptions(options);\n\n this.mergeOptions(options, ClassOptions);\n\n monitorViewEvents(this);\n\n this._initBehaviors();\n this.once('render', this._initialEvents);\n this._initChildViewStorage();\n this._bufferedChildren = [];\n\n const args = Array.prototype.slice.call(arguments);\n args[0] = this.options;\n Backbone.View.prototype.constructor.apply(this, args);\n\n this.delegateEntityEvents();\n },\n\n // Instead of inserting elements one by one into the page, it's much more performant to insert\n // elements into a document fragment and then insert that document fragment into the page\n _startBuffering() {\n this._isBuffering = true;\n },\n\n _endBuffering() {\n const shouldTriggerAttach = !!this._isAttached;\n const triggerOnChildren = shouldTriggerAttach ? this._getImmediateChildren() : [];\n\n this._isBuffering = false;\n\n _.each(triggerOnChildren, child => {\n triggerMethodOn(child, 'before:attach', child);\n });\n\n this.attachBuffer(this, this._createBuffer());\n\n _.each(triggerOnChildren, child => {\n child._isAttached = true;\n triggerMethodOn(child, 'attach', child);\n });\n\n this._bufferedChildren = [];\n },\n\n _getImmediateChildren() {\n return _.values(this.children._views);\n },\n\n // Configured the initial events that the collection view binds to.\n _initialEvents() {\n if (this.collection) {\n this.listenTo(this.collection, 'add', this._onCollectionAdd);\n this.listenTo(this.collection, 'update', this._onCollectionUpdate);\n this.listenTo(this.collection, 'reset', this.render);\n\n if (this.sort) {\n this.listenTo(this.collection, 'sort', this._sortViews);\n }\n }\n },\n\n // Handle a child added to the collection\n _onCollectionAdd(child, collection, opts) {\n // `index` is present when adding with `at` since BB 1.2; indexOf fallback for < 1.2\n let index = opts.at !== undefined && (opts.index || collection.indexOf(child));\n\n // When filtered or when there is no initial index, calculate index.\n if (this.filter || index === false) {\n index = _.indexOf(this._filteredSortedModels(index), child);\n }\n\n if (this._shouldAddChild(child, index)) {\n this._destroyEmptyView();\n this._addChild(child, index)\n }\n },\n\n // Handle collection update model removals\n _onCollectionUpdate(collection, options) {\n const changes = options.changes;\n this._removeChildModels(changes.removed);\n },\n\n // Remove the child views and destroy them.\n // This function also updates the indices of later views\n // in the collection in order to keep the children in sync with the collection.\n // \"models\" is an array of models and the corresponding views\n // will be removed and destroyed from the CollectionView\n _removeChildModels(models, {checkEmpty} = {}) {\n const shouldCheckEmpty = checkEmpty !== false;\n\n // Used to determine where to update the remaining\n // sibling view indices after these views are removed.\n const removedViews = this._getRemovedViews(models);\n\n if (!removedViews.length) {\n return;\n }\n\n this.children._updateLength();\n\n // decrement the index of views after this one\n this._updateIndices(removedViews, false);\n\n if (shouldCheckEmpty) {\n this._checkEmpty();\n }\n },\n\n // Returns the views that will be used for re-indexing\n // through CollectionView#_updateIndices.\n _getRemovedViews(models) {\n\n // Returning a view means something was removed.\n return _.reduce(models, (removingViews, model) => {\n const view = this.children.findByModel(model);\n\n if (!view || view._isDestroyed) {\n return removingViews;\n }\n\n this._removeChildView(view);\n\n removingViews.push(view);\n\n return removingViews;\n }, []);\n },\n\n _findGreatestIndexedView(views) {\n\n return _.reduce(views, (greatestIndexedView, view) => {\n // Even if the index is `undefined`, a view will get returned.\n if (!greatestIndexedView || greatestIndexedView._index < view._index) {\n return view;\n }\n\n return greatestIndexedView;\n }, undefined);\n },\n\n _removeChildView(view) {\n this.triggerMethod('before:remove:child', this, view);\n\n this.children._remove(view);\n if (view.destroy) {\n view.destroy();\n } else {\n destroyBackboneView(view);\n }\n\n delete view._parent;\n this.stopListening(view);\n this.triggerMethod('remove:child', this, view);\n },\n\n // Overriding Backbone.View's `setElement` to handle\n // if an el was previously defined. If so, the view might be\n // attached on setElement.\n setElement() {\n const hasEl = !!this.el;\n\n Backbone.View.prototype.setElement.apply(this, arguments);\n\n if (hasEl) {\n this._isAttached = isNodeAttached(this.el);\n }\n\n return this;\n },\n\n // Render children views. Override this method to provide your own implementation of a\n // render function for the collection view.\n render() {\n this._ensureViewIsIntact();\n this.triggerMethod('before:render', this);\n this._renderChildren();\n this._isRendered = true;\n this.triggerMethod('render', this);\n return this;\n },\n\n // An efficient rendering used for filtering. Instead of modifying the whole DOM for the\n // collection view, we are only adding or removing the related childrenViews.\n setFilter(filter, {preventRender} = {}) {\n const canBeRendered = this._isRendered && !this._isDestroyed;\n const filterChanged = this.filter !== filter;\n const shouldRender = canBeRendered && filterChanged && !preventRender;\n\n if (shouldRender) {\n const previousModels = this._filteredSortedModels();\n this.filter = filter;\n const models = this._filteredSortedModels();\n this._applyModelDeltas(models, previousModels);\n } else {\n this.filter = filter;\n }\n\n return this;\n },\n\n // `removeFilter` is actually an alias for removing filters.\n removeFilter(options) {\n return this.setFilter(null, options);\n },\n\n // Calculate and apply difference by cid between `models` and `previousModels`.\n _applyModelDeltas(models, previousModels) {\n const currentIds = {};\n _.each(models, (model, index) => {\n const addedChildNotExists = !this.children.findByModel(model);\n if (addedChildNotExists) {\n this._onCollectionAdd(model, this.collection, {at: index});\n }\n currentIds[model.cid] = true;\n });\n\n const removeModels = _.filter(previousModels, (prevModel) => {\n return !currentIds[prevModel.cid] && this.children.findByModel(prevModel);\n });\n\n this._removeChildModels(removeModels);\n },\n\n // Reorder DOM after sorting. When your element's rendering do not use their index,\n // you can pass reorderOnSort: true to only reorder the DOM after a sort instead of\n // rendering all the collectionView.\n reorder() {\n const children = this.children;\n const models = this._filteredSortedModels();\n\n if (!models.length && this._showingEmptyView) { return this; }\n\n const anyModelsAdded = _.some(models, function(model) {\n return !children.findByModel(model);\n });\n\n // If there are any new models added due to filtering we need to add child views,\n // so render as normal.\n if (anyModelsAdded) {\n this.render();\n } else {\n\n const filteredOutModels = [];\n\n // Get the DOM nodes in the same order as the models and\n // find the model that were children before but aren't in this new order.\n const elsToReorder = children.reduce(function(viewEls, view) {\n const index = _.indexOf(models, view.model);\n\n if (index === -1) {\n filteredOutModels.push(view.model);\n return viewEls;\n }\n\n view._index = index;\n\n viewEls[index] = view.el;\n\n return viewEls;\n }, new Array(models.length));\n\n this.triggerMethod('before:reorder', this);\n\n // Since append moves elements that are already in the DOM, appending the elements\n // will effectively reorder them.\n this._appendReorderedChildren(elsToReorder);\n\n // remove any views that have been filtered out\n this._removeChildModels(filteredOutModels);\n\n this.triggerMethod('reorder', this);\n }\n return this;\n },\n\n // Render view after sorting. Override this method to change how the view renders\n // after a `sort` on the collection.\n resortView() {\n if (this.reorderOnSort) {\n this.reorder();\n } else {\n this._renderChildren();\n }\n return this;\n },\n\n // Internal method. This checks for any changes in the order of the collection.\n // If the index of any view doesn't match, it will render.\n _sortViews() {\n const models = this._filteredSortedModels();\n\n // check for any changes in sort order of views\n const orderChanged = _.find(models, (item, index) => {\n const view = this.children.findByModel(item);\n return !view || view._index !== index;\n });\n\n if (orderChanged) {\n this.resortView();\n }\n },\n\n // Internal reference to what index a `emptyView` is.\n _emptyViewIndex: -1,\n\n // Internal method. Separated so that CompositeView can append to the childViewContainer\n // if necessary\n _appendReorderedChildren(children) {\n this.$el.append(children);\n },\n\n // Internal method. Separated so that CompositeView can have more control over events\n // being triggered, around the rendering process\n _renderChildren() {\n if (this._isRendered) {\n this._destroyEmptyView();\n this._destroyChildren({checkEmpty: false});\n }\n\n const models = this._filteredSortedModels();\n if (this.isEmpty({processedModels: models})) {\n this._showEmptyView();\n } else {\n this.triggerMethod('before:render:children', this);\n this._startBuffering();\n this._showCollection(models);\n this._endBuffering();\n this.triggerMethod('render:children', this);\n }\n },\n\n _createView(model, index) {\n const ChildView = this._getChildView(model);\n const childViewOptions = this._getChildViewOptions(model, index);\n const view = this.buildChildView(model, ChildView, childViewOptions);\n return view;\n },\n\n _setupChildView(view, index) {\n view._parent = this;\n\n monitorViewEvents(view);\n\n // set up the child view event forwarding\n this._proxyChildEvents(view);\n\n if (this.sort) {\n view._index = index;\n }\n },\n\n // Internal method to loop through collection and show each child view.\n _showCollection(models) {\n _.each(models, _.bind(this._addChild, this));\n this.children._updateLength();\n },\n\n // Allow the collection to be sorted by a custom view comparator\n _filteredSortedModels(addedAt) {\n if (!this.collection || !this.collection.length) { return []; }\n\n const viewComparator = this.getViewComparator();\n let models = this.collection.models;\n addedAt = Math.min(Math.max(addedAt, 0), models.length - 1);\n\n if (viewComparator) {\n let addedModel;\n // Preserve `at` location, even for a sorted view\n if (addedAt) {\n addedModel = models[addedAt];\n models = models.slice(0, addedAt).concat(models.slice(addedAt + 1));\n }\n models = this._sortModelsBy(models, viewComparator);\n if (addedModel) {\n models.splice(addedAt, 0, addedModel);\n }\n }\n\n // Filter after sorting in case the filter uses the index\n models = this._filterModels(models);\n\n return models;\n },\n\n getViewComparator() {\n return this.viewComparator;\n },\n\n // Filter an array of models, if a filter exists\n _filterModels(models) {\n if (this.filter) {\n models = _.filter(models, (model, index) => {\n return this._shouldAddChild(model, index);\n });\n }\n return models;\n },\n\n _sortModelsBy(models, comparator) {\n if (typeof comparator === 'string') {\n return _.sortBy(models, (model) => {\n return model.get(comparator);\n });\n } else if (comparator.length === 1) {\n return _.sortBy(models, _.bind(comparator, this));\n } else {\n return models.sort(_.bind(comparator, this));\n }\n },\n\n // Internal method to show an empty view in place of a collection of child views,\n // when the collection is empty\n _showEmptyView() {\n const EmptyView = this._getEmptyView();\n\n if (EmptyView && !this._showingEmptyView) {\n this._showingEmptyView = true;\n\n const model = new Backbone.Model();\n let emptyViewOptions =\n this.emptyViewOptions || this.childViewOptions;\n if (_.isFunction(emptyViewOptions)) {\n emptyViewOptions = emptyViewOptions.call(this, model, this._emptyViewIndex);\n }\n\n const view = this.buildChildView(model, EmptyView, emptyViewOptions);\n\n this.triggerMethod('before:render:empty', this, view);\n this.addChildView(view, 0);\n this.triggerMethod('render:empty', this, view);\n }\n },\n\n // Internal method to destroy an existing emptyView instance if one exists. Called when\n // a collection view has been rendered empty, and then a child is added to the collection.\n _destroyEmptyView() {\n if (this._showingEmptyView) {\n this.triggerMethod('before:remove:empty', this);\n\n this._destroyChildren();\n delete this._showingEmptyView;\n\n this.triggerMethod('remove:empty', this);\n }\n },\n\n // Retrieve the empty view class\n _getEmptyView() {\n const emptyView = this.emptyView;\n\n if (!emptyView) { return; }\n\n return this._getView(emptyView);\n },\n\n // Retrieve the `childView` class\n // The `childView` property can be either a view class or a function that\n // returns a view class. If it is a function, it will receive the model that\n // will be passed to the view instance (created from the returned view class)\n _getChildView(child) {\n let childView = this.childView;\n\n if (!childView) {\n throw new MarionetteError({\n name: 'NoChildViewError',\n message: 'A \"childView\" must be specified'\n });\n }\n\n childView = this._getView(childView, child);\n\n if (!childView) {\n throw new MarionetteError({\n name: 'InvalidChildViewError',\n message: '\"childView\" must be a view class or a function that returns a view class'\n });\n }\n\n return childView;\n },\n\n // First check if the `view` is a view class (the common case)\n // Then check if it's a function (which we assume that returns a view class)\n _getView(view, child) {\n if (view.prototype instanceof Backbone.View || view === Backbone.View) {\n return view;\n } else if (_.isFunction(view)) {\n return view.call(this, child);\n }\n },\n\n // Internal method for building and adding a child view\n _addChild(child, index) {\n const view = this._createView(child, index);\n this.addChildView(view, index);\n\n return view;\n },\n\n _getChildViewOptions(child, index) {\n if (_.isFunction(this.childViewOptions)) {\n return this.childViewOptions(child, index);\n }\n\n return this.childViewOptions;\n },\n\n // Render the child's view and add it to the HTML for the collection view at a given index.\n // This will also update the indices of later views in the collection in order to keep the\n // children in sync with the collection.\n addChildView(view, index) {\n this.triggerMethod('before:add:child', this, view);\n this._setupChildView(view, index);\n\n // Store the child view itself so we can properly remove and/or destroy it later\n if (this._isBuffering) {\n // Add to children, but don't update children's length.\n this.children._add(view);\n } else {\n // increment indices of views after this one\n this._updateIndices(view, true);\n this.children.add(view);\n }\n\n this._renderView(view);\n\n this._attachView(view, index);\n\n this.triggerMethod('add:child', this, view);\n\n return view;\n },\n\n // Internal method. This decrements or increments the indices of views after the added/removed\n // view to keep in sync with the collection.\n _updateIndices(views, increment) {\n if (!this.sort) {\n return;\n }\n\n const view = _.isArray(views) ? this._findGreatestIndexedView(views) : views;\n\n // update the indexes of views after this one\n this.children.each((laterView) => {\n if (laterView._index >= view._index) {\n laterView._index += increment ? 1 : -1;\n }\n });\n },\n\n _renderView(view) {\n if (view._isRendered) {\n return;\n }\n\n if (!view.supportsRenderLifecycle) {\n triggerMethodOn(view, 'before:render', view);\n }\n\n view.render();\n\n if (!view.supportsRenderLifecycle) {\n view._isRendered = true;\n triggerMethodOn(view, 'render', view);\n }\n },\n\n _attachView(view, index) {\n // Only trigger attach if already attached and not buffering,\n // otherwise _endBuffering() or Region#show() handles this.\n const shouldTriggerAttach = !view._isAttached && !this._isBuffering && this._isAttached;\n\n if (shouldTriggerAttach) {\n triggerMethodOn(view, 'before:attach', view);\n }\n\n this.attachHtml(this, view, index);\n\n if (shouldTriggerAttach) {\n view._isAttached = true;\n triggerMethodOn(view, 'attach', view);\n }\n },\n\n // Build a `childView` for a model in the collection.\n buildChildView(child, ChildViewClass, childViewOptions) {\n const options = _.extend({model: child}, childViewOptions);\n return new ChildViewClass(options);\n },\n\n // Remove the child view and destroy it. This function also updates the indices of later views\n // in the collection in order to keep the children in sync with the collection.\n removeChildView(view) {\n if (!view || view._isDestroyed) {\n return view;\n }\n\n this._removeChildView(view);\n this.children._updateLength();\n // decrement the index of views after this one\n this._updateIndices(view, false);\n return view;\n },\n\n // check if the collection is empty or optionally whether an array of pre-processed models is empty\n isEmpty(options) {\n let models;\n if (_.result(options, 'processedModels')) {\n models = options.processedModels;\n } else {\n models = this.collection ? this.collection.models : [];\n models = this._filterModels(models);\n }\n return models.length === 0;\n },\n\n // If empty, show the empty view\n _checkEmpty() {\n if (this.isEmpty()) {\n this._showEmptyView();\n }\n },\n\n // You might need to override this if you've overridden attachHtml\n attachBuffer(collectionView, buffer) {\n collectionView.$el.append(buffer);\n },\n\n // Create a fragment buffer from the currently buffered children\n _createBuffer() {\n const elBuffer = document.createDocumentFragment();\n _.each(this._bufferedChildren, (b) => {\n elBuffer.appendChild(b.el);\n });\n return elBuffer;\n },\n\n // Append the HTML to the collection's `el`. Override this method to do something other\n // than `.append`.\n attachHtml(collectionView, childView, index) {\n if (collectionView._isBuffering) {\n // buffering happens on reset events and initial renders\n // in order to reduce the number of inserts into the\n // document, which are expensive.\n collectionView._bufferedChildren.splice(index, 0, childView);\n } else {\n // If we've already rendered the main collection, append\n // the new child into the correct order if we need to. Otherwise\n // append to the end.\n if (!collectionView._insertBefore(childView, index)) {\n collectionView._insertAfter(childView);\n }\n }\n },\n\n // Internal method. Check whether we need to insert the view into the correct position.\n _insertBefore(childView, index) {\n let currentView;\n const findPosition = this.sort && (index < this.children.length - 1);\n if (findPosition) {\n // Find the view after this one\n currentView = this.children.find((view) => {\n return view._index === index + 1;\n });\n }\n\n if (currentView) {\n currentView.$el.before(childView.el);\n return true;\n }\n\n return false;\n },\n\n // Internal method. Append a view to the end of the $el\n _insertAfter(childView) {\n this.$el.append(childView.el);\n },\n\n // Internal method to set up the `children` object for storing all of the child views\n _initChildViewStorage() {\n this.children = new ChildViewContainer();\n },\n\n // called by ViewMixin destroy\n _removeChildren() {\n this._destroyChildren({checkEmpty: false});\n },\n\n // Destroy the child views that this collection view is holding on to, if any\n _destroyChildren(options) {\n if (!this.children.length) {\n return;\n }\n\n this.triggerMethod('before:destroy:children', this);\n const childModels = this.children.map('model');\n this._removeChildModels(childModels, options);\n this.triggerMethod('destroy:children', this);\n },\n\n // Return true if the given child should be shown. Return false otherwise.\n // The filter will be passed (child, index, collection), where\n // 'child' is the given model\n // 'index' is the index of that model in the collection\n // 'collection' is the collection referenced by this CollectionView\n _shouldAddChild(child, index) {\n const filter = this.filter;\n return !_.isFunction(filter) || filter.call(this, child, index, this.collection);\n },\n\n // Set up the child view event forwarding. Uses a \"childview:\" prefix in front of all forwarded events.\n _proxyChildEvents(view) {\n this.listenTo(view, 'all', this._childViewEventHandler);\n }\n});\n\n_.extend(CollectionView.prototype, ViewMixin);\n\nexport default CollectionView;\n","// Composite View\n// --------------\n\nimport _ from 'underscore';\nimport deprecate from './utils/deprecate';\nimport MarionetteError from './error';\nimport CollectionView from './collection-view';\nimport View from './view';\n\nconst ClassOptions = [\n 'childViewContainer',\n 'template',\n 'templateContext'\n];\n\n// Used for rendering a branch-leaf, hierarchical structure.\n// Extends directly from CollectionView\n// @deprecated\nconst CompositeView = CollectionView.extend({\n\n // Setting up the inheritance chain which allows changes to\n // Marionette.CollectionView.prototype.constructor which allows overriding\n // option to pass '{sort: false}' to prevent the CompositeView from\n // maintaining the sorted order of the collection.\n // This will fallback onto appending childView's to the end.\n constructor(options) {\n deprecate('CompositeView is deprecated. Convert to View at your earliest convenience');\n\n this.mergeOptions(options, ClassOptions);\n\n CollectionView.prototype.constructor.apply(this, arguments);\n },\n\n // Configured the initial events that the composite view\n // binds to. Override this method to prevent the initial\n // events, or to add your own initial events.\n _initialEvents() {\n\n // Bind only after composite view is rendered to avoid adding child views\n // to nonexistent childViewContainer\n\n if (this.collection) {\n this.listenTo(this.collection, 'add', this._onCollectionAdd);\n this.listenTo(this.collection, 'update', this._onCollectionUpdate);\n this.listenTo(this.collection, 'reset', this.renderChildren);\n\n if (this.sort) {\n this.listenTo(this.collection, 'sort', this._sortViews);\n }\n }\n },\n\n // Retrieve the `childView` to be used when rendering each of\n // the items in the collection. The default is to return\n // `this.childView` or Marionette.CompositeView if no `childView`\n // has been defined. As happens in CollectionView, `childView` can\n // be a function (which should return a view class).\n _getChildView(child) {\n let childView = this.childView;\n\n // for CompositeView, if `childView` is not specified, we'll get the same\n // composite view class rendered for each child in the collection\n // then check if the `childView` is a view class (the common case)\n // finally check if it's a function (which we assume that returns a view class)\n if (!childView) {\n return this.constructor;\n }\n\n childView = this._getView(childView, child);\n\n if (!childView) {\n throw new MarionetteError({\n name: 'InvalidChildViewError',\n message: '\"childView\" must be a view class or a function that returns a view class'\n });\n }\n\n return childView;\n },\n\n // Return the serialized model\n serializeData() {\n return this.serializeModel();\n },\n\n // Renders the model and the collection.\n render() {\n this._ensureViewIsIntact();\n this._isRendering = true;\n this.resetChildViewContainer();\n\n this.triggerMethod('before:render', this);\n\n this._renderTemplate();\n this.bindUIElements();\n this.renderChildren();\n\n this._isRendering = false;\n this._isRendered = true;\n this.triggerMethod('render', this);\n return this;\n },\n\n renderChildren() {\n if (this._isRendered || this._isRendering) {\n CollectionView.prototype._renderChildren.call(this);\n }\n },\n\n // You might need to override this if you've overridden attachHtml\n attachBuffer(compositeView, buffer) {\n const $container = this.getChildViewContainer(compositeView);\n $container.append(buffer);\n },\n\n // Internal method. Append a view to the end of the $el.\n // Overidden from CollectionView to ensure view is appended to\n // childViewContainer\n _insertAfter(childView) {\n const $container = this.getChildViewContainer(this, childView);\n $container.append(childView.el);\n },\n\n // Internal method. Append reordered childView'.\n // Overidden from CollectionView to ensure reordered views\n // are appended to childViewContainer\n _appendReorderedChildren(children) {\n const $container = this.getChildViewContainer(this);\n $container.append(children);\n },\n\n // Internal method to ensure an `$childViewContainer` exists, for the\n // `attachHtml` method to use.\n getChildViewContainer(containerView, childView) {\n if (!!containerView.$childViewContainer) {\n return containerView.$childViewContainer;\n }\n\n let container;\n const childViewContainer = containerView.childViewContainer;\n if (childViewContainer) {\n\n const selector = _.result(containerView, 'childViewContainer');\n\n if (selector.charAt(0) === '@' && containerView.ui) {\n container = containerView.ui[selector.substr(4)];\n } else {\n container = containerView.$(selector);\n }\n\n if (container.length <= 0) {\n throw new MarionetteError({\n name: 'ChildViewContainerMissingError',\n message: `The specified \"childViewContainer\" was not found: ${containerView.childViewContainer}`\n });\n }\n\n } else {\n container = containerView.$el;\n }\n\n containerView.$childViewContainer = container;\n return container;\n },\n\n // Internal method to reset the `$childViewContainer` on render\n resetChildViewContainer() {\n if (this.$childViewContainer) {\n this.$childViewContainer = undefined;\n }\n }\n});\n\n// To prevent duplication but allow the best View organization\n// Certain View methods are mixed directly into the deprecated CompositeView\nconst MixinFromView = _.pick(View.prototype, 'serializeModel', 'getTemplate', '_renderTemplate', 'mixinTemplateContext', 'attachElContent');\n_.extend(CompositeView.prototype, MixinFromView);\n\nexport default CompositeView;\n","// Behavior\n// --------\n\n// A Behavior is an isolated set of DOM /\n// user interactions that can be mixed into any View.\n// Behaviors allow you to blackbox View specific interactions\n// into portable logical chunks, keeping your views simple and your code DRY.\n\nimport _ from 'underscore';\nimport getUniqueEventName from './utils/get-unique-event-name';\nimport MarionetteObject from './object';\nimport DelegateEntityEventsMixin from './mixins/delegate-entity-events';\nimport TriggersMixin from './mixins/triggers';\nimport UIMixin from './mixins/ui';\n\nconst ClassOptions = [\n 'collectionEvents',\n 'events',\n 'modelEvents',\n 'triggers',\n 'ui'\n];\n\nconst Behavior = MarionetteObject.extend({\n cidPrefix: 'mnb',\n\n constructor(options, view) {\n // Setup reference to the view.\n // this comes in handle when a behavior\n // wants to directly talk up the chain\n // to the view.\n this.view = view;\n this.defaults = _.clone(_.result(this, 'defaults', {}));\n this._setOptions(this.defaults, options);\n this.mergeOptions(this.options, ClassOptions);\n\n // Construct an internal UI hash using\n // the behaviors UI hash and then the view UI hash.\n // This allows the user to use UI hash elements\n // defined in the parent view as well as those\n // defined in the given behavior.\n // This order will help the reuse and share of a behavior\n // between multiple views, while letting a view override a\n // selector under an UI key.\n this.ui = _.extend({}, _.result(this, 'ui'), _.result(view, 'ui'));\n\n MarionetteObject.apply(this, arguments);\n },\n\n // proxy behavior $ method to the view\n // this is useful for doing jquery DOM lookups\n // scoped to behaviors view.\n $() {\n return this.view.$.apply(this.view, arguments);\n },\n\n // Stops the behavior from listening to events.\n // Overrides Object#destroy to prevent additional events from being triggered.\n destroy() {\n this.stopListening();\n\n return this;\n },\n\n proxyViewProperties() {\n this.$el = this.view.$el;\n this.el = this.view.el;\n\n return this;\n },\n\n bindUIElements() {\n this._bindUIElements();\n\n return this;\n },\n\n unbindUIElements() {\n this._unbindUIElements();\n\n return this;\n },\n\n getUI(name) {\n this.view._ensureViewIsIntact();\n return this._getUI(name);\n },\n\n // Handle `modelEvents`, and `collectionEvents` configuration\n delegateEntityEvents() {\n this._delegateEntityEvents(this.view.model, this.view.collection);\n\n return this;\n },\n\n undelegateEntityEvents() {\n this._undelegateEntityEvents(this.view.model, this.view.collection);\n\n return this;\n },\n\n getEvents() {\n // Normalize behavior events hash to allow\n // a user to use the @ui. syntax.\n const behaviorEvents = this.normalizeUIKeys(_.result(this, 'events'));\n\n // binds the handler to the behavior and builds a unique eventName\n return _.reduce(behaviorEvents, (events, behaviorHandler, key) => {\n if (!_.isFunction(behaviorHandler)) {\n behaviorHandler = this[behaviorHandler];\n }\n if (!behaviorHandler) { return; }\n key = getUniqueEventName(key);\n events[key] = _.bind(behaviorHandler, this);\n return events;\n }, {});\n },\n\n // Internal method to build all trigger handlers for a given behavior\n getTriggers() {\n if (!this.triggers) { return; }\n\n // Normalize behavior triggers hash to allow\n // a user to use the @ui. syntax.\n const behaviorTriggers = this.normalizeUIKeys(_.result(this, 'triggers'));\n\n return this._getViewTriggers(this.view, behaviorTriggers);\n }\n\n});\n\n_.extend(Behavior.prototype, DelegateEntityEventsMixin, TriggersMixin, UIMixin);\n\nexport default Behavior;\n","// Application\n// -----------\nimport buildRegion from './common/build-region';\nimport MarionetteObject from './object';\nimport Region from './region';\n\nconst ClassOptions = [\n 'region',\n 'regionClass'\n];\n\n// A container for a Marionette application.\nconst Application = MarionetteObject.extend({\n cidPrefix: 'mna',\n\n constructor(options) {\n this._setOptions(options);\n\n this.mergeOptions(options, ClassOptions);\n\n this._initRegion();\n\n MarionetteObject.prototype.constructor.apply(this, arguments);\n },\n\n regionClass: Region,\n\n _initRegion() {\n const region = this.region;\n\n if (!region) { return; }\n\n const defaults = {\n regionClass: this.regionClass\n };\n\n this._region = buildRegion(region, defaults);\n },\n\n getRegion() {\n return this._region;\n },\n\n showView(view, ...args) {\n const region = this.getRegion();\n return region.show(view, ...args);\n },\n\n getView() {\n return this.getRegion().currentView;\n },\n\n // kick off all of the application's processes.\n start(options) {\n this.triggerMethod('before:start', this, options);\n this.triggerMethod('start', this, options);\n return this;\n }\n\n});\n\nexport default Application;\n","// App Router\n// ----------\n\n// Reduce the boilerplate code of handling route events\n// and then calling a single method on another object,\n// called a controller.\n// Have your routers configured to call the method on\n// your controller, directly.\n//\n// Configure an AppRouter with `appRoutes`.\n//\n// App routers can only take one `controller` object.\n// It is recommended that you divide your controller\n// objects in to smaller pieces of related functionality\n// and have multiple routers / controllers, instead of\n// just one giant router and controller.\n//\n// You can also add standard routes to an AppRouter.\n\nimport Backbone from 'backbone';\nimport _ from 'underscore';\nimport { triggerMethod } from './common/trigger-method';\nimport MarionetteError from './error';\nimport CommonMixin from './mixins/common';\n\nconst ClassOptions = [\n 'appRoutes',\n 'controller'\n];\n\nconst AppRouter = Backbone.Router.extend({\n\n constructor(options) {\n this._setOptions(options);\n\n this.mergeOptions(options, ClassOptions);\n\n Backbone.Router.apply(this, arguments);\n\n const appRoutes = this.appRoutes;\n const controller = this._getController();\n this.processAppRoutes(controller, appRoutes);\n this.on('route', this._processOnRoute, this);\n },\n\n // Similar to route method on a Backbone Router but\n // method is called on the controller\n appRoute(route, methodName) {\n const controller = this._getController();\n this._addAppRoute(controller, route, methodName);\n return this;\n },\n\n // process the route event and trigger the onRoute\n // method call, if it exists\n _processOnRoute(routeName, routeArgs) {\n // make sure an onRoute before trying to call it\n if (_.isFunction(this.onRoute)) {\n // find the path that matches the current route\n const routePath = _.invert(this.appRoutes)[routeName];\n this.onRoute(routeName, routePath, routeArgs);\n }\n },\n\n // Internal method to process the `appRoutes` for the\n // router, and turn them in to routes that trigger the\n // specified method on the specified `controller`.\n processAppRoutes(controller, appRoutes) {\n if (!appRoutes) { return this; }\n\n const routeNames = _.keys(appRoutes).reverse(); // Backbone requires reverted order of routes\n\n _.each(routeNames, route => {\n this._addAppRoute(controller, route, appRoutes[route]);\n });\n\n return this;\n },\n\n _getController() {\n return this.controller;\n },\n\n _addAppRoute(controller, route, methodName) {\n const method = controller[methodName];\n\n if (!method) {\n throw new MarionetteError(`Method \"${methodName}\" was not found on the controller`);\n }\n\n this.route(route, methodName, _.bind(method, controller));\n },\n\n triggerMethod: triggerMethod\n});\n\n_.extend(AppRouter.prototype, CommonMixin);\n\nexport default AppRouter;\n","import MarionetteError from '../error';\n\n// Placeholder method to be extended by the user.\n// The method should define the object that stores the behaviors.\n// i.e.\n//\n// ```js\n// Marionette.Behaviors.behaviorsLookup: function() {\n// return App.Behaviors\n// }\n// ```\nexport default function behaviorsLookup() {\n throw new MarionetteError({\n message: 'You must define where your behaviors are stored.',\n url: 'marionette.behaviors.md#behaviorslookup'\n });\n}\n","// Add Feature flags here\n// e.g. 'class' => false\nconst FEATURES = {\n};\n\nfunction isEnabled(name) {\n return !!FEATURES[name];\n}\n\nfunction setEnabled(name, state) {\n return FEATURES[name] = state;\n}\n\nexport {\n FEATURES,\n setEnabled,\n isEnabled\n};\n","import Backbone from 'backbone';\nimport {version} from '../package.json';\n\nimport proxy from './utils/proxy';\nimport extend from './utils/extend';\nimport deprecate from './utils/deprecate';\n\nimport isNodeAttached from './common/is-node-attached';\nimport mergeOptions from './common/merge-options';\nimport getOption from './common/get-option';\nimport normalizeMethods from './common/normalize-methods';\nimport monitorViewEvents from './common/monitor-view-events';\n\nimport {\n bindEvents,\n unbindEvents\n} from './common/bind-events';\n\nimport {\n bindRequests,\n unbindRequests\n} from './common/bind-requests';\n\nimport {\n triggerMethod,\n triggerMethodOn\n} from './common/trigger-method';\n\n\nimport MarionetteObject from './object';\nimport TemplateCache from './template-cache';\nimport View from './view';\nimport CollectionView from './collection-view';\nimport CompositeView from './composite-view';\nimport Behavior from './behavior';\nimport Region from './region';\nimport Application from './application';\nimport AppRouter from './app-router';\nimport MarionetteError from './error';\n\nimport behaviorsLookup from './config/behaviors-lookup';\nimport Renderer from './config/renderer';\n\nimport {\n FEATURES,\n isEnabled,\n setEnabled\n} from './config/features';\n\nconst previousMarionette = Backbone.Marionette;\nconst Marionette = Backbone.Marionette = {};\n\n// This allows you to run multiple instances of Marionette on the same\n// webapp. After loading the new version, call `noConflict()` to\n// get a reference to it. At the same time the old version will be\n// returned to Backbone.Marionette.\nMarionette.noConflict = function() {\n Backbone.Marionette = previousMarionette;\n return this;\n};\n\n// Utilities\nMarionette.bindEvents = proxy(bindEvents);\nMarionette.unbindEvents = proxy(unbindEvents);\nMarionette.bindRequests = proxy(bindRequests);\nMarionette.unbindRequests = proxy(unbindRequests);\nMarionette.mergeOptions = proxy(mergeOptions);\nMarionette.getOption = proxy(getOption);\nMarionette.normalizeMethods = proxy(normalizeMethods);\nMarionette.extend = extend;\nMarionette.isNodeAttached = isNodeAttached;\nMarionette.deprecate = deprecate;\nMarionette.triggerMethod = proxy(triggerMethod);\nMarionette.triggerMethodOn = triggerMethodOn;\nMarionette.isEnabled = isEnabled;\nMarionette.setEnabled = setEnabled;\nMarionette.monitorViewEvents = monitorViewEvents;\n\nMarionette.Behaviors = {};\nMarionette.Behaviors.behaviorsLookup = behaviorsLookup;\n\n// Classes\nMarionette.Application = Application;\nMarionette.AppRouter = AppRouter;\nMarionette.Renderer = Renderer;\nMarionette.TemplateCache = TemplateCache;\nMarionette.View = View;\nMarionette.CollectionView = CollectionView;\nMarionette.CompositeView = CompositeView;\nMarionette.Behavior = Behavior;\nMarionette.Region = Region;\nMarionette.Error = MarionetteError;\nMarionette.Object = MarionetteObject;\n\n// Configuration\nMarionette.DEV_MODE = false;\nMarionette.FEATURES = FEATURES;\nMarionette.VERSION = version;\n\nexport default Marionette;\n"],"names":["proxy","method","context","args","apply","extend","Backbone","Model","deprecate","message","test","_","isObject","prev","next","url","Marionette","DEV_MODE","undefined","_cache","_warn","_console","console","warn","log","noop","arguments","isNodeAttached","el","$","contains","document","documentElement","mergeOptions","options","keys","each","key","option","getOption","optionName","normalizeMethods","hash","reduce","normalizedHash","name","isFunction","splitter","getEventName","match","prefix","eventName","toUpperCase","getOnMethodName","memoize","event","replace","triggerMethod","methodName","call","result","trigger","triggerMethodOn","triggerMethodChildren","view","shouldTrigger","_getImmediateChildren","child","shouldTriggerAttach","_isAttached","shouldAttach","shouldTriggerDetach","shouldDetach","triggerDOMRefresh","_isRendered","handleBeforeAttach","handleAttach","handleBeforeDetach","handleDetach","handleRender","monitorViewEvents","_areViewEventsMonitored","on","errorProps","MarionetteError","Error","urlRoot","version","constructor","error","pick","captureStackTrace","toString","bindFromStrings","target","entity","evt","methods","actionName","methodNames","split","iterateEvents","bindings","isString","bindEvents","unbindEvents","iterateReplies","channel","normalizedRadioRequests","bindRequests","unbindRequests","setOptions","_setOptions","_initRadio","channelName","Radio","_channel","radioEvents","radioRequests","_destroyRadio","stopReplying","getChannel","ClassOptions","MarionetteObject","cid","uniqueId","cidPrefix","initialize","prototype","Events","CommonMixin","RadioMixin","_isDestroyed","isDestroyed","destroy","stopListening","TemplateCache","templateId","templateCaches","get","cachedTemplate","load","clear","i","length","compiledTemplate","template","loadTemplate","compileTemplate","$template","html","rawTemplate","invokeMap","invoke","getBehaviorClass","behaviorClass","Behaviors","behaviorsLookup","parseBehaviors","behaviors","chain","map","BehaviorClass","_options","behavior","nestedBehaviors","concat","flatten","value","_initBehaviors","_behaviors","_getBehaviorTriggers","triggers","_invoke","_getBehaviorEvents","events","_proxyBehaviorViewProperties","_delegateBehaviorEntityEvents","_undelegateBehaviorEntityEvents","_destroyBehaviors","_bindBehaviorUIElements","_unbindBehaviorUIElements","_triggerEventOnBehaviors","_delegateEntityEvents","model","collection","_undelegateEntityEvents","modelEvents","collectionEvents","delegateEventSplitter","uniqueName","selector","join","getUniqueEventName","buildViewTrigger","triggerDef","shouldPreventDefault","preventDefault","shouldStopPropagation","stopPropagation","e","_getViewTriggers","normalizeUIKeys","ui","memo","val","normalizedKey","normalizeUIString","uiString","r","slice","normalizeUIValues","properties","isArray","property","propertyVal","uiBindings","_getUIBindings","_bindUIElements","_uiBindings","_ui","_unbindUIElements","$el","_getUI","ViewMixin","supportsRenderLifecycle","supportsDestroyLifecycle","isRendered","isAttached","delegateEvents","eventsArg","_buildEventProxies","viewEvents","_getEvents","combinedEvents","getTriggers","View","delegateEntityEvents","undelegateEntityEvents","_ensureViewIsIntact","unbindUIElements","_removeElement","_removeChildren","bindUIElements","getUI","childViewEventPrefix","ret","_triggerEventOnParentLayout","_childViewEvents","_childViewTriggers","layoutView","_parentView","_childViewEventHandler","parent","_parent","childViewEvents","childViewTriggers","childEventName","BehaviorsMixin","DelegateEntityEventsMixin","TriggersMixin","UIMixin","destroyBackboneView","remove","Region","replaceElement","_isReplaced","_initEl","getEl","show","_ensureElement","_ensureView","currentView","empty","_empty","_renderView","_attachView","render","shouldReplaceEl","_replaceEl","attachHtml","allowMissingEl","_restoreEl","parentNode","replaceChild","isReplaced","appendChild","detachHtml","shouldDestroy","preventDestroy","off","_removeView","_detachView","detachView","contents","detach","hasView","reset","definition","defaults","buildRegionFromDefinition","opts","buildRegionFromObject","regionClass","RegionClass","omit","_initRegions","regions","_regions","addRegions","_reInitRegions","addRegion","isEmpty","_addRegions","regionDefinitions","parentEl","partial","buildRegion","_addRegion","region","removeRegion","_removeRegion","removeRegions","getRegions","bind","emptyRegions","hasRegion","getRegion","clone","showChildView","detachChildView","getChildView","Renderer","data","templateFunc","Array","serializeData","serializeModel","items","serializeCollection","attributes","setElement","hasEl","_renderTemplate","getTemplate","mixinTemplateContext","attachElContent","templateContext","compact","RegionsMixin","emulateCollection","object","listProperty","list","values","toArray","Container","views","_views","_indexByModel","_indexByCustom","_updateLength","add","customIndex","_add","viewCid","findByModel","findByModelCid","modelCid","findByCid","findByCustom","index","findByIndex","_remove","some","size","CollectionView","sort","once","_initialEvents","_initChildViewStorage","_bufferedChildren","_startBuffering","_isBuffering","_endBuffering","triggerOnChildren","attachBuffer","_createBuffer","children","listenTo","_onCollectionAdd","_onCollectionUpdate","_sortViews","at","indexOf","filter","_filteredSortedModels","_shouldAddChild","_destroyEmptyView","_addChild","changes","_removeChildModels","removed","models","checkEmpty","shouldCheckEmpty","removedViews","_getRemovedViews","_updateIndices","_checkEmpty","removingViews","_removeChildView","push","_findGreatestIndexedView","greatestIndexedView","_index","_renderChildren","setFilter","preventRender","canBeRendered","filterChanged","shouldRender","previousModels","_applyModelDeltas","removeFilter","currentIds","addedChildNotExists","removeModels","prevModel","reorder","_showingEmptyView","anyModelsAdded","filteredOutModels","elsToReorder","viewEls","_appendReorderedChildren","resortView","reorderOnSort","orderChanged","find","item","_emptyViewIndex","append","_destroyChildren","processedModels","_showEmptyView","_showCollection","_createView","ChildView","_getChildView","childViewOptions","_getChildViewOptions","buildChildView","_setupChildView","_proxyChildEvents","addedAt","viewComparator","getViewComparator","Math","min","max","addedModel","_sortModelsBy","splice","_filterModels","comparator","sortBy","EmptyView","_getEmptyView","emptyViewOptions","addChildView","emptyView","_getView","childView","increment","laterView","ChildViewClass","removeChildView","collectionView","buffer","elBuffer","createDocumentFragment","b","_insertBefore","_insertAfter","findPosition","before","ChildViewContainer","childModels","CompositeView","renderChildren","_isRendering","resetChildViewContainer","compositeView","$container","getChildViewContainer","containerView","$childViewContainer","container","childViewContainer","charAt","substr","MixinFromView","Behavior","proxyViewProperties","getEvents","behaviorEvents","behaviorHandler","behaviorTriggers","Application","_initRegion","_region","showView","getView","start","AppRouter","Router","appRoutes","controller","_getController","processAppRoutes","_processOnRoute","appRoute","route","_addAppRoute","routeName","routeArgs","onRoute","routePath","invert","routeNames","reverse","FEATURES","isEnabled","setEnabled","state","previousMarionette","noConflict","Object","VERSION"],"mappings":"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","sourceRoot":"/source/"} \ No newline at end of file
diff --git a/js/vendor/backbone.marionette/lib/backbone.marionette.min.js b/js/vendor/backbone.marionette/lib/backbone.marionette.min.js
new file mode 100644
index 000000000..7186b319d
--- /dev/null
+++ b/js/vendor/backbone.marionette/lib/backbone.marionette.min.js
@@ -0,0 +1,11 @@
+// MarionetteJS (Backbone.Marionette)
+// ----------------------------------
+// v3.1.0
+//
+// Copyright (c)2016 Derick Bailey, Muted Solutions, LLC.
+// Distributed under MIT license
+//
+// http://marionettejs.com
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("backbone"),require("underscore"),require("backbone.radio")):"function"==typeof define&&define.amd?define(["backbone","underscore","backbone.radio"],t):e.Marionette=e.Mn=t(e.Backbone,e._,e.Backbone.Radio)}(this,function(e,t,i){"use strict";function n(e,t,i){return i.toUpperCase()}function r(e){for(var i=arguments.length,n=Array(i>1?i-1:0),r=1;r<i;r++)n[r-1]=arguments[r];var s=K(e),o=q.call(this,s),h=void 0;return t.isFunction(o)&&(h=o.apply(this,n)),this.trigger.apply(this,arguments),h}function s(e){for(var i=arguments.length,n=Array(i>1?i-1:0),s=1;s<i;s++)n[s-1]=arguments[s];return t.isFunction(e.triggerMethod)?e.triggerMethod.apply(e,n):r.apply(e,n)}function o(e,i,n){e._getImmediateChildren&&t.each(e._getImmediateChildren(),function(e){n(e)&&s(e,i,e)})}function h(e){return!e._isAttached}function d(e){return!!h(e)&&(e._isAttached=!0,!0)}function a(e){return e._isAttached}function l(e){return!!a(e)&&(e._isAttached=!1,!0)}function c(e){e._isAttached&&e._isRendered&&s(e,"dom:refresh",e)}function u(){o(this,"before:attach",h)}function f(){o(this,"attach",d),c(this)}function p(){o(this,"before:detach",a)}function g(){o(this,"detach",l)}function _(){c(this)}function v(e){e._areViewEventsMonitored||(e._areViewEventsMonitored=!0,e.on({"before:attach":u,attach:f,"before:detach":p,detach:g,render:_}))}function m(e,i,n,r,s){var o=r.split(/\s+/);t.each(o,function(t){var r=e[t];if(!r)throw new Y('Method "'+t+'" was configured as an event handler, but does not exist.');e[s](i,n,r)})}function w(e,i,n,r){if(i&&n){if(!t.isObject(n))throw new Y({message:"Bindings must be an object.",url:"marionette.functions.html#marionettebindevents"});t.each(n,function(n,s){return t.isString(n)?void m(e,i,s,n,r):void e[r](i,s,n)})}}function y(e,t){return w(this,e,t,"listenTo"),this}function E(e,t){return w(this,e,t,"stopListening"),this}function V(e,i,n,r){if(i&&n){if(!t.isObject(n))throw new Y({message:"Bindings must be an object.",url:"marionette.functions.html#marionettebindrequests"});var s=N.call(e,n);i[r](s,e)}}function C(e,t){return V(this,e,t,"reply"),this}function b(e,t){return V(this,e,t,"stopReplying"),this}function M(e){if(Array.isArray(e)){for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}return Array.from(e)}function R(e,i){return e.behaviorClass?e.behaviorClass:t.isFunction(e)?e:t.isFunction(De.Behaviors.behaviorsLookup)?De.Behaviors.behaviorsLookup(e,i)[i]:De.Behaviors.behaviorsLookup[i]}function x(e,i){return t.chain(i).map(function(i,n){var r=R(i,n),s=i===r?{}:i,o=new r(s,e),h=x(e,t.result(o,"behaviors"));return[o].concat(h)}).flatten().value()}function B(e,i){return[e+t.uniqueId(".evt"),i].join(" ")}function I(e,i){t.isString(i)&&(i={event:i});var n=i.event,r=i.preventDefault!==!1,s=i.stopPropagation!==!1;return function(t){r&&t.preventDefault(),s&&t.stopPropagation(),e.triggerMethod(n,e)}}function A(e){e.supportsDestroyLifecycle||s(e,"before:destroy",e);var t=!!e._isAttached;t&&s(e,"before:detach",e),e.remove(),t&&(e._isAttached=!1,s(e,"detach",e)),e._isDestroyed=!0,e.supportsDestroyLifecycle||s(e,"destroy",e)}function O(e,t){return e instanceof fe?e:T(e,t)}function T(e,i){var n=t.extend({},i);if(t.isString(e))return t.extend(n,{el:e}),U(n);if(t.isFunction(e))return t.extend(n,{regionClass:e}),U(n);if(t.isObject(e))return e.selector&&F("The selector option on a Region definition object is deprecated. Use el to pass a selector string"),t.extend(n,{el:e.selector},e),U(n);throw new Y({message:"Improper region configuration type.",url:"marionette.region.html#region-configuration-types"})}function U(e){var i=e.regionClass,n=t.omit(e,"regionClass");return new i(n)}function D(){throw new Y({message:"You must define where your behaviors are stored.",url:"marionette.behaviors.md#behaviorslookup"})}function $(e){return!!Te[e]}function k(e,t){return Te[e]=t}e="default"in e?e.default:e,t="default"in t?t.default:t,i="default"in i?i.default:i;var S="3.1.0",z=function(e){return function(t){for(var i=arguments.length,n=Array(i>1?i-1:0),r=1;r<i;r++)n[r-1]=arguments[r];return e.apply(t,n)}},L=e.Model.extend,F=function e(i,n){t.isObject(i)&&(i=i.prev+" is going to be removed in the future. Please use "+i.next+" instead."+(i.url?" See: "+i.url:"")),De.DEV_MODE&&(void 0!==n&&n||e._cache[i]||(e._warn("Deprecation warning: "+i),e._cache[i]=!0))};F._console="undefined"!=typeof console?console:{},F._warn=function(){var e=F._console.warn||F._console.log||t.noop;return e.apply(F._console,arguments)},F._cache={};var P=function(t){return e.$.contains(document.documentElement,t)},j=function(e,i){var n=this;e&&t.each(i,function(t){var i=e[t];void 0!==i&&(n[t]=i)})},q=function(e){if(e)return this.options&&void 0!==this.options[e]?this.options[e]:this[e]},N=function(e){var i=this;return t.reduce(e,function(e,n,r){return t.isFunction(n)||(n=i[n]),n&&(e[r]=n),e},{})},H=/(^|:)(\w)/gi,K=t.memoize(function(e){return"on"+e.replace(H,n)}),G=["description","fileName","lineNumber","name","message","number"],Y=L.call(Error,{urlRoot:"http://marionettejs.com/docs/v"+S+"/",constructor:function(e,i){t.isObject(e)?(i=e,e=i.message):i||(i={});var n=Error.call(this,e);t.extend(this,t.pick(n,G),t.pick(i,G)),this.captureStackTrace(),i.url&&(this.url=this.urlRoot+i.url)},captureStackTrace:function(){Error.captureStackTrace&&Error.captureStackTrace(this,Y)},toString:function(){return this.name+": "+this.message+(this.url?" See: "+this.url:"")}});Y.extend=L;var Z=function(){for(var e=arguments.length,i=Array(e),n=0;n<e;n++)i[n]=arguments[n];this.options=t.extend.apply(t,[{},t.result(this,"options")].concat(i))},J={normalizeMethods:N,_setOptions:Z,mergeOptions:j,getOption:q,bindEvents:y,unbindEvents:E},Q={_initRadio:function(){var e=t.result(this,"channelName");if(e){if(!i)throw new Y({name:"BackboneRadioMissing",message:'The dependency "backbone.radio" is missing.'});var n=this._channel=i.channel(e),r=t.result(this,"radioEvents");this.bindEvents(n,r);var s=t.result(this,"radioRequests");this.bindRequests(n,s),this.on("destroy",this._destroyRadio)}},_destroyRadio:function(){this._channel.stopReplying(null,null,this)},getChannel:function(){return this._channel},bindEvents:y,unbindEvents:E,bindRequests:C,unbindRequests:b},W=["channelName","radioEvents","radioRequests"],X=function(e){this._setOptions(e),this.mergeOptions(e,W),this.cid=t.uniqueId(this.cidPrefix),this._initRadio(),this.initialize.apply(this,arguments)};X.extend=L,t.extend(X.prototype,e.Events,J,Q,{cidPrefix:"mno",_isDestroyed:!1,isDestroyed:function(){return this._isDestroyed},initialize:function(){},destroy:function(){if(this._isDestroyed)return this;for(var e=arguments.length,t=Array(e),i=0;i<e;i++)t[i]=arguments[i];return this.triggerMethod.apply(this,["before:destroy",this].concat(t)),this._isDestroyed=!0,this.triggerMethod.apply(this,["destroy",this].concat(t)),this.stopListening(),this},triggerMethod:r});var ee=function(e){this.templateId=e};t.extend(ee,{templateCaches:{},get:function(e,t){var i=this.templateCaches[e];return i||(i=new ee(e),this.templateCaches[e]=i),i.load(t)},clear:function(){for(var e=void 0,t=arguments.length,i=Array(t),n=0;n<t;n++)i[n]=arguments[n];var r=i.length;if(r>0)for(e=0;e<r;e++)delete this.templateCaches[i[e]];else this.templateCaches={}}}),t.extend(ee.prototype,{load:function(e){if(this.compiledTemplate)return this.compiledTemplate;var t=this.loadTemplate(this.templateId,e);return this.compiledTemplate=this.compileTemplate(t,e),this.compiledTemplate},loadTemplate:function(t,i){var n=e.$(t);if(!n.length)throw new Y({name:"NoTemplateError",message:'Could not find template: "'+t+'"'});return n.html()},compileTemplate:function(e,i){return t.template(e,i)}});var te=t.invokeMap||t.invoke,ie={_initBehaviors:function(){var e=t.result(this,"behaviors");this._behaviors=t.isObject(e)?x(this,e):{}},_getBehaviorTriggers:function(){var e=te(this._behaviors,"getTriggers");return t.extend.apply(t,[{}].concat(M(e)))},_getBehaviorEvents:function(){var e=te(this._behaviors,"getEvents");return t.extend.apply(t,[{}].concat(M(e)))},_proxyBehaviorViewProperties:function(){te(this._behaviors,"proxyViewProperties")},_delegateBehaviorEntityEvents:function(){te(this._behaviors,"delegateEntityEvents")},_undelegateBehaviorEntityEvents:function(){te(this._behaviors,"undelegateEntityEvents")},_destroyBehaviors:function(e){te.apply(void 0,[this._behaviors,"destroy"].concat(M(e)))},_bindBehaviorUIElements:function(){te(this._behaviors,"bindUIElements")},_unbindBehaviorUIElements:function(){te(this._behaviors,"unbindUIElements")},_triggerEventOnBehaviors:function(){for(var e=this._behaviors,t=0,i=e&&e.length;t<i;t++)r.apply(e[t],arguments)}},ne={_delegateEntityEvents:function(e,i){this._undelegateEntityEvents(e,i);var n=t.result(this,"modelEvents");y.call(this,e,n);var r=t.result(this,"collectionEvents");y.call(this,i,r)},_undelegateEntityEvents:function(e,i){var n=t.result(this,"modelEvents");E.call(this,e,n);var r=t.result(this,"collectionEvents");E.call(this,i,r)}},re=/^(\S+)\s*(.*)$/,se=function(e){var t=e.match(re);return B(t[1],t[2])},oe={_getViewTriggers:function(e,i){return t.reduce(i,function(t,i,n){return n=se(n),t[n]=I(e,i),t},{})}},he=function(e,i){return t.reduce(e,function(e,t,n){var r=de(n,i);return e[r]=t,e},{})},de=function(e,t){return e.replace(/@ui\.[a-zA-Z-_$0-9]*/g,function(e){return t[e.slice(4)]})},ae=function e(i,n,r){return t.each(i,function(s,o){t.isString(s)?i[o]=de(s,n):t.isObject(s)&&t.isArray(r)&&(t.extend(s,e(t.pick(s,r),n)),t.each(r,function(e){var i=s[e];t.isString(i)&&(s[e]=de(i,n))}))}),i},le={normalizeUIKeys:function(e){var t=this._getUIBindings();return he(e,t)},normalizeUIString:function(e){var t=this._getUIBindings();return de(e,t)},normalizeUIValues:function(e,t){var i=this._getUIBindings();return ae(e,i,t)},_getUIBindings:function(){var e=t.result(this,"_uiBindings"),i=t.result(this,"ui");return e||i},_bindUIElements:function(){var e=this;if(this.ui){this._uiBindings||(this._uiBindings=this.ui);var i=t.result(this,"_uiBindings");this._ui={},t.each(i,function(t,i){e._ui[i]=e.$(t)}),this.ui=this._ui}},_unbindUIElements:function(){var e=this;this.ui&&this._uiBindings&&(t.each(this.ui,function(t,i){delete e.ui[i]}),this.ui=this._uiBindings,delete this._uiBindings,delete this._ui)},_getUI:function(e){return this._ui[e]}},ce={supportsRenderLifecycle:!0,supportsDestroyLifecycle:!0,_isDestroyed:!1,isDestroyed:function(){return!!this._isDestroyed},_isRendered:!1,isRendered:function(){return!!this._isRendered},_isAttached:!1,isAttached:function(){return!!this._isAttached},delegateEvents:function(i){this._proxyBehaviorViewProperties(),this._buildEventProxies();var n=this._getEvents(i);"undefined"==typeof i&&(this.events=n);var r=t.extend({},this._getBehaviorEvents(),n,this._getBehaviorTriggers(),this.getTriggers());return e.View.prototype.delegateEvents.call(this,r),this},_getEvents:function(e){var i=e||this.events;return t.isFunction(i)?this.normalizeUIKeys(i.call(this)):this.normalizeUIKeys(i)},getTriggers:function(){if(this.triggers){var e=this.normalizeUIKeys(t.result(this,"triggers"));return this._getViewTriggers(this,e)}},delegateEntityEvents:function(){return this._delegateEntityEvents(this.model,this.collection),this._delegateBehaviorEntityEvents(),this},undelegateEntityEvents:function(){return this._undelegateEntityEvents(this.model,this.collection),this._undelegateBehaviorEntityEvents(),this},_ensureViewIsIntact:function(){if(this._isDestroyed)throw new Y({name:"ViewDestroyedError",message:'View (cid: "'+this.cid+'") has already been destroyed and cannot be used.'})},destroy:function(){if(this._isDestroyed)return this;for(var e=!!this._isAttached,t=arguments.length,i=Array(t),n=0;n<t;n++)i[n]=arguments[n];return this.triggerMethod.apply(this,["before:destroy",this].concat(i)),e&&this.triggerMethod("before:detach",this),this.unbindUIElements(),this._removeElement(),e&&(this._isAttached=!1,this.triggerMethod("detach",this)),this._removeChildren(),this._destroyBehaviors(i),this._isDestroyed=!0,this._isRendered=!1,this.triggerMethod.apply(this,["destroy",this].concat(i)),this.stopListening(),this},bindUIElements:function(){return this._bindUIElements(),this._bindBehaviorUIElements(),this},unbindUIElements:function(){return this._unbindUIElements(),this._unbindBehaviorUIElements(),this},getUI:function(e){return this._ensureViewIsIntact(),this._getUI(e)},childViewEventPrefix:"childview",triggerMethod:function(){var e=r.apply(this,arguments);return this._triggerEventOnBehaviors.apply(this,arguments),this._triggerEventOnParentLayout.apply(this,arguments),e},_buildEventProxies:function(){this._childViewEvents=t.result(this,"childViewEvents"),this._childViewTriggers=t.result(this,"childViewTriggers")},_triggerEventOnParentLayout:function(){var e=this._parentView();e&&e._childViewEventHandler.apply(e,arguments)},_parentView:function(){for(var e=this._parent;e;){if(e instanceof ve)return e;e=e._parent}},_childViewEventHandler:function(e){for(var i=this.normalizeMethods(this._childViewEvents),n=arguments.length,r=Array(n>1?n-1:0),s=1;s<n;s++)r[s-1]=arguments[s];"undefined"!=typeof i&&t.isFunction(i[e])&&i[e].apply(this,r);var o=this._childViewTriggers;o&&t.isString(o[e])&&this.triggerMethod.apply(this,[o[e]].concat(r));var h=t.result(this,"childViewEventPrefix");if(h!==!1){var d=h+":"+e;this.triggerMethod.apply(this,[d].concat(r))}}};t.extend(ce,ie,J,ne,oe,le);var ue=["allowMissingEl","parentEl","replaceElement"],fe=X.extend({cidPrefix:"mnr",replaceElement:!1,_isReplaced:!1,constructor:function(t){if(this._setOptions(t),this.mergeOptions(t,ue),this._initEl=this.el=this.getOption("el"),this.el=this.el instanceof e.$?this.el[0]:this.el,!this.el)throw new Y({name:"NoElError",message:'An "el" must be specified for a region.'});this.$el=this.getEl(this.el),X.call(this,t)},show:function(e,t){if(this._ensureElement(t))return this._ensureView(e),e===this.currentView?this:(this.triggerMethod("before:show",this,e,t),v(e),this.empty(t),e.on("destroy",this._empty,this),e._parent=this,this._renderView(e),this._attachView(e,t),this.triggerMethod("show",this,e,t),this)},_renderView:function(e){e._isRendered||(e.supportsRenderLifecycle||s(e,"before:render",e),e.render(),e.supportsRenderLifecycle||(e._isRendered=!0,s(e,"render",e)))},_attachView:function(e){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=!e._isAttached&&P(this.el),r="undefined"==typeof i.replaceElement?!!t.result(this,"replaceElement"):!!i.replaceElement;n&&s(e,"before:attach",e),r?this._replaceEl(e):this.attachHtml(e),n&&(e._isAttached=!0,s(e,"attach",e)),this.currentView=e},_ensureElement:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(t.isObject(this.el)||(this.$el=this.getEl(this.el),this.el=this.$el[0]),!this.$el||0===this.$el.length){var i="undefined"==typeof e.allowMissingEl?!!t.result(this,"allowMissingEl"):!!e.allowMissingEl;if(i)return!1;throw new Y('An "el" must exist in DOM for this region '+this.cid)}return!0},_ensureView:function(e){if(!e)throw new Y({name:"ViewNotValid",message:"The view passed is undefined and therefore invalid. You must pass a view instance to show."});if(e._isDestroyed)throw new Y({name:"ViewDestroyedError",message:'View (cid: "'+e.cid+'") has already been destroyed and cannot be used.'})},getEl:function(i){return e.$(i,t.result(this,"parentEl"))},_replaceEl:function(e){this._restoreEl();var t=this.el.parentNode;t.replaceChild(e.el,this.el),this._isReplaced=!0},_restoreEl:function(){if(this._isReplaced){var e=this.currentView;if(e){var t=e.el.parentNode;t&&(t.replaceChild(this.el,e.el),this._isReplaced=!1)}}},isReplaced:function(){return!!this._isReplaced},attachHtml:function(e){this.el.appendChild(e.el)},empty:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{allowMissingEl:!0},t=this.currentView;if(!t)return this._ensureElement(e)&&this.detachHtml(),this;var i=!e.preventDestroy;return i||F("The preventDestroy option is deprecated. Use Region#detachView"),this._empty(t,i),this},_empty:function(e,t){e.off("destroy",this._empty,this),this.triggerMethod("before:empty",this,e),this._restoreEl(),delete this.currentView,e._isDestroyed||(this._removeView(e,t),delete e._parent),this.triggerMethod("empty",this,e)},_removeView:function(e,t){return t?void(e.destroy?e.destroy():A(e)):void this._detachView(e)},detachView:function(){var e=this.currentView;if(e)return this._empty(e),e},_detachView:function(e){var t=!!e._isAttached;t&&s(e,"before:detach",e),this.detachHtml(),t&&(e._isAttached=!1,s(e,"detach",e))},detachHtml:function(){this.$el.contents().detach()},hasView:function(){return!!this.currentView},reset:function(e){return this.empty(e),this.$el&&(this.el=this._initEl),delete this.$el,this},destroy:function(e){return this.reset(e),X.prototype.destroy.apply(this,arguments)}}),pe={regionClass:fe,_initRegions:function(){this.regions=this.regions||{},this._regions={},this.addRegions(t.result(this,"regions"))},_reInitRegions:function(){te(this._regions,"reset")},addRegion:function(e,t){var i={};return i[e]=t,this.addRegions(i)[e]},addRegions:function(e){if(!t.isEmpty(e))return e=this.normalizeUIValues(e,["selector","el"]),this.regions=t.extend({},this.regions,e),this._addRegions(e)},_addRegions:function(e){var i=this,n={regionClass:this.regionClass,parentEl:t.partial(t.result,this,"el")};return t.reduce(e,function(e,t,r){return e[r]=O(t,n),i._addRegion(e[r],r),e},{})},_addRegion:function(e,t){this.triggerMethod("before:add:region",this,t,e),e._parent=this,this._regions[t]=e,this.triggerMethod("add:region",this,t,e)},removeRegion:function(e){var t=this._regions[e];return this._removeRegion(t,e),t},removeRegions:function(){var e=this.getRegions();return t.each(this._regions,t.bind(this._removeRegion,this)),e},_removeRegion:function(e,t){this.triggerMethod("before:remove:region",this,t,e),e.destroy(),delete this.regions[t],delete this._regions[t],this.triggerMethod("remove:region",this,t,e)},emptyRegions:function(){var e=this.getRegions();return te(e,"empty"),e},hasRegion:function(e){return!!this.getRegion(e)},getRegion:function(e){return this._regions[e]},getRegions:function(){return t.clone(this._regions)},showChildView:function(e,t){for(var i=this.getRegion(e),n=arguments.length,r=Array(n>2?n-2:0),s=2;s<n;s++)r[s-2]=arguments[s];return i.show.apply(i,[t].concat(r))},detachChildView:function(e){return this.getRegion(e).detachView()},getChildView:function(e){return this.getRegion(e).currentView}},ge={render:function(e,i){if(!e)throw new Y({name:"TemplateNotFoundError",message:"Cannot render the template since its false, null or undefined."});var n=t.isFunction(e)?e:ee.get(e);return n(i)}},_e=["behaviors","childViewEventPrefix","childViewEvents","childViewTriggers","collectionEvents","events","modelEvents","regionClass","regions","template","templateContext","triggers","ui"],ve=e.View.extend({constructor:function(i){this.render=t.bind(this.render,this),this._setOptions(i),this.mergeOptions(i,_e),v(this),this._initBehaviors(),this._initRegions();var n=Array.prototype.slice.call(arguments);n[0]=this.options,e.View.prototype.constructor.apply(this,n),this.delegateEntityEvents()},serializeData:function(){return this.model||this.collection?this.model?this.serializeModel():{items:this.serializeCollection()}:{}},serializeModel:function(){return this.model?t.clone(this.model.attributes):{}},serializeCollection:function(){return this.collection?this.collection.map(function(e){return t.clone(e.attributes)}):{}},setElement:function(){var t=!!this.el;return e.View.prototype.setElement.apply(this,arguments),t&&(this._isRendered=!!this.$el.length,this._isAttached=P(this.el)),this._isRendered&&this.bindUIElements(),this},render:function(){return this._ensureViewIsIntact(),this.triggerMethod("before:render",this),this._isRendered&&this._reInitRegions(),this._renderTemplate(),this.bindUIElements(),this._isRendered=!0,this.triggerMethod("render",this),this},_renderTemplate:function(){var e=this.getTemplate();if(e!==!1){var t=this.mixinTemplateContext(this.serializeData()),i=ge.render(e,t,this);this.attachElContent(i)}},getTemplate:function(){return this.template},mixinTemplateContext:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},i=t.result(this,"templateContext");return t.extend(e,i)},attachElContent:function(e){return this.$el.html(e),this},_removeChildren:function(){this.removeRegions()},_getImmediateChildren:function(){return t.chain(this.getRegions()).map("currentView").compact().value()}});t.extend(ve.prototype,ce,pe);var me=["forEach","each","map","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","toArray","first","initial","rest","last","without","isEmpty","pluck","reduce"],we=function(e,i){t.each(me,function(n){e[n]=function(){var e=t.values(t.result(this,i)),r=[e].concat(t.toArray(arguments));return t[n].apply(t,r)}})},ye=function(e){this._views={},this._indexByModel={},this._indexByCustom={},this._updateLength(),t.each(e,t.bind(this.add,this))};we(ye.prototype,"_views"),t.extend(ye.prototype,{add:function(e,t){return this._add(e,t)._updateLength()},_add:function(e,t){var i=e.cid;return this._views[i]=e,e.model&&(this._indexByModel[e.model.cid]=i),t&&(this._indexByCustom[t]=i),this},findByModel:function(e){return this.findByModelCid(e.cid)},findByModelCid:function(e){var t=this._indexByModel[e];return this.findByCid(t)},findByCustom:function(e){var t=this._indexByCustom[e];return this.findByCid(t)},findByIndex:function(e){return t.values(this._views)[e]},findByCid:function(e){return this._views[e]},remove:function(e){return this._remove(e)._updateLength()},_remove:function(e){var i=e.cid;return e.model&&delete this._indexByModel[e.model.cid],t.some(this._indexByCustom,t.bind(function(e,t){if(e===i)return delete this._indexByCustom[t],!0},this)),delete this._views[i],this},_updateLength:function(){return this.length=t.size(this._views),this}});var Ee=["behaviors","childView","childViewEventPrefix","childViewEvents","childViewOptions","childViewTriggers","collectionEvents","events","filter","emptyView","emptyViewOptions","modelEvents","reorderOnSort","sort","triggers","ui","viewComparator"],Ve=e.View.extend({sort:!0,constructor:function(i){this.render=t.bind(this.render,this),this._setOptions(i),this.mergeOptions(i,Ee),v(this),this._initBehaviors(),this.once("render",this._initialEvents),this._initChildViewStorage(),this._bufferedChildren=[];var n=Array.prototype.slice.call(arguments);n[0]=this.options,e.View.prototype.constructor.apply(this,n),this.delegateEntityEvents()},_startBuffering:function(){this._isBuffering=!0},_endBuffering:function(){var e=!!this._isAttached,i=e?this._getImmediateChildren():[];this._isBuffering=!1,t.each(i,function(e){s(e,"before:attach",e)}),this.attachBuffer(this,this._createBuffer()),t.each(i,function(e){e._isAttached=!0,s(e,"attach",e)}),this._bufferedChildren=[]},_getImmediateChildren:function(){return t.values(this.children._views)},_initialEvents:function(){this.collection&&(this.listenTo(this.collection,"add",this._onCollectionAdd),this.listenTo(this.collection,"update",this._onCollectionUpdate),this.listenTo(this.collection,"reset",this.render),this.sort&&this.listenTo(this.collection,"sort",this._sortViews))},_onCollectionAdd:function(e,i,n){var r=void 0!==n.at&&(n.index||i.indexOf(e));(this.filter||r===!1)&&(r=t.indexOf(this._filteredSortedModels(r),e)),this._shouldAddChild(e,r)&&(this._destroyEmptyView(),this._addChild(e,r))},_onCollectionUpdate:function(e,t){var i=t.changes;this._removeChildModels(i.removed)},_removeChildModels:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=t.checkEmpty,n=i!==!1,r=this._getRemovedViews(e);r.length&&(this.children._updateLength(),this._updateIndices(r,!1),n&&this._checkEmpty())},_getRemovedViews:function(e){var i=this;return t.reduce(e,function(e,t){var n=i.children.findByModel(t);return!n||n._isDestroyed?e:(i._removeChildView(n),e.push(n),e)},[])},_findGreatestIndexedView:function(e){return t.reduce(e,function(e,t){return!e||e._index<t._index?t:e},void 0)},_removeChildView:function(e){this.triggerMethod("before:remove:child",this,e),this.children._remove(e),e.destroy?e.destroy():A(e),delete e._parent,this.stopListening(e),this.triggerMethod("remove:child",this,e)},setElement:function(){var t=!!this.el;return e.View.prototype.setElement.apply(this,arguments),t&&(this._isAttached=P(this.el)),this},render:function(){return this._ensureViewIsIntact(),this.triggerMethod("before:render",this),this._renderChildren(),this._isRendered=!0,this.triggerMethod("render",this),this},setFilter:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=t.preventRender,n=this._isRendered&&!this._isDestroyed,r=this.filter!==e,s=n&&r&&!i;if(s){var o=this._filteredSortedModels();this.filter=e;var h=this._filteredSortedModels();this._applyModelDeltas(h,o)}else this.filter=e;return this},removeFilter:function(e){return this.setFilter(null,e)},_applyModelDeltas:function(e,i){var n=this,r={};t.each(e,function(e,t){var i=!n.children.findByModel(e);i&&n._onCollectionAdd(e,n.collection,{at:t}),r[e.cid]=!0});var s=t.filter(i,function(e){return!r[e.cid]&&n.children.findByModel(e)});this._removeChildModels(s)},reorder:function(){var e=this,i=this.children,n=this._filteredSortedModels();if(!n.length&&this._showingEmptyView)return this;var r=t.some(n,function(e){return!i.findByModel(e)});return r?this.render():!function(){var r=[],s=i.reduce(function(e,i){var s=t.indexOf(n,i.model);return s===-1?(r.push(i.model),e):(i._index=s,e[s]=i.el,e)},new Array(n.length));e.triggerMethod("before:reorder",e),e._appendReorderedChildren(s),e._removeChildModels(r),e.triggerMethod("reorder",e)}(),this},resortView:function(){return this.reorderOnSort?this.reorder():this._renderChildren(),this},_sortViews:function(){var e=this,i=this._filteredSortedModels(),n=t.find(i,function(t,i){var n=e.children.findByModel(t);return!n||n._index!==i});n&&this.resortView()},_emptyViewIndex:-1,_appendReorderedChildren:function(e){this.$el.append(e)},_renderChildren:function(){this._isRendered&&(this._destroyEmptyView(),this._destroyChildren({checkEmpty:!1}));var e=this._filteredSortedModels();this.isEmpty({processedModels:e})?this._showEmptyView():(this.triggerMethod("before:render:children",this),this._startBuffering(),this._showCollection(e),this._endBuffering(),this.triggerMethod("render:children",this))},_createView:function(e,t){var i=this._getChildView(e),n=this._getChildViewOptions(e,t),r=this.buildChildView(e,i,n);return r},_setupChildView:function(e,t){e._parent=this,v(e),this._proxyChildEvents(e),this.sort&&(e._index=t)},_showCollection:function(e){t.each(e,t.bind(this._addChild,this)),this.children._updateLength()},_filteredSortedModels:function(e){if(!this.collection||!this.collection.length)return[];var t=this.getViewComparator(),i=this.collection.models;if(e=Math.min(Math.max(e,0),i.length-1),t){var n=void 0;e&&(n=i[e],i=i.slice(0,e).concat(i.slice(e+1))),i=this._sortModelsBy(i,t),n&&i.splice(e,0,n)}return i=this._filterModels(i)},getViewComparator:function(){return this.viewComparator},_filterModels:function(e){var i=this;return this.filter&&(e=t.filter(e,function(e,t){return i._shouldAddChild(e,t)})),e},_sortModelsBy:function(e,i){return"string"==typeof i?t.sortBy(e,function(e){return e.get(i)}):1===i.length?t.sortBy(e,t.bind(i,this)):e.sort(t.bind(i,this))},_showEmptyView:function(){var i=this._getEmptyView();if(i&&!this._showingEmptyView){this._showingEmptyView=!0;var n=new e.Model,r=this.emptyViewOptions||this.childViewOptions;t.isFunction(r)&&(r=r.call(this,n,this._emptyViewIndex));var s=this.buildChildView(n,i,r);this.triggerMethod("before:render:empty",this,s),this.addChildView(s,0),this.triggerMethod("render:empty",this,s)}},_destroyEmptyView:function(){this._showingEmptyView&&(this.triggerMethod("before:remove:empty",this),this._destroyChildren(),delete this._showingEmptyView,this.triggerMethod("remove:empty",this))},_getEmptyView:function(){var e=this.emptyView;if(e)return this._getView(e)},_getChildView:function(e){var t=this.childView;if(!t)throw new Y({name:"NoChildViewError",message:'A "childView" must be specified'});if(t=this._getView(t,e),!t)throw new Y({name:"InvalidChildViewError",message:'"childView" must be a view class or a function that returns a view class'});return t},_getView:function(i,n){return i.prototype instanceof e.View||i===e.View?i:t.isFunction(i)?i.call(this,n):void 0},_addChild:function(e,t){var i=this._createView(e,t);return this.addChildView(i,t),i},_getChildViewOptions:function(e,i){return t.isFunction(this.childViewOptions)?this.childViewOptions(e,i):this.childViewOptions},addChildView:function(e,t){return this.triggerMethod("before:add:child",this,e),this._setupChildView(e,t),this._isBuffering?this.children._add(e):(this._updateIndices(e,!0),this.children.add(e)),this._renderView(e),this._attachView(e,t),this.triggerMethod("add:child",this,e),e},_updateIndices:function(e,i){if(this.sort){var n=t.isArray(e)?this._findGreatestIndexedView(e):e;this.children.each(function(e){e._index>=n._index&&(e._index+=i?1:-1)})}},_renderView:function(e){e._isRendered||(e.supportsRenderLifecycle||s(e,"before:render",e),e.render(),e.supportsRenderLifecycle||(e._isRendered=!0,s(e,"render",e)))},_attachView:function(e,t){var i=!e._isAttached&&!this._isBuffering&&this._isAttached;i&&s(e,"before:attach",e),this.attachHtml(this,e,t),i&&(e._isAttached=!0,s(e,"attach",e))},buildChildView:function(e,i,n){var r=t.extend({model:e},n);return new i(r)},removeChildView:function(e){return!e||e._isDestroyed?e:(this._removeChildView(e),this.children._updateLength(),this._updateIndices(e,!1),e)},isEmpty:function(e){var i=void 0;return t.result(e,"processedModels")?i=e.processedModels:(i=this.collection?this.collection.models:[],i=this._filterModels(i)),0===i.length},_checkEmpty:function(){this.isEmpty()&&this._showEmptyView()},attachBuffer:function(e,t){e.$el.append(t)},_createBuffer:function(){var e=document.createDocumentFragment();return t.each(this._bufferedChildren,function(t){e.appendChild(t.el)}),e},attachHtml:function(e,t,i){e._isBuffering?e._bufferedChildren.splice(i,0,t):e._insertBefore(t,i)||e._insertAfter(t)},_insertBefore:function(e,t){var i=void 0,n=this.sort&&t<this.children.length-1;return n&&(i=this.children.find(function(e){return e._index===t+1})),!!i&&(i.$el.before(e.el),!0)},_insertAfter:function(e){this.$el.append(e.el)},_initChildViewStorage:function(){this.children=new ye},_removeChildren:function(){this._destroyChildren({checkEmpty:!1})},_destroyChildren:function(e){if(this.children.length){this.triggerMethod("before:destroy:children",this);var t=this.children.map("model");this._removeChildModels(t,e),this.triggerMethod("destroy:children",this)}},_shouldAddChild:function(e,i){var n=this.filter;return!t.isFunction(n)||n.call(this,e,i,this.collection)},_proxyChildEvents:function(e){this.listenTo(e,"all",this._childViewEventHandler)}});t.extend(Ve.prototype,ce);var Ce=["childViewContainer","template","templateContext"],be=Ve.extend({constructor:function(e){F("CompositeView is deprecated. Convert to View at your earliest convenience"),this.mergeOptions(e,Ce),Ve.prototype.constructor.apply(this,arguments)},_initialEvents:function(){this.collection&&(this.listenTo(this.collection,"add",this._onCollectionAdd),this.listenTo(this.collection,"update",this._onCollectionUpdate),this.listenTo(this.collection,"reset",this.renderChildren),this.sort&&this.listenTo(this.collection,"sort",this._sortViews))},_getChildView:function(e){var t=this.childView;if(!t)return this.constructor;if(t=this._getView(t,e),!t)throw new Y({name:"InvalidChildViewError",message:'"childView" must be a view class or a function that returns a view class'});return t},serializeData:function(){return this.serializeModel()},render:function(){return this._ensureViewIsIntact(),this._isRendering=!0,
+this.resetChildViewContainer(),this.triggerMethod("before:render",this),this._renderTemplate(),this.bindUIElements(),this.renderChildren(),this._isRendering=!1,this._isRendered=!0,this.triggerMethod("render",this),this},renderChildren:function(){(this._isRendered||this._isRendering)&&Ve.prototype._renderChildren.call(this)},attachBuffer:function(e,t){var i=this.getChildViewContainer(e);i.append(t)},_insertAfter:function(e){var t=this.getChildViewContainer(this,e);t.append(e.el)},_appendReorderedChildren:function(e){var t=this.getChildViewContainer(this);t.append(e)},getChildViewContainer:function(e,i){if(e.$childViewContainer)return e.$childViewContainer;var n=void 0,r=e.childViewContainer;if(r){var s=t.result(e,"childViewContainer");if(n="@"===s.charAt(0)&&e.ui?e.ui[s.substr(4)]:e.$(s),n.length<=0)throw new Y({name:"ChildViewContainerMissingError",message:'The specified "childViewContainer" was not found: '+e.childViewContainer})}else n=e.$el;return e.$childViewContainer=n,n},resetChildViewContainer:function(){this.$childViewContainer&&(this.$childViewContainer=void 0)}}),Me=t.pick(ve.prototype,"serializeModel","getTemplate","_renderTemplate","mixinTemplateContext","attachElContent");t.extend(be.prototype,Me);var Re=["collectionEvents","events","modelEvents","triggers","ui"],xe=X.extend({cidPrefix:"mnb",constructor:function(e,i){this.view=i,this.defaults=t.clone(t.result(this,"defaults",{})),this._setOptions(this.defaults,e),this.mergeOptions(this.options,Re),this.ui=t.extend({},t.result(this,"ui"),t.result(i,"ui")),X.apply(this,arguments)},$:function(){return this.view.$.apply(this.view,arguments)},destroy:function(){return this.stopListening(),this},proxyViewProperties:function(){return this.$el=this.view.$el,this.el=this.view.el,this},bindUIElements:function(){return this._bindUIElements(),this},unbindUIElements:function(){return this._unbindUIElements(),this},getUI:function(e){return this.view._ensureViewIsIntact(),this._getUI(e)},delegateEntityEvents:function(){return this._delegateEntityEvents(this.view.model,this.view.collection),this},undelegateEntityEvents:function(){return this._undelegateEntityEvents(this.view.model,this.view.collection),this},getEvents:function(){var e=this,i=this.normalizeUIKeys(t.result(this,"events"));return t.reduce(i,function(i,n,r){if(t.isFunction(n)||(n=e[n]),n)return r=se(r),i[r]=t.bind(n,e),i},{})},getTriggers:function(){if(this.triggers){var e=this.normalizeUIKeys(t.result(this,"triggers"));return this._getViewTriggers(this.view,e)}}});t.extend(xe.prototype,ne,oe,le);var Be=["region","regionClass"],Ie=X.extend({cidPrefix:"mna",constructor:function(e){this._setOptions(e),this.mergeOptions(e,Be),this._initRegion(),X.prototype.constructor.apply(this,arguments)},regionClass:fe,_initRegion:function(){var e=this.region;if(e){var t={regionClass:this.regionClass};this._region=O(e,t)}},getRegion:function(){return this._region},showView:function(e){for(var t=this.getRegion(),i=arguments.length,n=Array(i>1?i-1:0),r=1;r<i;r++)n[r-1]=arguments[r];return t.show.apply(t,[e].concat(n))},getView:function(){return this.getRegion().currentView},start:function(e){return this.triggerMethod("before:start",this,e),this.triggerMethod("start",this,e),this}}),Ae=["appRoutes","controller"],Oe=e.Router.extend({constructor:function(t){this._setOptions(t),this.mergeOptions(t,Ae),e.Router.apply(this,arguments);var i=this.appRoutes,n=this._getController();this.processAppRoutes(n,i),this.on("route",this._processOnRoute,this)},appRoute:function(e,t){var i=this._getController();return this._addAppRoute(i,e,t),this},_processOnRoute:function(e,i){if(t.isFunction(this.onRoute)){var n=t.invert(this.appRoutes)[e];this.onRoute(e,n,i)}},processAppRoutes:function(e,i){var n=this;if(!i)return this;var r=t.keys(i).reverse();return t.each(r,function(t){n._addAppRoute(e,t,i[t])}),this},_getController:function(){return this.controller},_addAppRoute:function(e,i,n){var r=e[n];if(!r)throw new Y('Method "'+n+'" was not found on the controller');this.route(i,n,t.bind(r,e))},triggerMethod:r});t.extend(Oe.prototype,J);var Te={},Ue=e.Marionette,De=e.Marionette={};return De.noConflict=function(){return e.Marionette=Ue,this},De.bindEvents=z(y),De.unbindEvents=z(E),De.bindRequests=z(C),De.unbindRequests=z(b),De.mergeOptions=z(j),De.getOption=z(q),De.normalizeMethods=z(N),De.extend=L,De.isNodeAttached=P,De.deprecate=F,De.triggerMethod=z(r),De.triggerMethodOn=s,De.isEnabled=$,De.setEnabled=k,De.monitorViewEvents=v,De.Behaviors={},De.Behaviors.behaviorsLookup=D,De.Application=Ie,De.AppRouter=Oe,De.Renderer=ge,De.TemplateCache=ee,De.View=ve,De.CollectionView=Ve,De.CompositeView=be,De.Behavior=xe,De.Region=fe,De.Error=Y,De.Object=X,De.DEV_MODE=!1,De.FEATURES=Te,De.VERSION=S,De});
+//# sourceMappingURL=backbone.marionette.min.js.map
diff --git a/js/vendor/backbone.marionette/lib/backbone.marionette.min.js.map b/js/vendor/backbone.marionette/lib/backbone.marionette.min.js.map
new file mode 100644
index 000000000..e2410f49b
--- /dev/null
+++ b/js/vendor/backbone.marionette/lib/backbone.marionette.min.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["/source/src/common/trigger-method.js","/source/src/common/monitor-view-events.js","/source/src/common/bind-events.js","/source/src/common/bind-requests.js","/source/src/mixins/behaviors.js","/source/src/utils/get-unique-event-name.js","/source/src/mixins/triggers.js","/source/src/utils/destroy-backbone-view.js","/source/src/common/build-region.js","/source/src/config/behaviors-lookup.js","/source/src/config/features.js","/source/src/utils/proxy.js","/source/src/utils/extend.js","/source/src/utils/deprecate.js","/source/src/common/is-node-attached.js","/source/src/common/merge-options.js","/source/src/common/get-option.js","/source/src/common/normalize-methods.js","/source/src/error.js","/source/src/utils/set-options.js","/source/src/mixins/common.js","/source/src/mixins/radio.js","/source/src/object.js","/source/src/template-cache.js","/source/src/utils/invoke.js","/source/src/mixins/delegate-entity-events.js","/source/src/mixins/ui.js","/source/src/mixins/view.js","/source/src/region.js","/source/src/mixins/regions.js","/source/src/config/renderer.js","/source/src/view.js","/source/src/utils/emulate-collection.js","/source/src/child-view-container.js","/source/src/collection-view.js","/source/src/composite-view.js","/source/src/behavior.js","/source/src/application.js","/source/src/app-router.js","/source/src/backbone.marionette.js"],"names":["getEventName","match","prefix","eventName","toUpperCase","triggerMethod","event","_len","arguments","length","args","Array","_key","methodName","getOnMethodName","method","getOption","call","this","result","_","isFunction","apply","trigger","triggerMethodOn","context","_len2","_key2","triggerMethodChildren","view","shouldTrigger","_getImmediateChildren","each","child","shouldTriggerAttach","_isAttached","shouldAttach","shouldTriggerDetach","shouldDetach","triggerDOMRefresh","_isRendered","handleBeforeAttach","handleAttach","handleBeforeDetach","handleDetach","handleRender","monitorViewEvents","_areViewEventsMonitored","on","before:attach","attach","before:detach","detach","render","bindFromStrings","target","entity","evt","methods","actionName","methodNames","split","MarionetteError","iterateEvents","bindings","isObject","message","url","isString","bindEvents","unbindEvents","iterateReplies","channel","normalizedRadioRequests","normalizeMethods","bindRequests","unbindRequests","getBehaviorClass","options","key","behaviorClass","Marionette","Behaviors","behaviorsLookup","parseBehaviors","behaviors","chain","map","BehaviorClass","_options","behavior","nestedBehaviors","concat","flatten","value","uniqueName","selector","uniqueId","join","buildViewTrigger","triggerDef","shouldPreventDefault","preventDefault","shouldStopPropagation","stopPropagation","e","destroyBackboneView","supportsDestroyLifecycle","remove","_isDestroyed","buildRegion","definition","defaults","Region","buildRegionFromDefinition","opts","extend","el","buildRegionFromObject","regionClass","deprecate","RegionClass","omit","isEnabled","name","FEATURES","setEnabled","state","proxy","Backbone","Model","test","prev","next","DEV_MODE","undefined","_cache","_warn","_console","console","warn","log","noop","isNodeAttached","$","contains","document","documentElement","mergeOptions","keys","_this","option","optionName","hash","reduce","normalizedHash","splitter","memoize","replace","errorProps","Error","urlRoot","version","constructor","error","pick","captureStackTrace","toString","setOptions","CommonMixin","_setOptions","RadioMixin","_initRadio","channelName","Radio","_channel","radioEvents","radioRequests","_destroyRadio","stopReplying","getChannel","ClassOptions","MarionetteObject","cid","cidPrefix","initialize","prototype","Events","isDestroyed","destroy","stopListening","TemplateCache","templateId","templateCaches","get","cachedTemplate","load","clear","i","compiledTemplate","template","loadTemplate","compileTemplate","$template","html","rawTemplate","_invoke","invokeMap","invoke","BehaviorsMixin","_initBehaviors","_behaviors","_getBehaviorTriggers","triggers","_toConsumableArray","_getBehaviorEvents","events","_proxyBehaviorViewProperties","_delegateBehaviorEntityEvents","_undelegateBehaviorEntityEvents","_destroyBehaviors","_bindBehaviorUIElements","_unbindBehaviorUIElements","_triggerEventOnBehaviors","DelegateEntityEventsMixin","_delegateEntityEvents","model","collection","_undelegateEntityEvents","modelEvents","collectionEvents","delegateEventSplitter","getUniqueEventName","TriggersMixin","_getViewTriggers","normalizeUIKeys","ui","memo","val","normalizedKey","normalizeUIString","uiString","r","slice","normalizeUIValues","properties","isArray","property","propertyVal","UIMixin","uiBindings","_getUIBindings","_bindUIElements","_uiBindings","_ui","_unbindUIElements","_this2","$el","_getUI","ViewMixin","supportsRenderLifecycle","isRendered","isAttached","delegateEvents","eventsArg","_buildEventProxies","viewEvents","_getEvents","combinedEvents","getTriggers","View","delegateEntityEvents","undelegateEntityEvents","_ensureViewIsIntact","unbindUIElements","_removeElement","_removeChildren","bindUIElements","getUI","childViewEventPrefix","ret","_triggerEventOnParentLayout","_childViewEvents","_childViewTriggers","layoutView","_parentView","_childViewEventHandler","parent","_parent","childViewEvents","childViewTriggers","childEventName","replaceElement","_isReplaced","_initEl","getEl","show","_ensureElement","_ensureView","currentView","empty","_empty","_renderView","_attachView","shouldReplaceEl","_replaceEl","attachHtml","allowMissingEl","_restoreEl","parentNode","replaceChild","isReplaced","appendChild","detachHtml","shouldDestroy","preventDestroy","off","_removeView","_detachView","detachView","contents","hasView","reset","RegionsMixin","_initRegions","regions","_regions","addRegions","_reInitRegions","addRegion","isEmpty","_addRegions","regionDefinitions","parentEl","partial","_addRegion","region","removeRegion","_removeRegion","removeRegions","getRegions","bind","emptyRegions","hasRegion","getRegion","clone","showChildView","detachChildView","getChildView","Renderer","data","templateFunc","serializeData","serializeModel","items","serializeCollection","attributes","setElement","hasEl","_renderTemplate","getTemplate","mixinTemplateContext","attachElContent","templateContext","compact","emulateCollection","object","listProperty","list","values","toArray","Container","views","_views","_indexByModel","_indexByCustom","_updateLength","add","customIndex","_add","viewCid","findByModel","findByModelCid","modelCid","findByCid","findByCustom","index","findByIndex","_remove","some","size","CollectionView","sort","once","_initialEvents","_initChildViewStorage","_bufferedChildren","_startBuffering","_isBuffering","_endBuffering","triggerOnChildren","attachBuffer","_createBuffer","children","listenTo","_onCollectionAdd","_onCollectionUpdate","_sortViews","at","indexOf","filter","_filteredSortedModels","_shouldAddChild","_destroyEmptyView","_addChild","changes","_removeChildModels","removed","models","_ref","checkEmpty","shouldCheckEmpty","removedViews","_getRemovedViews","_updateIndices","_checkEmpty","removingViews","_removeChildView","push","_findGreatestIndexedView","greatestIndexedView","_index","_renderChildren","setFilter","_ref2","preventRender","canBeRendered","filterChanged","shouldRender","previousModels","_applyModelDeltas","removeFilter","currentIds","addedChildNotExists","removeModels","prevModel","reorder","_this3","_showingEmptyView","anyModelsAdded","filteredOutModels","elsToReorder","viewEls","_appendReorderedChildren","resortView","reorderOnSort","_this4","orderChanged","find","item","_emptyViewIndex","append","_destroyChildren","processedModels","_showEmptyView","_showCollection","_createView","ChildView","_getChildView","childViewOptions","_getChildViewOptions","buildChildView","_setupChildView","_proxyChildEvents","addedAt","viewComparator","getViewComparator","Math","min","max","addedModel","_sortModelsBy","splice","_filterModels","_this5","comparator","sortBy","EmptyView","_getEmptyView","emptyViewOptions","addChildView","emptyView","_getView","childView","increment","laterView","ChildViewClass","removeChildView","collectionView","buffer","elBuffer","createDocumentFragment","b","_insertBefore","_insertAfter","findPosition","before","ChildViewContainer","childModels","CompositeView","renderChildren","_isRendering","resetChildViewContainer","compositeView","$container","getChildViewContainer","containerView","$childViewContainer","container","childViewContainer","charAt","substr","MixinFromView","Behavior","proxyViewProperties","getEvents","behaviorEvents","behaviorHandler","behaviorTriggers","Application","_initRegion","_region","showView","getView","start","AppRouter","Router","appRoutes","controller","_getController","processAppRoutes","_processOnRoute","appRoute","route","_addAppRoute","routeName","routeArgs","onRoute","routePath","invert","routeNames","reverse","previousMarionette","noConflict","Object","VERSION"],"mappings":"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","file":"backbone.marionette.min.js","sourcesContent":["// Trigger Method\n// --------------\n\nimport _ from 'underscore';\nimport getOption from './get-option';\n\n// split the event name on the \":\"\nconst splitter = /(^|:)(\\w)/gi;\n\n// take the event section (\"section1:section2:section3\")\n// and turn it in to uppercase name onSection1Section2Section3\nfunction getEventName(match, prefix, eventName) {\n return eventName.toUpperCase();\n}\n\nconst getOnMethodName = _.memoize(function(event) {\n return 'on' + event.replace(splitter, getEventName);\n});\n\n// Trigger an event and/or a corresponding method name. Examples:\n//\n// `this.triggerMethod(\"foo\")` will trigger the \"foo\" event and\n// call the \"onFoo\" method.\n//\n// `this.triggerMethod(\"foo:bar\")` will trigger the \"foo:bar\" event and\n// call the \"onFooBar\" method.\nexport function triggerMethod(event, ...args) {\n // get the method name from the event name\n const methodName = getOnMethodName(event);\n const method = getOption.call(this, methodName);\n let result;\n\n // call the onMethodName if it exists\n if (_.isFunction(method)) {\n // pass all args, except the event name\n result = method.apply(this, args);\n }\n\n // trigger the event\n this.trigger.apply(this, arguments);\n\n return result;\n}\n\n// triggerMethodOn invokes triggerMethod on a specific context\n//\n// e.g. `Marionette.triggerMethodOn(view, 'show')`\n// will trigger a \"show\" event or invoke onShow the view.\nexport function triggerMethodOn(context, ...args) {\n if (_.isFunction(context.triggerMethod)) {\n return context.triggerMethod.apply(context, args);\n }\n\n return triggerMethod.apply(context, args);\n}\n","// DOM Refresh\n// -----------\n\nimport _ from 'underscore';\nimport { triggerMethodOn } from './trigger-method';\n\n// Trigger method on children unless a pure Backbone.View\nfunction triggerMethodChildren(view, event, shouldTrigger) {\n if (!view._getImmediateChildren) { return; }\n _.each(view._getImmediateChildren(), child => {\n if (!shouldTrigger(child)) { return; }\n triggerMethodOn(child, event, child);\n });\n}\n\nfunction shouldTriggerAttach(view) {\n return !view._isAttached;\n}\n\nfunction shouldAttach(view) {\n if (!shouldTriggerAttach(view)) { return false; }\n view._isAttached = true;\n return true;\n}\n\nfunction shouldTriggerDetach(view) {\n return view._isAttached;\n}\n\nfunction shouldDetach(view) {\n if (!shouldTriggerDetach(view)) { return false; }\n view._isAttached = false;\n return true;\n}\n\nfunction triggerDOMRefresh(view) {\n if (view._isAttached && view._isRendered) {\n triggerMethodOn(view, 'dom:refresh', view);\n }\n}\n\nfunction handleBeforeAttach() {\n triggerMethodChildren(this, 'before:attach', shouldTriggerAttach);\n}\n\nfunction handleAttach() {\n triggerMethodChildren(this, 'attach', shouldAttach);\n triggerDOMRefresh(this);\n}\n\nfunction handleBeforeDetach() {\n triggerMethodChildren(this, 'before:detach', shouldTriggerDetach);\n}\n\nfunction handleDetach() {\n triggerMethodChildren(this, 'detach', shouldDetach);\n}\n\nfunction handleRender() {\n triggerDOMRefresh(this);\n}\n\n// Monitor a view's state, propagating attach/detach events to children and firing dom:refresh\n// whenever a rendered view is attached or an attached view is rendered.\nfunction monitorViewEvents(view) {\n if (view._areViewEventsMonitored) { return; }\n\n view._areViewEventsMonitored = true;\n\n view.on({\n 'before:attach': handleBeforeAttach,\n 'attach': handleAttach,\n 'before:detach': handleBeforeDetach,\n 'detach': handleDetach,\n 'render': handleRender\n });\n}\n\nexport default monitorViewEvents;\n","// Bind Entity Events & Unbind Entity Events\n// -----------------------------------------\n//\n// These methods are used to bind/unbind a backbone \"entity\" (e.g. collection/model)\n// to methods on a target object.\n//\n// The first parameter, `target`, must have the Backbone.Events module mixed in.\n//\n// The second parameter is the `entity` (Backbone.Model, Backbone.Collection or\n// any object that has Backbone.Events mixed in) to bind the events from.\n//\n// The third parameter is a hash of { \"event:name\": \"eventHandler\" }\n// configuration. Multiple handlers can be separated by a space. A\n// function can be supplied instead of a string handler name.\n\nimport _ from 'underscore';\nimport MarionetteError from '../error';\n\n// Bind/unbind the event to handlers specified as a string of\n// handler names on the target object\nfunction bindFromStrings(target, entity, evt, methods, actionName) {\n const methodNames = methods.split(/\\s+/);\n\n _.each(methodNames, function(methodName) {\n const method = target[methodName];\n if (!method) {\n throw new MarionetteError(`Method \"${methodName}\" was configured as an event handler, but does not exist.`);\n }\n\n target[actionName](entity, evt, method);\n });\n}\n\n// generic looping function\nfunction iterateEvents(target, entity, bindings, actionName) {\n if (!entity || !bindings) { return; }\n\n // type-check bindings\n if (!_.isObject(bindings)) {\n throw new MarionetteError({\n message: 'Bindings must be an object.',\n url: 'marionette.functions.html#marionettebindevents'\n });\n }\n\n // iterate the bindings and bind/unbind them\n _.each(bindings, function(method, evt) {\n\n // allow for a list of method names as a string\n if (_.isString(method)) {\n bindFromStrings(target, entity, evt, method, actionName);\n return;\n }\n\n target[actionName](entity, evt, method);\n });\n}\n\nfunction bindEvents(entity, bindings) {\n iterateEvents(this, entity, bindings, 'listenTo');\n return this;\n}\n\nfunction unbindEvents(entity, bindings) {\n iterateEvents(this, entity, bindings, 'stopListening');\n return this;\n}\n\n// Export Public API\nexport {\n bindEvents,\n unbindEvents\n};\n","// Bind/Unbind Radio Requests\n// -----------------------------------------\n//\n// These methods are used to bind/unbind a backbone.radio request\n// to methods on a target object.\n//\n// The first parameter, `target`, will set the context of the reply method\n//\n// The second parameter is the `Radio.channel` to bind the reply to.\n//\n// The third parameter is a hash of { \"request:name\": \"replyHandler\" }\n// configuration. A function can be supplied instead of a string handler name.\n\nimport _ from 'underscore';\nimport normalizeMethods from './normalize-methods';\nimport MarionetteError from '../error';\n\nfunction iterateReplies(target, channel, bindings, actionName) {\n if (!channel || !bindings) { return; }\n\n // type-check bindings\n if (!_.isObject(bindings)) {\n throw new MarionetteError({\n message: 'Bindings must be an object.',\n url: 'marionette.functions.html#marionettebindrequests'\n });\n }\n\n const normalizedRadioRequests = normalizeMethods.call(target, bindings);\n\n channel[actionName](normalizedRadioRequests, target);\n}\n\nfunction bindRequests(channel, bindings) {\n iterateReplies(this, channel, bindings, 'reply');\n return this;\n}\n\nfunction unbindRequests(channel, bindings) {\n iterateReplies(this, channel, bindings, 'stopReplying');\n return this;\n}\n\nexport {\n bindRequests,\n unbindRequests\n};\n","import _ from 'underscore';\nimport _invoke from '../utils/invoke';\nimport { triggerMethod } from '../common/trigger-method';\nimport Marionette from '../backbone.marionette';\n\n// MixinOptions\n// - behaviors\n\n// Takes care of getting the behavior class\n// given options and a key.\n// If a user passes in options.behaviorClass\n// default to using that.\n// If a user passes in a Behavior Class directly, use that\n// Otherwise delegate the lookup to the users `behaviorsLookup` implementation.\nfunction getBehaviorClass(options, key) {\n if (options.behaviorClass) {\n return options.behaviorClass;\n //treat functions as a Behavior constructor\n } else if (_.isFunction(options)) {\n return options;\n }\n\n // behaviorsLookup can be either a flat object or a method\n if (_.isFunction(Marionette.Behaviors.behaviorsLookup)) {\n return Marionette.Behaviors.behaviorsLookup(options, key)[key];\n }\n\n return Marionette.Behaviors.behaviorsLookup[key];\n}\n\n// Iterate over the behaviors object, for each behavior\n// instantiate it and get its grouped behaviors.\n// This accepts a list of behaviors in either an object or array form\nfunction parseBehaviors(view, behaviors) {\n return _.chain(behaviors).map(function(options, key) {\n const BehaviorClass = getBehaviorClass(options, key);\n //if we're passed a class directly instead of an object\n const _options = options === BehaviorClass ? {} : options;\n const behavior = new BehaviorClass(_options, view);\n const nestedBehaviors = parseBehaviors(view, _.result(behavior, 'behaviors'));\n\n return [behavior].concat(nestedBehaviors);\n }).flatten().value();\n}\n\nexport default {\n _initBehaviors() {\n const behaviors = _.result(this, 'behaviors');\n\n // Behaviors defined on a view can be a flat object literal\n // or it can be a function that returns an object.\n this._behaviors = _.isObject(behaviors) ? parseBehaviors(this, behaviors) : {};\n },\n\n _getBehaviorTriggers() {\n const triggers = _invoke(this._behaviors, 'getTriggers');\n return _.extend({}, ...triggers);\n },\n\n _getBehaviorEvents() {\n const events = _invoke(this._behaviors, 'getEvents');\n return _.extend({}, ...events);\n },\n\n // proxy behavior $el to the view's $el.\n _proxyBehaviorViewProperties() {\n _invoke(this._behaviors, 'proxyViewProperties');\n },\n\n // delegate modelEvents and collectionEvents\n _delegateBehaviorEntityEvents() {\n _invoke(this._behaviors, 'delegateEntityEvents');\n },\n\n // undelegate modelEvents and collectionEvents\n _undelegateBehaviorEntityEvents() {\n _invoke(this._behaviors, 'undelegateEntityEvents');\n },\n\n _destroyBehaviors(args) {\n // Call destroy on each behavior after\n // destroying the view.\n // This unbinds event listeners\n // that behaviors have registered for.\n _invoke(this._behaviors, 'destroy', ...args);\n },\n\n _bindBehaviorUIElements() {\n _invoke(this._behaviors, 'bindUIElements');\n },\n\n _unbindBehaviorUIElements() {\n _invoke(this._behaviors, 'unbindUIElements');\n },\n\n _triggerEventOnBehaviors() {\n const behaviors = this._behaviors;\n // Use good ol' for as this is a very hot function\n for (let i = 0, length = behaviors && behaviors.length; i < length; i++) {\n triggerMethod.apply(behaviors[i], arguments);\n }\n }\n};\n","import _ from 'underscore';\n\n// Borrow event splitter from Backbone\nconst delegateEventSplitter = /^(\\S+)\\s*(.*)$/;\n\nfunction uniqueName(eventName, selector) {\n return [eventName + _.uniqueId('.evt'), selector].join(' ');\n}\n\n// Set event name to be namespaced using a unique index\n// to generate a non colliding event namespace\n// http://api.jquery.com/event.namespace/\nconst getUniqueEventName = function(eventName) {\n const match = eventName.match(delegateEventSplitter);\n return uniqueName(match[1], match[2]);\n};\n\nexport default getUniqueEventName;\n","import _ from 'underscore';\nimport getUniqueEventName from '../utils/get-unique-event-name';\n\n// Internal method to create an event handler for a given `triggerDef` like\n// 'click:foo'\nfunction buildViewTrigger(view, triggerDef) {\n if (_.isString(triggerDef)) {\n triggerDef = {event: triggerDef};\n }\n\n const eventName = triggerDef.event;\n const shouldPreventDefault = triggerDef.preventDefault !== false;\n const shouldStopPropagation = triggerDef.stopPropagation !== false;\n\n return function(e) {\n if (shouldPreventDefault) {\n e.preventDefault();\n }\n\n if (shouldStopPropagation) {\n e.stopPropagation();\n }\n\n view.triggerMethod(eventName, view);\n };\n}\n\nexport default {\n\n // Configure `triggers` to forward DOM events to view\n // events. `triggers: {\"click .foo\": \"do:foo\"}`\n _getViewTriggers(view, triggers) {\n // Configure the triggers, prevent default\n // action and stop propagation of DOM events\n return _.reduce(triggers, (events, value, key) => {\n key = getUniqueEventName(key);\n events[key] = buildViewTrigger(view, value);\n return events;\n }, {});\n }\n\n};\n","import { triggerMethodOn } from '../common/trigger-method';\n\nexport default function destroyBackboneView(view) {\n if (!view.supportsDestroyLifecycle) {\n triggerMethodOn(view, 'before:destroy', view);\n }\n\n const shouldTriggerDetach = !!view._isAttached;\n\n if (shouldTriggerDetach) {\n triggerMethodOn(view, 'before:detach', view);\n }\n\n view.remove();\n\n if (shouldTriggerDetach) {\n view._isAttached = false;\n triggerMethodOn(view, 'detach', view);\n }\n\n view._isDestroyed = true;\n\n if (!view.supportsDestroyLifecycle) {\n triggerMethodOn(view, 'destroy', view);\n }\n}\n","import _ from 'underscore';\nimport deprecate from '../utils/deprecate';\nimport MarionetteError from '../error';\nimport Region from '../region';\n\n// return the region instance from the definition\nexport default function(definition, defaults) {\n if (definition instanceof Region) {\n return definition;\n }\n\n return buildRegionFromDefinition(definition, defaults);\n}\n\nfunction buildRegionFromDefinition(definition, defaults) {\n const opts = _.extend({}, defaults);\n\n if (_.isString(definition)) {\n _.extend(opts, { el: definition });\n\n return buildRegionFromObject(opts);\n }\n\n if (_.isFunction(definition)) {\n _.extend(opts, { regionClass: definition });\n\n return buildRegionFromObject(opts);\n }\n\n if (_.isObject(definition)) {\n if (definition.selector) {\n deprecate('The selector option on a Region definition object is deprecated. Use el to pass a selector string');\n }\n\n _.extend(opts, { el: definition.selector }, definition);\n\n return buildRegionFromObject(opts);\n }\n\n throw new MarionetteError({\n message: 'Improper region configuration type.',\n url: 'marionette.region.html#region-configuration-types'\n });\n}\n\nfunction buildRegionFromObject(definition) {\n const RegionClass = definition.regionClass\n\n const options = _.omit(definition, 'regionClass');\n\n return new RegionClass(options);\n}\n","import MarionetteError from '../error';\n\n// Placeholder method to be extended by the user.\n// The method should define the object that stores the behaviors.\n// i.e.\n//\n// ```js\n// Marionette.Behaviors.behaviorsLookup: function() {\n// return App.Behaviors\n// }\n// ```\nexport default function behaviorsLookup() {\n throw new MarionetteError({\n message: 'You must define where your behaviors are stored.',\n url: 'marionette.behaviors.md#behaviorslookup'\n });\n}\n","// Add Feature flags here\n// e.g. 'class' => false\nconst FEATURES = {\n};\n\nfunction isEnabled(name) {\n return !!FEATURES[name];\n}\n\nfunction setEnabled(name, state) {\n return FEATURES[name] = state;\n}\n\nexport {\n FEATURES,\n setEnabled,\n isEnabled\n};\n","//Internal utility for creating context style global utils\nconst proxy = function(method) {\n return function(context, ...args) {\n return method.apply(context, args);\n };\n};\n\nexport default proxy;\n","// Marionette.extend\n// -----------------\n\nimport Backbone from 'backbone';\n\n// Borrow the Backbone `extend` method so we can use it as needed\nconst extend = Backbone.Model.extend;\n\nexport default extend;\n","/* global console */\n\nimport _ from 'underscore';\n\nimport Marionette from '../backbone.marionette';\n\nconst deprecate = function(message, test) {\n if (_.isObject(message)) {\n message = (\n message.prev + ' is going to be removed in the future. ' +\n 'Please use ' + message.next + ' instead.' +\n (message.url ? ' See: ' + message.url : '')\n );\n }\n\n if (!Marionette.DEV_MODE) {\n return;\n }\n\n if ((test === undefined || !test) && !deprecate._cache[message]) {\n deprecate._warn('Deprecation warning: ' + message);\n deprecate._cache[message] = true;\n }\n};\n\ndeprecate._console = typeof console !== 'undefined' ? console : {};\ndeprecate._warn = function() {\n const warn = deprecate._console.warn || deprecate._console.log || _.noop;\n return warn.apply(deprecate._console, arguments);\n};\ndeprecate._cache = {};\n\nexport default deprecate;\n","// Marionette.isNodeAttached\n// -------------------------\n\nimport Backbone from 'backbone';\n\n// Determine if `el` is a child of the document\nconst isNodeAttached = function(el) {\n return Backbone.$.contains(document.documentElement, el);\n};\n\nexport default isNodeAttached;\n","import _ from 'underscore';\n\n// Merge `keys` from `options` onto `this`\nconst mergeOptions = function(options, keys) {\n if (!options) { return; }\n\n _.each(keys, (key) => {\n const option = options[key];\n if (option !== undefined) {\n this[key] = option;\n }\n });\n};\n\nexport default mergeOptions;\n","// Marionette.getOption\n// --------------------\n\n// Retrieve an object, function or other value from the\n// object or its `options`, with `options` taking precedence.\nconst getOption = function(optionName) {\n if (!optionName) { return; }\n if (this.options && (this.options[optionName] !== undefined)) {\n return this.options[optionName];\n } else {\n return this[optionName];\n }\n};\n\nexport default getOption;\n","import _ from 'underscore';\n\n// Marionette.normalizeMethods\n// ----------------------\n\n// Pass in a mapping of events => functions or function names\n// and return a mapping of events => functions\nconst normalizeMethods = function(hash) {\n return _.reduce(hash, (normalizedHash, method, name) => {\n if (!_.isFunction(method)) {\n method = this[method];\n }\n if (method) {\n normalizedHash[name] = method;\n }\n return normalizedHash;\n }, {});\n};\n\nexport default normalizeMethods;\n","// Error\n// -----\n\nimport _ from 'underscore';\nimport extend from './utils/extend';\nimport {version} from '../package.json';\n\nconst errorProps = ['description', 'fileName', 'lineNumber', 'name', 'message', 'number'];\n\nconst MarionetteError = extend.call(Error, {\n urlRoot: `http://marionettejs.com/docs/v${version}/`,\n\n constructor(message, options) {\n if (_.isObject(message)) {\n options = message;\n message = options.message;\n } else if (!options) {\n options = {};\n }\n\n const error = Error.call(this, message);\n _.extend(this, _.pick(error, errorProps), _.pick(options, errorProps));\n\n this.captureStackTrace();\n\n if (options.url) {\n this.url = this.urlRoot + options.url;\n }\n },\n\n captureStackTrace() {\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, MarionetteError);\n }\n },\n\n toString() {\n return this.name + ': ' + this.message + (this.url ? ' See: ' + this.url : '');\n }\n});\n\nMarionetteError.extend = extend;\n\nexport default MarionetteError;\n","import _ from 'underscore';\n\n// Internal utility for setting options consistently across Mn\nconst setOptions = function(...args) {\n this.options = _.extend({}, _.result(this, 'options'), ...args);\n};\n\nexport default setOptions;\n","import _setOptions from '../utils/set-options';\nimport getOption from '../common/get-option';\nimport mergeOptions from '../common/merge-options';\nimport normalizeMethods from '../common/normalize-methods';\nimport {\n bindEvents,\n unbindEvents\n} from '../common/bind-events';\n\nexport default {\n\n // Imports the \"normalizeMethods\" to transform hashes of\n // events=>function references/names to a hash of events=>function references\n normalizeMethods: normalizeMethods,\n\n _setOptions: _setOptions,\n\n // A handy way to merge passed-in options onto the instance\n mergeOptions: mergeOptions,\n\n // Enable getting options from this or this.options by name.\n getOption: getOption,\n\n // Enable binding view's events from another entity.\n bindEvents: bindEvents,\n\n // Enable unbinding view's events from another entity.\n unbindEvents: unbindEvents\n};\n","import _ from 'underscore';\nimport Radio from 'backbone.radio';\n\nimport {\n bindRequests,\n unbindRequests\n} from '../common/bind-requests';\n\nimport {\n bindEvents,\n unbindEvents\n} from '../common/bind-events';\n\nimport MarionetteError from '../error';\n\n// MixinOptions\n// - channelName\n// - radioEvents\n// - radioRequests\n\nexport default {\n\n _initRadio() {\n const channelName = _.result(this, 'channelName');\n\n if (!channelName) {\n return;\n }\n\n /* istanbul ignore next */\n if (!Radio) {\n throw new MarionetteError({\n name: 'BackboneRadioMissing',\n message: 'The dependency \"backbone.radio\" is missing.'\n });\n }\n\n const channel = this._channel = Radio.channel(channelName);\n\n const radioEvents = _.result(this, 'radioEvents');\n this.bindEvents(channel, radioEvents);\n\n const radioRequests = _.result(this, 'radioRequests');\n this.bindRequests(channel, radioRequests);\n\n this.on('destroy', this._destroyRadio);\n },\n\n _destroyRadio() {\n this._channel.stopReplying(null, null, this);\n },\n\n getChannel() {\n return this._channel;\n },\n\n // Proxy `bindEvents`\n bindEvents: bindEvents,\n\n // Proxy `unbindEvents`\n unbindEvents: unbindEvents,\n\n // Proxy `bindRequests`\n bindRequests: bindRequests,\n\n // Proxy `unbindRequests`\n unbindRequests: unbindRequests\n\n};\n","// Object\n// ------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport extend from './utils/extend';\nimport { triggerMethod } from './common/trigger-method';\nimport CommonMixin from './mixins/common';\nimport RadioMixin from './mixins/radio';\n\nconst ClassOptions = [\n 'channelName',\n 'radioEvents',\n 'radioRequests'\n];\n\n// A Base Class that other Classes should descend from.\n// Object borrows many conventions and utilities from Backbone.\nconst MarionetteObject = function(options) {\n this._setOptions(options);\n this.mergeOptions(options, ClassOptions);\n this.cid = _.uniqueId(this.cidPrefix);\n this._initRadio();\n this.initialize.apply(this, arguments);\n};\n\nMarionetteObject.extend = extend;\n\n// Object Methods\n// --------------\n\n// Ensure it can trigger events with Backbone.Events\n_.extend(MarionetteObject.prototype, Backbone.Events, CommonMixin, RadioMixin, {\n cidPrefix: 'mno',\n\n // for parity with Marionette.AbstractView lifecyle\n _isDestroyed: false,\n\n isDestroyed() {\n return this._isDestroyed;\n },\n\n //this is a noop method intended to be overridden by classes that extend from this base\n initialize() {},\n\n destroy(...args) {\n if (this._isDestroyed) { return this; }\n\n this.triggerMethod('before:destroy', this, ...args);\n\n this._isDestroyed = true;\n this.triggerMethod('destroy', this, ...args);\n this.stopListening();\n\n return this;\n },\n\n triggerMethod: triggerMethod\n});\n\nexport default MarionetteObject;\n","// Template Cache\n// --------------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport MarionetteError from './error';\n\n// Manage templates stored in `<script>` blocks,\n// caching them for faster access.\nconst TemplateCache = function(templateId) {\n this.templateId = templateId;\n};\n\n// TemplateCache object-level methods. Manage the template\n// caches from these method calls instead of creating\n// your own TemplateCache instances\n_.extend(TemplateCache, {\n templateCaches: {},\n\n // Get the specified template by id. Either\n // retrieves the cached version, or loads it\n // from the DOM.\n get(templateId, options) {\n let cachedTemplate = this.templateCaches[templateId];\n\n if (!cachedTemplate) {\n cachedTemplate = new TemplateCache(templateId);\n this.templateCaches[templateId] = cachedTemplate;\n }\n\n return cachedTemplate.load(options);\n },\n\n // Clear templates from the cache. If no arguments\n // are specified, clears all templates:\n // `clear()`\n //\n // If arguments are specified, clears each of the\n // specified templates from the cache:\n // `clear(\"#t1\", \"#t2\", \"...\")`\n clear(...args) {\n let i;\n const length = args.length;\n\n if (length > 0) {\n for (i = 0; i < length; i++) {\n delete this.templateCaches[args[i]];\n }\n } else {\n this.templateCaches = {};\n }\n }\n});\n\n// TemplateCache instance methods, allowing each\n// template cache object to manage its own state\n// and know whether or not it has been loaded\n_.extend(TemplateCache.prototype, {\n\n // Internal method to load the template\n load(options) {\n // Guard clause to prevent loading this template more than once\n if (this.compiledTemplate) {\n return this.compiledTemplate;\n }\n\n // Load the template and compile it\n const template = this.loadTemplate(this.templateId, options);\n this.compiledTemplate = this.compileTemplate(template, options);\n\n return this.compiledTemplate;\n },\n\n // Load a template from the DOM, by default. Override\n // this method to provide your own template retrieval\n // For asynchronous loading with AMD/RequireJS, consider\n // using a template-loader plugin as described here:\n // https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs\n loadTemplate(templateId, options) {\n const $template = Backbone.$(templateId);\n\n if (!$template.length) {\n throw new MarionetteError({\n name: 'NoTemplateError',\n message: `Could not find template: \"${templateId}\"`\n });\n }\n return $template.html();\n },\n\n // Pre-compile the template before caching it. Override\n // this method if you do not need to pre-compile a template\n // (JST / RequireJS for example) or if you want to change\n // the template engine used (Handebars, etc).\n compileTemplate(rawTemplate, options) {\n return _.template(rawTemplate, options);\n }\n});\n\nexport default TemplateCache;\n","// Implementation of the invoke method (http://underscorejs.org/#invoke) with support for\n// lodash v3, v4, and underscore.js\nimport _ from 'underscore';\n\nexport default _.invokeMap || _.invoke;\n","import _ from 'underscore';\n\nimport {\n bindEvents,\n unbindEvents\n} from '../common/bind-events';\n\n// MixinOptions\n// - collectionEvents\n// - modelEvents\n\nexport default {\n // Handle `modelEvents`, and `collectionEvents` configuration\n _delegateEntityEvents(model, collection) {\n this._undelegateEntityEvents(model, collection);\n\n const modelEvents = _.result(this, 'modelEvents');\n bindEvents.call(this, model, modelEvents);\n\n const collectionEvents = _.result(this, 'collectionEvents');\n bindEvents.call(this, collection, collectionEvents);\n },\n\n _undelegateEntityEvents(model, collection) {\n const modelEvents = _.result(this, 'modelEvents');\n unbindEvents.call(this, model, modelEvents);\n\n const collectionEvents = _.result(this, 'collectionEvents');\n unbindEvents.call(this, collection, collectionEvents);\n }\n};\n","import _ from 'underscore';\n// allows for the use of the @ui. syntax within\n// a given key for triggers and events\n// swaps the @ui with the associated selector.\n// Returns a new, non-mutated, parsed events hash.\nconst normalizeUIKeys = function(hash, ui) {\n return _.reduce(hash, (memo, val, key) => {\n const normalizedKey = normalizeUIString(key, ui);\n memo[normalizedKey] = val;\n return memo;\n }, {});\n};\n\n// utility method for parsing @ui. syntax strings\n// into associated selector\nconst normalizeUIString = function(uiString, ui) {\n return uiString.replace(/@ui\\.[a-zA-Z-_$0-9]*/g, (r) => {\n return ui[r.slice(4)];\n });\n};\n\n// allows for the use of the @ui. syntax within\n// a given value for regions\n// swaps the @ui with the associated selector\nconst normalizeUIValues = function(hash, ui, properties) {\n _.each(hash, (val, key) => {\n if (_.isString(val)) {\n hash[key] = normalizeUIString(val, ui);\n } else if (_.isObject(val) && _.isArray(properties)) {\n _.extend(val, normalizeUIValues(_.pick(val, properties), ui));\n /* Value is an object, and we got an array of embedded property names to normalize. */\n _.each(properties, (property) => {\n const propertyVal = val[property];\n if (_.isString(propertyVal)) {\n val[property] = normalizeUIString(propertyVal, ui);\n }\n });\n }\n });\n return hash;\n};\n\nexport default {\n\n // normalize the keys of passed hash with the views `ui` selectors.\n // `{\"@ui.foo\": \"bar\"}`\n normalizeUIKeys(hash) {\n const uiBindings = this._getUIBindings();\n return normalizeUIKeys(hash, uiBindings);\n },\n\n // normalize the passed string with the views `ui` selectors.\n // `\"@ui.bar\"`\n normalizeUIString(uiString) {\n const uiBindings = this._getUIBindings();\n return normalizeUIString(uiString, uiBindings);\n },\n\n // normalize the values of passed hash with the views `ui` selectors.\n // `{foo: \"@ui.bar\"}`\n normalizeUIValues(hash, properties) {\n const uiBindings = this._getUIBindings();\n return normalizeUIValues(hash, uiBindings, properties);\n },\n\n _getUIBindings() {\n const uiBindings = _.result(this, '_uiBindings');\n const ui = _.result(this, 'ui');\n return uiBindings || ui;\n },\n\n // This method binds the elements specified in the \"ui\" hash inside the view's code with\n // the associated jQuery selectors.\n _bindUIElements() {\n if (!this.ui) { return; }\n\n // store the ui hash in _uiBindings so they can be reset later\n // and so re-rendering the view will be able to find the bindings\n if (!this._uiBindings) {\n this._uiBindings = this.ui;\n }\n\n // get the bindings result, as a function or otherwise\n const bindings = _.result(this, '_uiBindings');\n\n // empty the ui so we don't have anything to start with\n this._ui = {};\n\n // bind each of the selectors\n _.each(bindings, (selector, key) => {\n this._ui[key] = this.$(selector);\n });\n\n this.ui = this._ui;\n },\n\n _unbindUIElements() {\n if (!this.ui || !this._uiBindings) { return; }\n\n // delete all of the existing ui bindings\n _.each(this.ui, ($el, name) => {\n delete this.ui[name];\n });\n\n // reset the ui element to the original bindings configuration\n this.ui = this._uiBindings;\n delete this._uiBindings;\n delete this._ui;\n },\n\n _getUI(name) {\n return this._ui[name];\n }\n};\n","// ViewMixin\n// ---------\n\nimport Backbone from 'backbone';\nimport _ from 'underscore';\nimport { triggerMethod } from '../common/trigger-method';\nimport BehaviorsMixin from './behaviors';\nimport CommonMixin from './common';\nimport DelegateEntityEventsMixin from './delegate-entity-events';\nimport TriggersMixin from './triggers';\nimport UIMixin from './ui';\nimport View from '../view';\nimport MarionetteError from '../error';\n\n// MixinOptions\n// - behaviors\n// - childViewEventPrefix\n// - childViewEvents\n// - childViewTriggers\n// - collectionEvents\n// - modelEvents\n// - triggers\n// - ui\n\n\nconst ViewMixin = {\n supportsRenderLifecycle: true,\n supportsDestroyLifecycle: true,\n\n _isDestroyed: false,\n\n isDestroyed() {\n return !!this._isDestroyed;\n },\n\n _isRendered: false,\n\n isRendered() {\n return !!this._isRendered;\n },\n\n _isAttached: false,\n\n isAttached() {\n return !!this._isAttached;\n },\n\n // Overriding Backbone.View's `delegateEvents` to handle\n // `events` and `triggers`\n delegateEvents(eventsArg) {\n\n this._proxyBehaviorViewProperties();\n this._buildEventProxies();\n\n const viewEvents = this._getEvents(eventsArg);\n\n if (typeof eventsArg === 'undefined') {\n this.events = viewEvents;\n }\n\n const combinedEvents = _.extend({},\n this._getBehaviorEvents(),\n viewEvents,\n this._getBehaviorTriggers(),\n this.getTriggers()\n );\n\n Backbone.View.prototype.delegateEvents.call(this, combinedEvents);\n\n return this;\n },\n\n _getEvents(eventsArg) {\n const events = eventsArg || this.events;\n\n if (_.isFunction(events)) {\n return this.normalizeUIKeys(events.call(this));\n }\n\n return this.normalizeUIKeys(events);\n },\n\n // Configure `triggers` to forward DOM events to view\n // events. `triggers: {\"click .foo\": \"do:foo\"}`\n getTriggers() {\n if (!this.triggers) { return; }\n\n // Allow `triggers` to be configured as a function\n const triggers = this.normalizeUIKeys(_.result(this, 'triggers'));\n\n // Configure the triggers, prevent default\n // action and stop propagation of DOM events\n return this._getViewTriggers(this, triggers);\n },\n\n // Handle `modelEvents`, and `collectionEvents` configuration\n delegateEntityEvents() {\n this._delegateEntityEvents(this.model, this.collection);\n\n // bind each behaviors model and collection events\n this._delegateBehaviorEntityEvents();\n\n return this;\n },\n\n // Handle unbinding `modelEvents`, and `collectionEvents` configuration\n undelegateEntityEvents() {\n this._undelegateEntityEvents(this.model, this.collection);\n\n // unbind each behaviors model and collection events\n this._undelegateBehaviorEntityEvents();\n\n return this;\n },\n\n // Internal helper method to verify whether the view hasn't been destroyed\n _ensureViewIsIntact() {\n if (this._isDestroyed) {\n throw new MarionetteError({\n name: 'ViewDestroyedError',\n message: `View (cid: \"${this.cid}\") has already been destroyed and cannot be used.`\n });\n }\n },\n\n // Handle destroying the view and its children.\n destroy(...args) {\n if (this._isDestroyed) { return this; }\n const shouldTriggerDetach = !!this._isAttached;\n\n this.triggerMethod('before:destroy', this, ...args);\n if (shouldTriggerDetach) {\n this.triggerMethod('before:detach', this);\n }\n\n // unbind UI elements\n this.unbindUIElements();\n\n // remove the view from the DOM\n // https://github.com/jashkenas/backbone/blob/1.2.3/backbone.js#L1235\n this._removeElement();\n\n if (shouldTriggerDetach) {\n this._isAttached = false;\n this.triggerMethod('detach', this);\n }\n\n // remove children after the remove to prevent extra paints\n this._removeChildren();\n\n this._destroyBehaviors(args);\n\n this._isDestroyed = true;\n this._isRendered = false;\n this.triggerMethod('destroy', this, ...args);\n\n this.stopListening();\n\n return this;\n },\n\n bindUIElements() {\n this._bindUIElements();\n this._bindBehaviorUIElements();\n\n return this;\n },\n\n // This method unbinds the elements specified in the \"ui\" hash\n unbindUIElements() {\n this._unbindUIElements();\n this._unbindBehaviorUIElements();\n\n return this;\n },\n\n getUI(name) {\n this._ensureViewIsIntact();\n return this._getUI(name);\n },\n\n // used as the prefix for child view events\n // that are forwarded through the layoutview\n childViewEventPrefix: 'childview',\n\n // import the `triggerMethod` to trigger events with corresponding\n // methods if the method exists\n triggerMethod() {\n const ret = triggerMethod.apply(this, arguments);\n\n this._triggerEventOnBehaviors.apply(this, arguments);\n this._triggerEventOnParentLayout.apply(this, arguments);\n\n return ret;\n },\n\n // Cache `childViewEvents` and `childViewTriggers`\n _buildEventProxies() {\n this._childViewEvents = _.result(this, 'childViewEvents');\n this._childViewTriggers = _.result(this, 'childViewTriggers');\n },\n\n _triggerEventOnParentLayout() {\n const layoutView = this._parentView();\n if (!layoutView) {\n return;\n }\n\n layoutView._childViewEventHandler.apply(layoutView, arguments);\n },\n\n // Walk the _parent tree until we find a view (if one exists).\n // Returns the parent view hierarchically closest to this view.\n _parentView() {\n let parent = this._parent;\n\n while (parent) {\n if (parent instanceof View) {\n return parent;\n }\n parent = parent._parent;\n }\n },\n\n _childViewEventHandler(eventName, ...args) {\n const childViewEvents = this.normalizeMethods(this._childViewEvents);\n\n // call collectionView childViewEvent if defined\n if (typeof childViewEvents !== 'undefined' && _.isFunction(childViewEvents[eventName])) {\n childViewEvents[eventName].apply(this, args);\n }\n\n // use the parent view's proxyEvent handlers\n const childViewTriggers = this._childViewTriggers;\n\n // Call the event with the proxy name on the parent layout\n if (childViewTriggers && _.isString(childViewTriggers[eventName])) {\n this.triggerMethod(childViewTriggers[eventName], ...args);\n }\n\n const prefix = _.result(this, 'childViewEventPrefix');\n\n if (prefix !== false) {\n const childEventName = prefix + ':' + eventName;\n\n this.triggerMethod(childEventName, ...args);\n }\n }\n};\n\n_.extend(ViewMixin, BehaviorsMixin, CommonMixin, DelegateEntityEventsMixin, TriggersMixin, UIMixin);\n\nexport default ViewMixin;\n","// Region\n// ------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport deprecate from './utils/deprecate';\nimport destroyBackboneView from './utils/destroy-backbone-view';\nimport monitorViewEvents from './common/monitor-view-events';\nimport isNodeAttached from './common/is-node-attached';\nimport { triggerMethodOn } from './common/trigger-method';\nimport MarionetteObject from './object';\nimport MarionetteError from './error';\n\nconst ClassOptions = [\n 'allowMissingEl',\n 'parentEl',\n 'replaceElement'\n];\n\nconst Region = MarionetteObject.extend({\n cidPrefix: 'mnr',\n replaceElement: false,\n _isReplaced: false,\n\n constructor(options) {\n this._setOptions(options);\n\n this.mergeOptions(options, ClassOptions);\n\n // getOption necessary because options.el may be passed as undefined\n this._initEl = this.el = this.getOption('el');\n\n // Handle when this.el is passed in as a $ wrapped element.\n this.el = this.el instanceof Backbone.$ ? this.el[0] : this.el;\n\n if (!this.el) {\n throw new MarionetteError({\n name: 'NoElError',\n message: 'An \"el\" must be specified for a region.'\n });\n }\n\n this.$el = this.getEl(this.el);\n MarionetteObject.call(this, options);\n },\n\n // Displays a backbone view instance inside of the region. Handles calling the `render`\n // method for you. Reads content directly from the `el` attribute. The `preventDestroy`\n // option can be used to prevent a view from the old view being destroyed on show.\n show(view, options) {\n if (!this._ensureElement(options)) {\n return;\n }\n this._ensureView(view);\n if (view === this.currentView) { return this; }\n\n this.triggerMethod('before:show', this, view, options);\n\n monitorViewEvents(view);\n\n this.empty(options);\n\n // We need to listen for if a view is destroyed in a way other than through the region.\n // If this happens we need to remove the reference to the currentView since once a view\n // has been destroyed we can not reuse it.\n view.on('destroy', this._empty, this);\n\n // Make this region the view's parent.\n // It's important that this parent binding happens before rendering so that any events\n // the child may trigger during render can also be triggered on the child's ancestor views.\n view._parent = this;\n\n this._renderView(view);\n\n this._attachView(view, options);\n\n this.triggerMethod('show', this, view, options);\n return this;\n },\n\n _renderView(view) {\n if (view._isRendered) {\n return;\n }\n\n if (!view.supportsRenderLifecycle) {\n triggerMethodOn(view, 'before:render', view);\n }\n\n view.render();\n\n if (!view.supportsRenderLifecycle) {\n view._isRendered = true;\n triggerMethodOn(view, 'render', view);\n }\n },\n\n _attachView(view, options = {}) {\n const shouldTriggerAttach = !view._isAttached && isNodeAttached(this.el);\n const shouldReplaceEl = typeof options.replaceElement === 'undefined' ? !!_.result(this, 'replaceElement') : !!options.replaceElement;\n\n if (shouldTriggerAttach) {\n triggerMethodOn(view, 'before:attach', view);\n }\n\n if (shouldReplaceEl) {\n this._replaceEl(view);\n } else {\n this.attachHtml(view);\n }\n\n if (shouldTriggerAttach) {\n view._isAttached = true;\n triggerMethodOn(view, 'attach', view);\n }\n\n this.currentView = view;\n },\n\n _ensureElement(options = {}) {\n if (!_.isObject(this.el)) {\n this.$el = this.getEl(this.el);\n this.el = this.$el[0];\n }\n\n if (!this.$el || this.$el.length === 0) {\n const allowMissingEl = typeof options.allowMissingEl === 'undefined' ? !!_.result(this, 'allowMissingEl') : !!options.allowMissingEl;\n\n if (allowMissingEl) {\n return false;\n } else {\n throw new MarionetteError(`An \"el\" must exist in DOM for this region ${this.cid}`);\n }\n }\n return true;\n },\n\n _ensureView(view) {\n if (!view) {\n throw new MarionetteError({\n name: 'ViewNotValid',\n message: 'The view passed is undefined and therefore invalid. You must pass a view instance to show.'\n });\n }\n\n if (view._isDestroyed) {\n throw new MarionetteError({\n name: 'ViewDestroyedError',\n message: `View (cid: \"${view.cid}\") has already been destroyed and cannot be used.`\n });\n }\n },\n\n // Override this method to change how the region finds the DOM element that it manages. Return\n // a jQuery selector object scoped to a provided parent el or the document if none exists.\n getEl(el) {\n return Backbone.$(el, _.result(this, 'parentEl'));\n },\n\n _replaceEl(view) {\n // always restore the el to ensure the regions el is present before replacing\n this._restoreEl();\n\n const parent = this.el.parentNode;\n\n parent.replaceChild(view.el, this.el);\n this._isReplaced = true;\n },\n\n // Restore the region's element in the DOM.\n _restoreEl() {\n // There is nothing to replace\n if (!this._isReplaced) {\n return;\n }\n\n const view = this.currentView;\n\n if (!view) {\n return;\n }\n\n const parent = view.el.parentNode;\n\n if (!parent) {\n return;\n }\n\n parent.replaceChild(this.el, view.el);\n this._isReplaced = false;\n },\n\n // Check to see if the region's el was replaced.\n isReplaced() {\n return !!this._isReplaced;\n },\n\n // Override this method to change how the new view is appended to the `$el` that the\n // region is managing\n attachHtml(view) {\n this.el.appendChild(view.el);\n },\n\n // Destroy the current view, if there is one. If there is no current view, it does\n // nothing and returns immediately.\n empty(options = { allowMissingEl: true }) {\n const view = this.currentView;\n\n // If there is no view in the region we should only detach current html\n if (!view) {\n if (this._ensureElement(options)) {\n this.detachHtml();\n }\n return this;\n }\n\n const shouldDestroy = !options.preventDestroy;\n\n if (!shouldDestroy) {\n deprecate('The preventDestroy option is deprecated. Use Region#detachView');\n }\n\n this._empty(view, shouldDestroy);\n return this;\n },\n\n _empty(view, shouldDestroy) {\n view.off('destroy', this._empty, this);\n this.triggerMethod('before:empty', this, view);\n\n this._restoreEl();\n\n delete this.currentView;\n\n if (!view._isDestroyed) {\n this._removeView(view, shouldDestroy);\n delete view._parent;\n }\n\n this.triggerMethod('empty', this, view);\n },\n\n _removeView(view, shouldDestroy) {\n if (!shouldDestroy) {\n this._detachView(view);\n return;\n }\n\n if (view.destroy) {\n view.destroy();\n } else {\n destroyBackboneView(view);\n }\n },\n\n detachView() {\n const view = this.currentView;\n\n if (!view) {\n return;\n }\n\n this._empty(view);\n\n return view;\n },\n\n _detachView(view) {\n const shouldTriggerDetach = !!view._isAttached;\n if (shouldTriggerDetach) {\n triggerMethodOn(view, 'before:detach', view);\n }\n\n this.detachHtml();\n\n if (shouldTriggerDetach) {\n view._isAttached = false;\n triggerMethodOn(view, 'detach', view);\n }\n },\n\n // Override this method to change how the region detaches current content\n detachHtml() {\n this.$el.contents().detach();\n },\n\n // Checks whether a view is currently present within the region. Returns `true` if there is\n // and `false` if no view is present.\n hasView() {\n return !!this.currentView;\n },\n\n // Reset the region by destroying any existing view and clearing out the cached `$el`.\n // The next time a view is shown via this region, the region will re-query the DOM for\n // the region's `el`.\n reset(options) {\n this.empty(options);\n\n if (this.$el) {\n this.el = this._initEl;\n }\n\n delete this.$el;\n return this;\n },\n\n destroy(options) {\n this.reset(options);\n return MarionetteObject.prototype.destroy.apply(this, arguments);\n }\n});\n\nexport default Region;\n","import _ from 'underscore';\nimport _invoke from '../utils/invoke';\nimport buildRegion from '../common/build-region';\nimport Region from '../region';\n\n// MixinOptions\n// - regions\n// - regionClass\n\nexport default {\n regionClass: Region,\n\n // Internal method to initialize the regions that have been defined in a\n // `regions` attribute on this View.\n _initRegions() {\n\n // init regions hash\n this.regions = this.regions || {};\n this._regions = {};\n\n this.addRegions(_.result(this, 'regions'));\n },\n\n // Internal method to re-initialize all of the regions by updating\n // the `el` that they point to\n _reInitRegions() {\n _invoke(this._regions, 'reset');\n },\n\n // Add a single region, by name, to the View\n addRegion(name, definition) {\n const regions = {};\n regions[name] = definition;\n return this.addRegions(regions)[name];\n },\n\n // Add multiple regions as a {name: definition, name2: def2} object literal\n addRegions(regions) {\n // If there's nothing to add, stop here.\n if (_.isEmpty(regions)) {\n return;\n }\n\n // Normalize region selectors hash to allow\n // a user to use the @ui. syntax.\n regions = this.normalizeUIValues(regions, ['selector', 'el']);\n\n // Add the regions definitions to the regions property\n this.regions = _.extend({}, this.regions, regions);\n\n return this._addRegions(regions);\n },\n\n // internal method to build and add regions\n _addRegions(regionDefinitions) {\n const defaults = {\n regionClass: this.regionClass,\n parentEl: _.partial(_.result, this, 'el')\n };\n\n return _.reduce(regionDefinitions, (regions, definition, name) => {\n regions[name] = buildRegion(definition, defaults);\n this._addRegion(regions[name], name);\n return regions;\n }, {});\n },\n\n _addRegion(region, name) {\n this.triggerMethod('before:add:region', this, name, region);\n\n region._parent = this;\n\n this._regions[name] = region;\n\n this.triggerMethod('add:region', this, name, region);\n },\n\n // Remove a single region from the View, by name\n removeRegion(name) {\n const region = this._regions[name];\n\n this._removeRegion(region, name);\n\n return region;\n },\n\n // Remove all regions from the View\n removeRegions() {\n const regions = this.getRegions();\n\n _.each(this._regions, _.bind(this._removeRegion, this));\n\n return regions;\n },\n\n _removeRegion(region, name) {\n this.triggerMethod('before:remove:region', this, name, region);\n\n region.destroy();\n\n delete this.regions[name];\n delete this._regions[name];\n\n this.triggerMethod('remove:region', this, name, region);\n },\n\n // Empty all regions in the region manager, but\n // leave them attached\n emptyRegions() {\n const regions = this.getRegions();\n _invoke(regions, 'empty');\n return regions;\n },\n\n // Checks to see if view contains region\n // Accepts the region name\n // hasRegion('main')\n hasRegion(name) {\n return !!this.getRegion(name);\n },\n\n // Provides access to regions\n // Accepts the region name\n // getRegion('main')\n getRegion(name) {\n return this._regions[name];\n },\n\n // Get all regions\n getRegions() {\n return _.clone(this._regions);\n },\n\n showChildView(name, view, ...args) {\n const region = this.getRegion(name);\n return region.show(view, ...args);\n },\n\n detachChildView(name) {\n return this.getRegion(name).detachView();\n },\n\n getChildView(name) {\n return this.getRegion(name).currentView;\n }\n\n};\n","// Renderer\n// --------\n\nimport _ from 'underscore';\nimport MarionetteError from '../error';\nimport TemplateCache from '../template-cache';\n\n// Render a template with data by passing in the template\n// selector and the data to render.\nconst Renderer = {\n\n // Render a template with data. The `template` parameter is\n // passed to the `TemplateCache` object to retrieve the\n // template function. Override this method to provide your own\n // custom rendering and template handling for all of Marionette.\n render(template, data) {\n if (!template) {\n throw new MarionetteError({\n name: 'TemplateNotFoundError',\n message: 'Cannot render the template since its false, null or undefined.'\n });\n }\n\n const templateFunc = _.isFunction(template) ? template : TemplateCache.get(template);\n\n return templateFunc(data);\n }\n};\n\nexport default Renderer;\n","// View\n// ---------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport isNodeAttached from './common/is-node-attached';\nimport monitorViewEvents from './common/monitor-view-events';\nimport ViewMixin from './mixins/view';\nimport RegionsMixin from './mixins/regions';\nimport Renderer from './config/renderer';\n\nconst ClassOptions = [\n 'behaviors',\n 'childViewEventPrefix',\n 'childViewEvents',\n 'childViewTriggers',\n 'collectionEvents',\n 'events',\n 'modelEvents',\n 'regionClass',\n 'regions',\n 'template',\n 'templateContext',\n 'triggers',\n 'ui'\n];\n\n// The standard view. Includes view events, automatic rendering\n// of Underscore templates, nested views, and more.\nconst View = Backbone.View.extend({\n\n constructor(options) {\n this.render = _.bind(this.render, this);\n\n this._setOptions(options);\n\n this.mergeOptions(options, ClassOptions);\n\n monitorViewEvents(this);\n\n this._initBehaviors();\n this._initRegions();\n\n const args = Array.prototype.slice.call(arguments);\n args[0] = this.options;\n Backbone.View.prototype.constructor.apply(this, args);\n\n this.delegateEntityEvents();\n },\n\n // Serialize the view's model *or* collection, if\n // it exists, for the template\n serializeData() {\n if (!this.model && !this.collection) {\n return {};\n }\n\n // If we have a model, we serialize that\n if (this.model) {\n return this.serializeModel();\n }\n\n // Otherwise, we serialize the collection,\n // making it available under the `items` property\n return {\n items: this.serializeCollection()\n };\n },\n\n // Prepares the special `model` property of a view\n // for being displayed in the template. By default\n // we simply clone the attributes. Override this if\n // you need a custom transformation for your view's model\n serializeModel() {\n if (!this.model) { return {}; }\n return _.clone(this.model.attributes);\n },\n\n // Serialize a collection by cloning each of\n // its model's attributes\n serializeCollection() {\n if (!this.collection) { return {}; }\n return this.collection.map(function(model) { return _.clone(model.attributes); });\n },\n\n // Overriding Backbone.View's `setElement` to handle\n // if an el was previously defined. If so, the view might be\n // rendered or attached on setElement.\n setElement() {\n const hasEl = !!this.el;\n\n Backbone.View.prototype.setElement.apply(this, arguments);\n\n if (hasEl) {\n this._isRendered = !!this.$el.length;\n this._isAttached = isNodeAttached(this.el);\n }\n\n if (this._isRendered) {\n this.bindUIElements();\n }\n\n return this;\n },\n\n // Render the view, defaulting to underscore.js templates.\n // You can override this in your view definition to provide\n // a very specific rendering for your view. In general, though,\n // you should override the `Marionette.Renderer` object to\n // change how Marionette renders views.\n // Subsequent renders after the first will re-render all nested\n // views.\n render() {\n this._ensureViewIsIntact();\n\n this.triggerMethod('before:render', this);\n\n // If this is not the first render call, then we need to\n // re-initialize the `el` for each region\n if (this._isRendered) {\n this._reInitRegions();\n }\n\n this._renderTemplate();\n this.bindUIElements();\n\n this._isRendered = true;\n this.triggerMethod('render', this);\n\n return this;\n },\n\n // Internal method to render the template with the serialized data\n // and template context via the `Marionette.Renderer` object.\n _renderTemplate() {\n const template = this.getTemplate();\n\n // Allow template-less views\n if (template === false) {\n return;\n }\n\n // Add in entity data and template context\n const data = this.mixinTemplateContext(this.serializeData());\n\n // Render and add to el\n const html = Renderer.render(template, data, this);\n this.attachElContent(html);\n },\n\n // Get the template for this view\n // instance. You can set a `template` attribute in the view\n // definition or pass a `template: \"whatever\"` parameter in\n // to the constructor options.\n getTemplate() {\n return this.template;\n },\n\n // Mix in template context methods. Looks for a\n // `templateContext` attribute, which can either be an\n // object literal, or a function that returns an object\n // literal. All methods and attributes from this object\n // are copies to the object passed in.\n mixinTemplateContext(target = {}) {\n const templateContext = _.result(this, 'templateContext');\n return _.extend(target, templateContext);\n },\n\n // Attaches the content of a given view.\n // This method can be overridden to optimize rendering,\n // or to render in a non standard way.\n //\n // For example, using `innerHTML` instead of `$el.html`\n //\n // ```js\n // attachElContent(html) {\n // this.el.innerHTML = html;\n // return this;\n // }\n // ```\n attachElContent(html) {\n this.$el.html(html);\n\n return this;\n },\n\n // called by ViewMixin destroy\n _removeChildren() {\n this.removeRegions();\n },\n\n _getImmediateChildren() {\n return _.chain(this.getRegions())\n .map('currentView')\n .compact()\n .value();\n }\n});\n\n_.extend(View.prototype, ViewMixin, RegionsMixin);\n\nexport default View;\n","// Mix in methods from Underscore, for iteration, and other\n// collection related features.\n// Borrowing this code from Backbone.Collection:\n// https://github.com/jashkenas/backbone/blob/1.1.2/backbone.js#L962\n\nimport _ from 'underscore';\n\nconst methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',\n 'select', 'reject', 'every', 'all', 'some', 'any', 'include',\n 'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',\n 'last', 'without', 'isEmpty', 'pluck', 'reduce'];\n\nconst emulateCollection = function(object, listProperty) {\n _.each(methods, function(method) {\n object[method] = function() {\n const list = _.values(_.result(this, listProperty));\n const args = [list].concat(_.toArray(arguments));\n return _[method].apply(_, args);\n };\n });\n};\n\nexport default emulateCollection;\n","import _ from 'underscore';\nimport emulateCollection from './utils/emulate-collection';\n\n// Provide a container to store, retrieve and\n// shut down child views.\nconst Container = function(views) {\n this._views = {};\n this._indexByModel = {};\n this._indexByCustom = {};\n this._updateLength();\n\n _.each(views, _.bind(this.add, this));\n};\n\nemulateCollection(Container.prototype, '_views');\n\n// Container Methods\n// -----------------\n\n_.extend(Container.prototype, {\n\n // Add a view to this container. Stores the view\n // by `cid` and makes it searchable by the model\n // cid (and model itself). Optionally specify\n // a custom key to store an retrieve the view.\n add(view, customIndex) {\n return this._add(view, customIndex)._updateLength();\n },\n\n // To be used when avoiding call _updateLength\n // When you are done adding all your new views\n // call _updateLength\n _add(view, customIndex) {\n const viewCid = view.cid;\n\n // store the view\n this._views[viewCid] = view;\n\n // index it by model\n if (view.model) {\n this._indexByModel[view.model.cid] = viewCid;\n }\n\n // index by custom\n if (customIndex) {\n this._indexByCustom[customIndex] = viewCid;\n }\n\n return this;\n },\n\n // Find a view by the model that was attached to\n // it. Uses the model's `cid` to find it.\n findByModel(model) {\n return this.findByModelCid(model.cid);\n },\n\n // Find a view by the `cid` of the model that was attached to\n // it. Uses the model's `cid` to find the view `cid` and\n // retrieve the view using it.\n findByModelCid(modelCid) {\n const viewCid = this._indexByModel[modelCid];\n return this.findByCid(viewCid);\n },\n\n // Find a view by a custom indexer.\n findByCustom(index) {\n const viewCid = this._indexByCustom[index];\n return this.findByCid(viewCid);\n },\n\n // Find by index. This is not guaranteed to be a\n // stable index.\n findByIndex(index) {\n return _.values(this._views)[index];\n },\n\n // retrieve a view by its `cid` directly\n findByCid(cid) {\n return this._views[cid];\n },\n\n // Remove a view\n remove(view) {\n return this._remove(view)._updateLength();\n },\n\n // To be used when avoiding call _updateLength\n // When you are done adding all your new views\n // call _updateLength\n _remove(view) {\n const viewCid = view.cid;\n\n // delete model index\n if (view.model) {\n delete this._indexByModel[view.model.cid];\n }\n\n // delete custom index\n _.some(this._indexByCustom, _.bind(function(cid, key) {\n if (cid === viewCid) {\n delete this._indexByCustom[key];\n return true;\n }\n }, this));\n\n // remove the view from the container\n delete this._views[viewCid];\n\n return this;\n },\n\n // Update the `.length` attribute on this container\n _updateLength() {\n this.length = _.size(this._views);\n\n return this;\n }\n});\n\nexport default Container;\n","// Collection View\n// ---------------\n\nimport _ from 'underscore';\nimport Backbone from 'backbone';\nimport destroyBackboneView from './utils/destroy-backbone-view';\nimport isNodeAttached from './common/is-node-attached';\nimport monitorViewEvents from './common/monitor-view-events';\nimport { triggerMethodOn } from './common/trigger-method';\nimport ChildViewContainer from './child-view-container';\nimport MarionetteError from './error';\nimport ViewMixin from './mixins/view';\n\nconst ClassOptions = [\n 'behaviors',\n 'childView',\n 'childViewEventPrefix',\n 'childViewEvents',\n 'childViewOptions',\n 'childViewTriggers',\n 'collectionEvents',\n 'events',\n 'filter',\n 'emptyView',\n 'emptyViewOptions',\n 'modelEvents',\n 'reorderOnSort',\n 'sort',\n 'triggers',\n 'ui',\n 'viewComparator'\n];\n\n// A view that iterates over a Backbone.Collection\n// and renders an individual child view for each model.\nconst CollectionView = Backbone.View.extend({\n\n // flag for maintaining the sorted order of the collection\n sort: true,\n\n // constructor\n // option to pass `{sort: false}` to prevent the `CollectionView` from\n // maintaining the sorted order of the collection.\n // This will fallback onto appending childView's to the end.\n //\n // option to pass `{viewComparator: compFunction()}` to allow the `CollectionView`\n // to use a custom sort order for the collection.\n constructor(options) {\n this.render = _.bind(this.render, this);\n\n this._setOptions(options);\n\n this.mergeOptions(options, ClassOptions);\n\n monitorViewEvents(this);\n\n this._initBehaviors();\n this.once('render', this._initialEvents);\n this._initChildViewStorage();\n this._bufferedChildren = [];\n\n const args = Array.prototype.slice.call(arguments);\n args[0] = this.options;\n Backbone.View.prototype.constructor.apply(this, args);\n\n this.delegateEntityEvents();\n },\n\n // Instead of inserting elements one by one into the page, it's much more performant to insert\n // elements into a document fragment and then insert that document fragment into the page\n _startBuffering() {\n this._isBuffering = true;\n },\n\n _endBuffering() {\n const shouldTriggerAttach = !!this._isAttached;\n const triggerOnChildren = shouldTriggerAttach ? this._getImmediateChildren() : [];\n\n this._isBuffering = false;\n\n _.each(triggerOnChildren, child => {\n triggerMethodOn(child, 'before:attach', child);\n });\n\n this.attachBuffer(this, this._createBuffer());\n\n _.each(triggerOnChildren, child => {\n child._isAttached = true;\n triggerMethodOn(child, 'attach', child);\n });\n\n this._bufferedChildren = [];\n },\n\n _getImmediateChildren() {\n return _.values(this.children._views);\n },\n\n // Configured the initial events that the collection view binds to.\n _initialEvents() {\n if (this.collection) {\n this.listenTo(this.collection, 'add', this._onCollectionAdd);\n this.listenTo(this.collection, 'update', this._onCollectionUpdate);\n this.listenTo(this.collection, 'reset', this.render);\n\n if (this.sort) {\n this.listenTo(this.collection, 'sort', this._sortViews);\n }\n }\n },\n\n // Handle a child added to the collection\n _onCollectionAdd(child, collection, opts) {\n // `index` is present when adding with `at` since BB 1.2; indexOf fallback for < 1.2\n let index = opts.at !== undefined && (opts.index || collection.indexOf(child));\n\n // When filtered or when there is no initial index, calculate index.\n if (this.filter || index === false) {\n index = _.indexOf(this._filteredSortedModels(index), child);\n }\n\n if (this._shouldAddChild(child, index)) {\n this._destroyEmptyView();\n this._addChild(child, index)\n }\n },\n\n // Handle collection update model removals\n _onCollectionUpdate(collection, options) {\n const changes = options.changes;\n this._removeChildModels(changes.removed);\n },\n\n // Remove the child views and destroy them.\n // This function also updates the indices of later views\n // in the collection in order to keep the children in sync with the collection.\n // \"models\" is an array of models and the corresponding views\n // will be removed and destroyed from the CollectionView\n _removeChildModels(models, {checkEmpty} = {}) {\n const shouldCheckEmpty = checkEmpty !== false;\n\n // Used to determine where to update the remaining\n // sibling view indices after these views are removed.\n const removedViews = this._getRemovedViews(models);\n\n if (!removedViews.length) {\n return;\n }\n\n this.children._updateLength();\n\n // decrement the index of views after this one\n this._updateIndices(removedViews, false);\n\n if (shouldCheckEmpty) {\n this._checkEmpty();\n }\n },\n\n // Returns the views that will be used for re-indexing\n // through CollectionView#_updateIndices.\n _getRemovedViews(models) {\n\n // Returning a view means something was removed.\n return _.reduce(models, (removingViews, model) => {\n const view = this.children.findByModel(model);\n\n if (!view || view._isDestroyed) {\n return removingViews;\n }\n\n this._removeChildView(view);\n\n removingViews.push(view);\n\n return removingViews;\n }, []);\n },\n\n _findGreatestIndexedView(views) {\n\n return _.reduce(views, (greatestIndexedView, view) => {\n // Even if the index is `undefined`, a view will get returned.\n if (!greatestIndexedView || greatestIndexedView._index < view._index) {\n return view;\n }\n\n return greatestIndexedView;\n }, undefined);\n },\n\n _removeChildView(view) {\n this.triggerMethod('before:remove:child', this, view);\n\n this.children._remove(view);\n if (view.destroy) {\n view.destroy();\n } else {\n destroyBackboneView(view);\n }\n\n delete view._parent;\n this.stopListening(view);\n this.triggerMethod('remove:child', this, view);\n },\n\n // Overriding Backbone.View's `setElement` to handle\n // if an el was previously defined. If so, the view might be\n // attached on setElement.\n setElement() {\n const hasEl = !!this.el;\n\n Backbone.View.prototype.setElement.apply(this, arguments);\n\n if (hasEl) {\n this._isAttached = isNodeAttached(this.el);\n }\n\n return this;\n },\n\n // Render children views. Override this method to provide your own implementation of a\n // render function for the collection view.\n render() {\n this._ensureViewIsIntact();\n this.triggerMethod('before:render', this);\n this._renderChildren();\n this._isRendered = true;\n this.triggerMethod('render', this);\n return this;\n },\n\n // An efficient rendering used for filtering. Instead of modifying the whole DOM for the\n // collection view, we are only adding or removing the related childrenViews.\n setFilter(filter, {preventRender} = {}) {\n const canBeRendered = this._isRendered && !this._isDestroyed;\n const filterChanged = this.filter !== filter;\n const shouldRender = canBeRendered && filterChanged && !preventRender;\n\n if (shouldRender) {\n const previousModels = this._filteredSortedModels();\n this.filter = filter;\n const models = this._filteredSortedModels();\n this._applyModelDeltas(models, previousModels);\n } else {\n this.filter = filter;\n }\n\n return this;\n },\n\n // `removeFilter` is actually an alias for removing filters.\n removeFilter(options) {\n return this.setFilter(null, options);\n },\n\n // Calculate and apply difference by cid between `models` and `previousModels`.\n _applyModelDeltas(models, previousModels) {\n const currentIds = {};\n _.each(models, (model, index) => {\n const addedChildNotExists = !this.children.findByModel(model);\n if (addedChildNotExists) {\n this._onCollectionAdd(model, this.collection, {at: index});\n }\n currentIds[model.cid] = true;\n });\n\n const removeModels = _.filter(previousModels, (prevModel) => {\n return !currentIds[prevModel.cid] && this.children.findByModel(prevModel);\n });\n\n this._removeChildModels(removeModels);\n },\n\n // Reorder DOM after sorting. When your element's rendering do not use their index,\n // you can pass reorderOnSort: true to only reorder the DOM after a sort instead of\n // rendering all the collectionView.\n reorder() {\n const children = this.children;\n const models = this._filteredSortedModels();\n\n if (!models.length && this._showingEmptyView) { return this; }\n\n const anyModelsAdded = _.some(models, function(model) {\n return !children.findByModel(model);\n });\n\n // If there are any new models added due to filtering we need to add child views,\n // so render as normal.\n if (anyModelsAdded) {\n this.render();\n } else {\n\n const filteredOutModels = [];\n\n // Get the DOM nodes in the same order as the models and\n // find the model that were children before but aren't in this new order.\n const elsToReorder = children.reduce(function(viewEls, view) {\n const index = _.indexOf(models, view.model);\n\n if (index === -1) {\n filteredOutModels.push(view.model);\n return viewEls;\n }\n\n view._index = index;\n\n viewEls[index] = view.el;\n\n return viewEls;\n }, new Array(models.length));\n\n this.triggerMethod('before:reorder', this);\n\n // Since append moves elements that are already in the DOM, appending the elements\n // will effectively reorder them.\n this._appendReorderedChildren(elsToReorder);\n\n // remove any views that have been filtered out\n this._removeChildModels(filteredOutModels);\n\n this.triggerMethod('reorder', this);\n }\n return this;\n },\n\n // Render view after sorting. Override this method to change how the view renders\n // after a `sort` on the collection.\n resortView() {\n if (this.reorderOnSort) {\n this.reorder();\n } else {\n this._renderChildren();\n }\n return this;\n },\n\n // Internal method. This checks for any changes in the order of the collection.\n // If the index of any view doesn't match, it will render.\n _sortViews() {\n const models = this._filteredSortedModels();\n\n // check for any changes in sort order of views\n const orderChanged = _.find(models, (item, index) => {\n const view = this.children.findByModel(item);\n return !view || view._index !== index;\n });\n\n if (orderChanged) {\n this.resortView();\n }\n },\n\n // Internal reference to what index a `emptyView` is.\n _emptyViewIndex: -1,\n\n // Internal method. Separated so that CompositeView can append to the childViewContainer\n // if necessary\n _appendReorderedChildren(children) {\n this.$el.append(children);\n },\n\n // Internal method. Separated so that CompositeView can have more control over events\n // being triggered, around the rendering process\n _renderChildren() {\n if (this._isRendered) {\n this._destroyEmptyView();\n this._destroyChildren({checkEmpty: false});\n }\n\n const models = this._filteredSortedModels();\n if (this.isEmpty({processedModels: models})) {\n this._showEmptyView();\n } else {\n this.triggerMethod('before:render:children', this);\n this._startBuffering();\n this._showCollection(models);\n this._endBuffering();\n this.triggerMethod('render:children', this);\n }\n },\n\n _createView(model, index) {\n const ChildView = this._getChildView(model);\n const childViewOptions = this._getChildViewOptions(model, index);\n const view = this.buildChildView(model, ChildView, childViewOptions);\n return view;\n },\n\n _setupChildView(view, index) {\n view._parent = this;\n\n monitorViewEvents(view);\n\n // set up the child view event forwarding\n this._proxyChildEvents(view);\n\n if (this.sort) {\n view._index = index;\n }\n },\n\n // Internal method to loop through collection and show each child view.\n _showCollection(models) {\n _.each(models, _.bind(this._addChild, this));\n this.children._updateLength();\n },\n\n // Allow the collection to be sorted by a custom view comparator\n _filteredSortedModels(addedAt) {\n if (!this.collection || !this.collection.length) { return []; }\n\n const viewComparator = this.getViewComparator();\n let models = this.collection.models;\n addedAt = Math.min(Math.max(addedAt, 0), models.length - 1);\n\n if (viewComparator) {\n let addedModel;\n // Preserve `at` location, even for a sorted view\n if (addedAt) {\n addedModel = models[addedAt];\n models = models.slice(0, addedAt).concat(models.slice(addedAt + 1));\n }\n models = this._sortModelsBy(models, viewComparator);\n if (addedModel) {\n models.splice(addedAt, 0, addedModel);\n }\n }\n\n // Filter after sorting in case the filter uses the index\n models = this._filterModels(models);\n\n return models;\n },\n\n getViewComparator() {\n return this.viewComparator;\n },\n\n // Filter an array of models, if a filter exists\n _filterModels(models) {\n if (this.filter) {\n models = _.filter(models, (model, index) => {\n return this._shouldAddChild(model, index);\n });\n }\n return models;\n },\n\n _sortModelsBy(models, comparator) {\n if (typeof comparator === 'string') {\n return _.sortBy(models, (model) => {\n return model.get(comparator);\n });\n } else if (comparator.length === 1) {\n return _.sortBy(models, _.bind(comparator, this));\n } else {\n return models.sort(_.bind(comparator, this));\n }\n },\n\n // Internal method to show an empty view in place of a collection of child views,\n // when the collection is empty\n _showEmptyView() {\n const EmptyView = this._getEmptyView();\n\n if (EmptyView && !this._showingEmptyView) {\n this._showingEmptyView = true;\n\n const model = new Backbone.Model();\n let emptyViewOptions =\n this.emptyViewOptions || this.childViewOptions;\n if (_.isFunction(emptyViewOptions)) {\n emptyViewOptions = emptyViewOptions.call(this, model, this._emptyViewIndex);\n }\n\n const view = this.buildChildView(model, EmptyView, emptyViewOptions);\n\n this.triggerMethod('before:render:empty', this, view);\n this.addChildView(view, 0);\n this.triggerMethod('render:empty', this, view);\n }\n },\n\n // Internal method to destroy an existing emptyView instance if one exists. Called when\n // a collection view has been rendered empty, and then a child is added to the collection.\n _destroyEmptyView() {\n if (this._showingEmptyView) {\n this.triggerMethod('before:remove:empty', this);\n\n this._destroyChildren();\n delete this._showingEmptyView;\n\n this.triggerMethod('remove:empty', this);\n }\n },\n\n // Retrieve the empty view class\n _getEmptyView() {\n const emptyView = this.emptyView;\n\n if (!emptyView) { return; }\n\n return this._getView(emptyView);\n },\n\n // Retrieve the `childView` class\n // The `childView` property can be either a view class or a function that\n // returns a view class. If it is a function, it will receive the model that\n // will be passed to the view instance (created from the returned view class)\n _getChildView(child) {\n let childView = this.childView;\n\n if (!childView) {\n throw new MarionetteError({\n name: 'NoChildViewError',\n message: 'A \"childView\" must be specified'\n });\n }\n\n childView = this._getView(childView, child);\n\n if (!childView) {\n throw new MarionetteError({\n name: 'InvalidChildViewError',\n message: '\"childView\" must be a view class or a function that returns a view class'\n });\n }\n\n return childView;\n },\n\n // First check if the `view` is a view class (the common case)\n // Then check if it's a function (which we assume that returns a view class)\n _getView(view, child) {\n if (view.prototype instanceof Backbone.View || view === Backbone.View) {\n return view;\n } else if (_.isFunction(view)) {\n return view.call(this, child);\n }\n },\n\n // Internal method for building and adding a child view\n _addChild(child, index) {\n const view = this._createView(child, index);\n this.addChildView(view, index);\n\n return view;\n },\n\n _getChildViewOptions(child, index) {\n if (_.isFunction(this.childViewOptions)) {\n return this.childViewOptions(child, index);\n }\n\n return this.childViewOptions;\n },\n\n // Render the child's view and add it to the HTML for the collection view at a given index.\n // This will also update the indices of later views in the collection in order to keep the\n // children in sync with the collection.\n addChildView(view, index) {\n this.triggerMethod('before:add:child', this, view);\n this._setupChildView(view, index);\n\n // Store the child view itself so we can properly remove and/or destroy it later\n if (this._isBuffering) {\n // Add to children, but don't update children's length.\n this.children._add(view);\n } else {\n // increment indices of views after this one\n this._updateIndices(view, true);\n this.children.add(view);\n }\n\n this._renderView(view);\n\n this._attachView(view, index);\n\n this.triggerMethod('add:child', this, view);\n\n return view;\n },\n\n // Internal method. This decrements or increments the indices of views after the added/removed\n // view to keep in sync with the collection.\n _updateIndices(views, increment) {\n if (!this.sort) {\n return;\n }\n\n const view = _.isArray(views) ? this._findGreatestIndexedView(views) : views;\n\n // update the indexes of views after this one\n this.children.each((laterView) => {\n if (laterView._index >= view._index) {\n laterView._index += increment ? 1 : -1;\n }\n });\n },\n\n _renderView(view) {\n if (view._isRendered) {\n return;\n }\n\n if (!view.supportsRenderLifecycle) {\n triggerMethodOn(view, 'before:render', view);\n }\n\n view.render();\n\n if (!view.supportsRenderLifecycle) {\n view._isRendered = true;\n triggerMethodOn(view, 'render', view);\n }\n },\n\n _attachView(view, index) {\n // Only trigger attach if already attached and not buffering,\n // otherwise _endBuffering() or Region#show() handles this.\n const shouldTriggerAttach = !view._isAttached && !this._isBuffering && this._isAttached;\n\n if (shouldTriggerAttach) {\n triggerMethodOn(view, 'before:attach', view);\n }\n\n this.attachHtml(this, view, index);\n\n if (shouldTriggerAttach) {\n view._isAttached = true;\n triggerMethodOn(view, 'attach', view);\n }\n },\n\n // Build a `childView` for a model in the collection.\n buildChildView(child, ChildViewClass, childViewOptions) {\n const options = _.extend({model: child}, childViewOptions);\n return new ChildViewClass(options);\n },\n\n // Remove the child view and destroy it. This function also updates the indices of later views\n // in the collection in order to keep the children in sync with the collection.\n removeChildView(view) {\n if (!view || view._isDestroyed) {\n return view;\n }\n\n this._removeChildView(view);\n this.children._updateLength();\n // decrement the index of views after this one\n this._updateIndices(view, false);\n return view;\n },\n\n // check if the collection is empty or optionally whether an array of pre-processed models is empty\n isEmpty(options) {\n let models;\n if (_.result(options, 'processedModels')) {\n models = options.processedModels;\n } else {\n models = this.collection ? this.collection.models : [];\n models = this._filterModels(models);\n }\n return models.length === 0;\n },\n\n // If empty, show the empty view\n _checkEmpty() {\n if (this.isEmpty()) {\n this._showEmptyView();\n }\n },\n\n // You might need to override this if you've overridden attachHtml\n attachBuffer(collectionView, buffer) {\n collectionView.$el.append(buffer);\n },\n\n // Create a fragment buffer from the currently buffered children\n _createBuffer() {\n const elBuffer = document.createDocumentFragment();\n _.each(this._bufferedChildren, (b) => {\n elBuffer.appendChild(b.el);\n });\n return elBuffer;\n },\n\n // Append the HTML to the collection's `el`. Override this method to do something other\n // than `.append`.\n attachHtml(collectionView, childView, index) {\n if (collectionView._isBuffering) {\n // buffering happens on reset events and initial renders\n // in order to reduce the number of inserts into the\n // document, which are expensive.\n collectionView._bufferedChildren.splice(index, 0, childView);\n } else {\n // If we've already rendered the main collection, append\n // the new child into the correct order if we need to. Otherwise\n // append to the end.\n if (!collectionView._insertBefore(childView, index)) {\n collectionView._insertAfter(childView);\n }\n }\n },\n\n // Internal method. Check whether we need to insert the view into the correct position.\n _insertBefore(childView, index) {\n let currentView;\n const findPosition = this.sort && (index < this.children.length - 1);\n if (findPosition) {\n // Find the view after this one\n currentView = this.children.find((view) => {\n return view._index === index + 1;\n });\n }\n\n if (currentView) {\n currentView.$el.before(childView.el);\n return true;\n }\n\n return false;\n },\n\n // Internal method. Append a view to the end of the $el\n _insertAfter(childView) {\n this.$el.append(childView.el);\n },\n\n // Internal method to set up the `children` object for storing all of the child views\n _initChildViewStorage() {\n this.children = new ChildViewContainer();\n },\n\n // called by ViewMixin destroy\n _removeChildren() {\n this._destroyChildren({checkEmpty: false});\n },\n\n // Destroy the child views that this collection view is holding on to, if any\n _destroyChildren(options) {\n if (!this.children.length) {\n return;\n }\n\n this.triggerMethod('before:destroy:children', this);\n const childModels = this.children.map('model');\n this._removeChildModels(childModels, options);\n this.triggerMethod('destroy:children', this);\n },\n\n // Return true if the given child should be shown. Return false otherwise.\n // The filter will be passed (child, index, collection), where\n // 'child' is the given model\n // 'index' is the index of that model in the collection\n // 'collection' is the collection referenced by this CollectionView\n _shouldAddChild(child, index) {\n const filter = this.filter;\n return !_.isFunction(filter) || filter.call(this, child, index, this.collection);\n },\n\n // Set up the child view event forwarding. Uses a \"childview:\" prefix in front of all forwarded events.\n _proxyChildEvents(view) {\n this.listenTo(view, 'all', this._childViewEventHandler);\n }\n});\n\n_.extend(CollectionView.prototype, ViewMixin);\n\nexport default CollectionView;\n","// Composite View\n// --------------\n\nimport _ from 'underscore';\nimport deprecate from './utils/deprecate';\nimport MarionetteError from './error';\nimport CollectionView from './collection-view';\nimport View from './view';\n\nconst ClassOptions = [\n 'childViewContainer',\n 'template',\n 'templateContext'\n];\n\n// Used for rendering a branch-leaf, hierarchical structure.\n// Extends directly from CollectionView\n// @deprecated\nconst CompositeView = CollectionView.extend({\n\n // Setting up the inheritance chain which allows changes to\n // Marionette.CollectionView.prototype.constructor which allows overriding\n // option to pass '{sort: false}' to prevent the CompositeView from\n // maintaining the sorted order of the collection.\n // This will fallback onto appending childView's to the end.\n constructor(options) {\n deprecate('CompositeView is deprecated. Convert to View at your earliest convenience');\n\n this.mergeOptions(options, ClassOptions);\n\n CollectionView.prototype.constructor.apply(this, arguments);\n },\n\n // Configured the initial events that the composite view\n // binds to. Override this method to prevent the initial\n // events, or to add your own initial events.\n _initialEvents() {\n\n // Bind only after composite view is rendered to avoid adding child views\n // to nonexistent childViewContainer\n\n if (this.collection) {\n this.listenTo(this.collection, 'add', this._onCollectionAdd);\n this.listenTo(this.collection, 'update', this._onCollectionUpdate);\n this.listenTo(this.collection, 'reset', this.renderChildren);\n\n if (this.sort) {\n this.listenTo(this.collection, 'sort', this._sortViews);\n }\n }\n },\n\n // Retrieve the `childView` to be used when rendering each of\n // the items in the collection. The default is to return\n // `this.childView` or Marionette.CompositeView if no `childView`\n // has been defined. As happens in CollectionView, `childView` can\n // be a function (which should return a view class).\n _getChildView(child) {\n let childView = this.childView;\n\n // for CompositeView, if `childView` is not specified, we'll get the same\n // composite view class rendered for each child in the collection\n // then check if the `childView` is a view class (the common case)\n // finally check if it's a function (which we assume that returns a view class)\n if (!childView) {\n return this.constructor;\n }\n\n childView = this._getView(childView, child);\n\n if (!childView) {\n throw new MarionetteError({\n name: 'InvalidChildViewError',\n message: '\"childView\" must be a view class or a function that returns a view class'\n });\n }\n\n return childView;\n },\n\n // Return the serialized model\n serializeData() {\n return this.serializeModel();\n },\n\n // Renders the model and the collection.\n render() {\n this._ensureViewIsIntact();\n this._isRendering = true;\n this.resetChildViewContainer();\n\n this.triggerMethod('before:render', this);\n\n this._renderTemplate();\n this.bindUIElements();\n this.renderChildren();\n\n this._isRendering = false;\n this._isRendered = true;\n this.triggerMethod('render', this);\n return this;\n },\n\n renderChildren() {\n if (this._isRendered || this._isRendering) {\n CollectionView.prototype._renderChildren.call(this);\n }\n },\n\n // You might need to override this if you've overridden attachHtml\n attachBuffer(compositeView, buffer) {\n const $container = this.getChildViewContainer(compositeView);\n $container.append(buffer);\n },\n\n // Internal method. Append a view to the end of the $el.\n // Overidden from CollectionView to ensure view is appended to\n // childViewContainer\n _insertAfter(childView) {\n const $container = this.getChildViewContainer(this, childView);\n $container.append(childView.el);\n },\n\n // Internal method. Append reordered childView'.\n // Overidden from CollectionView to ensure reordered views\n // are appended to childViewContainer\n _appendReorderedChildren(children) {\n const $container = this.getChildViewContainer(this);\n $container.append(children);\n },\n\n // Internal method to ensure an `$childViewContainer` exists, for the\n // `attachHtml` method to use.\n getChildViewContainer(containerView, childView) {\n if (!!containerView.$childViewContainer) {\n return containerView.$childViewContainer;\n }\n\n let container;\n const childViewContainer = containerView.childViewContainer;\n if (childViewContainer) {\n\n const selector = _.result(containerView, 'childViewContainer');\n\n if (selector.charAt(0) === '@' && containerView.ui) {\n container = containerView.ui[selector.substr(4)];\n } else {\n container = containerView.$(selector);\n }\n\n if (container.length <= 0) {\n throw new MarionetteError({\n name: 'ChildViewContainerMissingError',\n message: `The specified \"childViewContainer\" was not found: ${containerView.childViewContainer}`\n });\n }\n\n } else {\n container = containerView.$el;\n }\n\n containerView.$childViewContainer = container;\n return container;\n },\n\n // Internal method to reset the `$childViewContainer` on render\n resetChildViewContainer() {\n if (this.$childViewContainer) {\n this.$childViewContainer = undefined;\n }\n }\n});\n\n// To prevent duplication but allow the best View organization\n// Certain View methods are mixed directly into the deprecated CompositeView\nconst MixinFromView = _.pick(View.prototype, 'serializeModel', 'getTemplate', '_renderTemplate', 'mixinTemplateContext', 'attachElContent');\n_.extend(CompositeView.prototype, MixinFromView);\n\nexport default CompositeView;\n","// Behavior\n// --------\n\n// A Behavior is an isolated set of DOM /\n// user interactions that can be mixed into any View.\n// Behaviors allow you to blackbox View specific interactions\n// into portable logical chunks, keeping your views simple and your code DRY.\n\nimport _ from 'underscore';\nimport getUniqueEventName from './utils/get-unique-event-name';\nimport MarionetteObject from './object';\nimport DelegateEntityEventsMixin from './mixins/delegate-entity-events';\nimport TriggersMixin from './mixins/triggers';\nimport UIMixin from './mixins/ui';\n\nconst ClassOptions = [\n 'collectionEvents',\n 'events',\n 'modelEvents',\n 'triggers',\n 'ui'\n];\n\nconst Behavior = MarionetteObject.extend({\n cidPrefix: 'mnb',\n\n constructor(options, view) {\n // Setup reference to the view.\n // this comes in handle when a behavior\n // wants to directly talk up the chain\n // to the view.\n this.view = view;\n this.defaults = _.clone(_.result(this, 'defaults', {}));\n this._setOptions(this.defaults, options);\n this.mergeOptions(this.options, ClassOptions);\n\n // Construct an internal UI hash using\n // the behaviors UI hash and then the view UI hash.\n // This allows the user to use UI hash elements\n // defined in the parent view as well as those\n // defined in the given behavior.\n // This order will help the reuse and share of a behavior\n // between multiple views, while letting a view override a\n // selector under an UI key.\n this.ui = _.extend({}, _.result(this, 'ui'), _.result(view, 'ui'));\n\n MarionetteObject.apply(this, arguments);\n },\n\n // proxy behavior $ method to the view\n // this is useful for doing jquery DOM lookups\n // scoped to behaviors view.\n $() {\n return this.view.$.apply(this.view, arguments);\n },\n\n // Stops the behavior from listening to events.\n // Overrides Object#destroy to prevent additional events from being triggered.\n destroy() {\n this.stopListening();\n\n return this;\n },\n\n proxyViewProperties() {\n this.$el = this.view.$el;\n this.el = this.view.el;\n\n return this;\n },\n\n bindUIElements() {\n this._bindUIElements();\n\n return this;\n },\n\n unbindUIElements() {\n this._unbindUIElements();\n\n return this;\n },\n\n getUI(name) {\n this.view._ensureViewIsIntact();\n return this._getUI(name);\n },\n\n // Handle `modelEvents`, and `collectionEvents` configuration\n delegateEntityEvents() {\n this._delegateEntityEvents(this.view.model, this.view.collection);\n\n return this;\n },\n\n undelegateEntityEvents() {\n this._undelegateEntityEvents(this.view.model, this.view.collection);\n\n return this;\n },\n\n getEvents() {\n // Normalize behavior events hash to allow\n // a user to use the @ui. syntax.\n const behaviorEvents = this.normalizeUIKeys(_.result(this, 'events'));\n\n // binds the handler to the behavior and builds a unique eventName\n return _.reduce(behaviorEvents, (events, behaviorHandler, key) => {\n if (!_.isFunction(behaviorHandler)) {\n behaviorHandler = this[behaviorHandler];\n }\n if (!behaviorHandler) { return; }\n key = getUniqueEventName(key);\n events[key] = _.bind(behaviorHandler, this);\n return events;\n }, {});\n },\n\n // Internal method to build all trigger handlers for a given behavior\n getTriggers() {\n if (!this.triggers) { return; }\n\n // Normalize behavior triggers hash to allow\n // a user to use the @ui. syntax.\n const behaviorTriggers = this.normalizeUIKeys(_.result(this, 'triggers'));\n\n return this._getViewTriggers(this.view, behaviorTriggers);\n }\n\n});\n\n_.extend(Behavior.prototype, DelegateEntityEventsMixin, TriggersMixin, UIMixin);\n\nexport default Behavior;\n","// Application\n// -----------\nimport buildRegion from './common/build-region';\nimport MarionetteObject from './object';\nimport Region from './region';\n\nconst ClassOptions = [\n 'region',\n 'regionClass'\n];\n\n// A container for a Marionette application.\nconst Application = MarionetteObject.extend({\n cidPrefix: 'mna',\n\n constructor(options) {\n this._setOptions(options);\n\n this.mergeOptions(options, ClassOptions);\n\n this._initRegion();\n\n MarionetteObject.prototype.constructor.apply(this, arguments);\n },\n\n regionClass: Region,\n\n _initRegion() {\n const region = this.region;\n\n if (!region) { return; }\n\n const defaults = {\n regionClass: this.regionClass\n };\n\n this._region = buildRegion(region, defaults);\n },\n\n getRegion() {\n return this._region;\n },\n\n showView(view, ...args) {\n const region = this.getRegion();\n return region.show(view, ...args);\n },\n\n getView() {\n return this.getRegion().currentView;\n },\n\n // kick off all of the application's processes.\n start(options) {\n this.triggerMethod('before:start', this, options);\n this.triggerMethod('start', this, options);\n return this;\n }\n\n});\n\nexport default Application;\n","// App Router\n// ----------\n\n// Reduce the boilerplate code of handling route events\n// and then calling a single method on another object,\n// called a controller.\n// Have your routers configured to call the method on\n// your controller, directly.\n//\n// Configure an AppRouter with `appRoutes`.\n//\n// App routers can only take one `controller` object.\n// It is recommended that you divide your controller\n// objects in to smaller pieces of related functionality\n// and have multiple routers / controllers, instead of\n// just one giant router and controller.\n//\n// You can also add standard routes to an AppRouter.\n\nimport Backbone from 'backbone';\nimport _ from 'underscore';\nimport { triggerMethod } from './common/trigger-method';\nimport MarionetteError from './error';\nimport CommonMixin from './mixins/common';\n\nconst ClassOptions = [\n 'appRoutes',\n 'controller'\n];\n\nconst AppRouter = Backbone.Router.extend({\n\n constructor(options) {\n this._setOptions(options);\n\n this.mergeOptions(options, ClassOptions);\n\n Backbone.Router.apply(this, arguments);\n\n const appRoutes = this.appRoutes;\n const controller = this._getController();\n this.processAppRoutes(controller, appRoutes);\n this.on('route', this._processOnRoute, this);\n },\n\n // Similar to route method on a Backbone Router but\n // method is called on the controller\n appRoute(route, methodName) {\n const controller = this._getController();\n this._addAppRoute(controller, route, methodName);\n return this;\n },\n\n // process the route event and trigger the onRoute\n // method call, if it exists\n _processOnRoute(routeName, routeArgs) {\n // make sure an onRoute before trying to call it\n if (_.isFunction(this.onRoute)) {\n // find the path that matches the current route\n const routePath = _.invert(this.appRoutes)[routeName];\n this.onRoute(routeName, routePath, routeArgs);\n }\n },\n\n // Internal method to process the `appRoutes` for the\n // router, and turn them in to routes that trigger the\n // specified method on the specified `controller`.\n processAppRoutes(controller, appRoutes) {\n if (!appRoutes) { return this; }\n\n const routeNames = _.keys(appRoutes).reverse(); // Backbone requires reverted order of routes\n\n _.each(routeNames, route => {\n this._addAppRoute(controller, route, appRoutes[route]);\n });\n\n return this;\n },\n\n _getController() {\n return this.controller;\n },\n\n _addAppRoute(controller, route, methodName) {\n const method = controller[methodName];\n\n if (!method) {\n throw new MarionetteError(`Method \"${methodName}\" was not found on the controller`);\n }\n\n this.route(route, methodName, _.bind(method, controller));\n },\n\n triggerMethod: triggerMethod\n});\n\n_.extend(AppRouter.prototype, CommonMixin);\n\nexport default AppRouter;\n","import Backbone from 'backbone';\nimport {version} from '../package.json';\n\nimport proxy from './utils/proxy';\nimport extend from './utils/extend';\nimport deprecate from './utils/deprecate';\n\nimport isNodeAttached from './common/is-node-attached';\nimport mergeOptions from './common/merge-options';\nimport getOption from './common/get-option';\nimport normalizeMethods from './common/normalize-methods';\nimport monitorViewEvents from './common/monitor-view-events';\n\nimport {\n bindEvents,\n unbindEvents\n} from './common/bind-events';\n\nimport {\n bindRequests,\n unbindRequests\n} from './common/bind-requests';\n\nimport {\n triggerMethod,\n triggerMethodOn\n} from './common/trigger-method';\n\n\nimport MarionetteObject from './object';\nimport TemplateCache from './template-cache';\nimport View from './view';\nimport CollectionView from './collection-view';\nimport CompositeView from './composite-view';\nimport Behavior from './behavior';\nimport Region from './region';\nimport Application from './application';\nimport AppRouter from './app-router';\nimport MarionetteError from './error';\n\nimport behaviorsLookup from './config/behaviors-lookup';\nimport Renderer from './config/renderer';\n\nimport {\n FEATURES,\n isEnabled,\n setEnabled\n} from './config/features';\n\nconst previousMarionette = Backbone.Marionette;\nconst Marionette = Backbone.Marionette = {};\n\n// This allows you to run multiple instances of Marionette on the same\n// webapp. After loading the new version, call `noConflict()` to\n// get a reference to it. At the same time the old version will be\n// returned to Backbone.Marionette.\nMarionette.noConflict = function() {\n Backbone.Marionette = previousMarionette;\n return this;\n};\n\n// Utilities\nMarionette.bindEvents = proxy(bindEvents);\nMarionette.unbindEvents = proxy(unbindEvents);\nMarionette.bindRequests = proxy(bindRequests);\nMarionette.unbindRequests = proxy(unbindRequests);\nMarionette.mergeOptions = proxy(mergeOptions);\nMarionette.getOption = proxy(getOption);\nMarionette.normalizeMethods = proxy(normalizeMethods);\nMarionette.extend = extend;\nMarionette.isNodeAttached = isNodeAttached;\nMarionette.deprecate = deprecate;\nMarionette.triggerMethod = proxy(triggerMethod);\nMarionette.triggerMethodOn = triggerMethodOn;\nMarionette.isEnabled = isEnabled;\nMarionette.setEnabled = setEnabled;\nMarionette.monitorViewEvents = monitorViewEvents;\n\nMarionette.Behaviors = {};\nMarionette.Behaviors.behaviorsLookup = behaviorsLookup;\n\n// Classes\nMarionette.Application = Application;\nMarionette.AppRouter = AppRouter;\nMarionette.Renderer = Renderer;\nMarionette.TemplateCache = TemplateCache;\nMarionette.View = View;\nMarionette.CollectionView = CollectionView;\nMarionette.CompositeView = CompositeView;\nMarionette.Behavior = Behavior;\nMarionette.Region = Region;\nMarionette.Error = MarionetteError;\nMarionette.Object = MarionetteObject;\n\n// Configuration\nMarionette.DEV_MODE = false;\nMarionette.FEATURES = FEATURES;\nMarionette.VERSION = version;\n\nexport default Marionette;\n"],"sourceRoot":"/source/"} \ No newline at end of file
diff --git a/js/vendor/backbone.marionette/license.txt b/js/vendor/backbone.marionette/license.txt
new file mode 100644
index 000000000..b95239c6e
--- /dev/null
+++ b/js/vendor/backbone.marionette/license.txt
@@ -0,0 +1 @@
+MarionetteJS is distributed under [MIT license](http://mutedsolutions.mit-license.org/).
diff --git a/js/vendor/backbone.marionette/marionette-logo.png b/js/vendor/backbone.marionette/marionette-logo.png
new file mode 100644
index 000000000..66466e2de
--- /dev/null
+++ b/js/vendor/backbone.marionette/marionette-logo.png
Binary files differ
diff --git a/js/vendor/backbone.marionette/package.json b/js/vendor/backbone.marionette/package.json
new file mode 100644
index 000000000..738e99f9b
--- /dev/null
+++ b/js/vendor/backbone.marionette/package.json
@@ -0,0 +1,90 @@
+{
+ "name": "backbone.marionette",
+ "description": "The Backbone Framework",
+ "version": "3.1.0",
+ "homepage": "https://github.com/marionettejs/backbone.marionette",
+ "main": "lib/backbone.marionette.js",
+ "keywords": [
+ "backbone",
+ "plugin",
+ "marionette",
+ "composite",
+ "architecture",
+ "single",
+ "page",
+ "app",
+ "client",
+ "browser"
+ ],
+ "license": "MIT",
+ "scripts": {
+ "build": "gulp build",
+ "coverage": "gulp coverage",
+ "coveralls": "gulp coveralls",
+ "test": "gulp",
+ "test-browser": "gulp test-browser"
+ },
+ "author": {
+ "name": "Derick Bailey",
+ "email": "derickbailey@gmail.com",
+ "url": "http://derickbailey.com/"
+ },
+ "bugs": {
+ "url": "https://github.com/marionettejs/backbone.marionette/issues"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/marionettejs/backbone.marionette.git"
+ },
+ "github": "https://github.com/marionettejs/backbone.marionette",
+ "dependencies": {
+ "backbone.radio": "^2.0.0"
+ },
+ "peerDependencies": {
+ "backbone": "~1.3.3",
+ "underscore": "~1.8.3"
+ },
+ "devDependencies": {
+ "babel-core": "6.17.0",
+ "babel-eslint": "6.0.4",
+ "babel-plugin-transform-regenerator": "6.16.1",
+ "babel-polyfill": "6.6.1",
+ "babel-preset-es2015": "6.16.0",
+ "babel-preset-es2015-rollup": "1.1.1",
+ "babel-register": "6.4.3",
+ "backbone": "1.2.1 - 1.3.x",
+ "chai": "3.4.0",
+ "chai-jq": "0.0.9",
+ "eslint": "3.2.2",
+ "gulp": "3.9.0",
+ "gulp-coveralls": "0.1.4",
+ "gulp-eslint": "3.0.1",
+ "gulp-file": "0.3.0",
+ "gulp-filter": "3.0.1",
+ "gulp-istanbul": "1.0.0",
+ "gulp-lintspaces": "0.4.1",
+ "gulp-livereload": "3.8.1",
+ "gulp-mocha": "3.0.0",
+ "gulp-plumber": "1.0.1",
+ "gulp-rename": "1.2.2",
+ "gulp-sourcemaps": "1.6.0",
+ "gulp-uglify": "2.0.0",
+ "gulp-util": "3.0.7",
+ "isparta": "4.0.0",
+ "jquery": "^3.1.0",
+ "jsdom": "9.4.1",
+ "mocha": "3.0.0",
+ "opn": "4.0.2",
+ "rollup": "0.34.3",
+ "rollup-plugin-babel": "2.6.1",
+ "rollup-plugin-commonjs": "3.3.1",
+ "rollup-plugin-json": "2.0.1",
+ "rollup-plugin-multi-entry": "2.0.1",
+ "rollup-plugin-node-globals": "1.0.6",
+ "rollup-plugin-node-resolve": "2.0.0",
+ "run-sequence": "1.1.5",
+ "sinon": "1.17.2",
+ "sinon-chai": "2.8.0",
+ "underscore": "1.8 - 1.8.3"
+ }
+}
diff --git a/js/vendor/backbone.marionette/readme.md b/js/vendor/backbone.marionette/readme.md
new file mode 100644
index 000000000..b9bed4a4f
--- /dev/null
+++ b/js/vendor/backbone.marionette/readme.md
@@ -0,0 +1,142 @@
+<h1 align="center">Marionette.js</h1>
+<p align="center">
+ <img title="backbone marionette" src='marionette-logo.png' />
+</p>
+<p align="center">The Backbone Framework</p>
+<p align="center">
+ <a title='Build Status' href="https://travis-ci.org/marionettejs/backbone.marionette">
+ <img src='https://secure.travis-ci.org/marionettejs/backbone.marionette.svg?branch=master' />
+ </a>
+ <a href='https://coveralls.io/r/marionettejs/backbone.marionette'>
+ <img src='https://img.shields.io/coveralls/marionettejs/backbone.marionette.svg' alt='Coverage Status' />
+ </a>
+ <a href='https://gitter.im/marionettejs/backbone.marionette?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge'>
+ <img src='https://badges.gitter.im/Join%20Chat.svg' alt='Gitter Chat' />
+ </a>
+</p>
+
+## Marionette v3
+
+Marionette 3 is now available! See our
+[upgrade notes](http://marionettejs.com/docs/v3.0.0) for the differences between
+v2 and v3. Please let us know if you encounter any issues so we can resolve
+them and
+[help us continue work on Marionette!](https://github.com/marionettejs/backbone.marionette/milestones/v3.x)
+
+## About Marionette
+
+Marionette is a composite application library for Backbone.js that
+aims to simplify the construction of large scale JavaScript applications.
+It is a collection of common design and implementation patterns found in
+applications.
+
+## Documentation
+
+All of the documentation for Marionette can be found at
+
+##### [marionettejs.com/docs/current](http://marionettejs.com/docs/current)
+
+### App Architecture On Backbone's Building Blocks
+
+Backbone provides a great set of building blocks for our JavaScript
+applications. It gives us the core constructs that are needed to build
+small apps, organize jQuery DOM events, or create single page apps that
+support mobile devices and large scale enterprise needs. But Backbone is
+not a complete framework. It's a set of building blocks. It leaves
+much of the application design, architecture and scalability to the
+developer, including memory management, view management, and more.
+
+Marionette brings an application architecture to Backbone, along with
+built in view management and memory management. It's designed to be a
+lightweight and flexible library of tools that sits on top of Backbone,
+providing the framework for building a scalable application.
+
+Like Backbone itself, you're not required to use all of Marionette just
+because you want to use some of it. You can pick and choose which features
+you want to use. This allows you to work with other Backbone
+frameworks and plugins easily. It also means that you are not required
+to engage in an all-or-nothing migration to begin using Marionette.
+
+### Chat with us
+
+Find us [on gitter](https://gitter.im/marionettejs/backbone.marionette) or on
+IRC in the FreeNode.net [#marionette channel](http://freenode.net).
+
+We're happy to discuss design patterns and learn how you're using Marionette.
+
+
+### Key Benefits
+
+* Scalable: applications built in modules with event-driven architecture
+* Sensible defaults: Underscore templates are used for view rendering
+* Easily modifiable: works with the specific needs of your application
+* Reduce boilerplate: for all views, including specialized types
+* Create: application visuals at runtime with `Region` and `View` objects
+* Nested: `View`s and `CollectionView`s within visual regions
+* Built-in: memory management and zombie-killing for `View`s, `CollectionViews`a and `Region`s
+* Event-driven architecture: utilizing `Backbone.Radio`
+* Flexible: "as-needed" architecture allowing you to pick and choose what you need
+* And much, much more
+
+## Source Code and Downloads
+
+You can
+[download the latest builds directly](https://github.com/marionettejs/backbone.marionette/tree/v3.0.0/lib)
+or visit the [downloads section on the Marionette website](http://marionettejs.com#download)
+for more downloading options.
+
+#### [MarionetteJS.com](http://marionettejs.com#download)
+
+### NPM and Bower
+
+Marionette is available via bower and npm:
+
+```bash
+# NPM
+npm install backbone.marionette
+
+# Bower
+bower install marionette
+```
+
+## Release Notes And Upgrade Guide
+
+**Changelog**: For change logs and release notes, see the
+[changelog](changelog.md) file.
+
+**Upgrade Guide**: Be sure to read [the upgrade guide](upgradeGuide.md)
+for information on upgrading to the latest version of Marionette.
+
+
+### Annotated Source Code
+
+The source code for Marionette is heavily documented.
+You can read the annotations for all the details of how Marionette works and advice on which methods to override.
+
+##### [View the annotated source code](http://marionettejs.com/annotated-src/backbone.marionette)
+
+## Compatibility and Requirements
+
+MarionetteJS currently works with the following libraries:
+
+* [jQuery](http://jquery.com) v1.8+
+* [Underscore](http://underscorejs.org) v1.8.3
+* [Backbone](http://backbonejs.org) v1.3.3
+* [Backbone.Radio](https://github.com/marionettejs/backbone.radio) v2.0.0+
+
+Marionette has not been tested against any other versions of these
+libraries. You may or may not have success if you use a version other
+than what is listed here.
+
+## How to Contribute
+
+If you would like to contribute to Marionette's source code, please read
+the [guidelines for pull requests and contributions](CONTRIBUTING.md).
+Following these guidelines will help make your contributions easier to
+bring into the next release.
+
+### [Github Issues](https://github.com/marionettejs/backbone.marionette/issues)
+
+Report issues with Marionette, submit pull requests to fix problems, or to
+create summarized and documented feature requests (preferably with pull
+requests that implement the feature).
diff --git a/js/vendor/backbone.marionette/trigger-deploy-mn-com.js b/js/vendor/backbone.marionette/trigger-deploy-mn-com.js
new file mode 100644
index 000000000..a6d44cf2e
--- /dev/null
+++ b/js/vendor/backbone.marionette/trigger-deploy-mn-com.js
@@ -0,0 +1,32 @@
+var Travis = require('travis-ci');
+var repo = 'marionettejs/marionettejs.com';
+var travis = new Travis({
+ version: '2.0.0',
+ headers: {
+ 'User-Agent': 'Travis/1.0'
+ }
+});
+
+travis.authenticate({
+ github_token: process.env.GH_TOKEN
+}, function (err, res) {
+ if (err) {
+ return console.error(err);
+ }
+
+ //get repo builds
+ travis.repos(repo.split('/')[0], repo.split('/')[1]).builds.get(function (err, res) {
+ if (err) {
+ return console.error(err);
+ }
+ //rebuild latest build
+ travis.requests.post({
+ build_id: res.builds[0].id
+ }, function (err, res) {
+ if (err) {
+ return console.error(err);
+ }
+ console.log(res.flash[0].notice);
+ });
+ });
+});
diff --git a/js/vendor/backbone.radio/.bower.json b/js/vendor/backbone.radio/.bower.json
new file mode 100644
index 000000000..b05376acf
--- /dev/null
+++ b/js/vendor/backbone.radio/.bower.json
@@ -0,0 +1,38 @@
+{
+ "name": "backbone.radio",
+ "version": "2.0.0",
+ "homepage": "https://github.com/marionettejs/backbone.radio",
+ "authors": [
+ "Jmeas <jellyes2@gmail.com>"
+ ],
+ "description": "Messaging patterns for Backbone applications.",
+ "main": "build/backbone.radio.js",
+ "keywords": [
+ "backbone",
+ "marionette",
+ "decoupled",
+ "pubsub",
+ "publish",
+ "subscribe",
+ "messaging",
+ "architecture",
+ "spa"
+ ],
+ "license": "MIT",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "_release": "2.0.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v2.0.0",
+ "commit": "8d3c7deec61205daddbd49ce86dbac27afb1aaad"
+ },
+ "_source": "https://github.com/marionettejs/backbone.radio.git",
+ "_target": "^2.0.0",
+ "_originalSource": "backbone.radio"
+} \ No newline at end of file
diff --git a/js/vendor/backbone.radio/CHANGELOG.md b/js/vendor/backbone.radio/CHANGELOG.md
new file mode 100644
index 000000000..b5f1e6e43
--- /dev/null
+++ b/js/vendor/backbone.radio/CHANGELOG.md
@@ -0,0 +1,132 @@
+### [2.0.0](https://github.com/marionettejs/backbone.radio/releases/tag/2.0.0)
+
+- Updated Backbone and Underscore version ranges.
+- Moved Backbone and Underscore to peerDependencies.
+
+### [2.0.0-pre.2](https://github.com/marionettejs/backbone.radio/releases/tag/2.0.0-pre.2)
+
+- Updated Backbone and Underscore version ranges.
+
+### [2.0.0-pre.1](https://github.com/marionettejs/backbone.radio/releases/tag/2.0.0-pre.1)
+
+- Moved Backbone and Underscore to peerDependencies.
+
+### [1.0.5](https://github.com/marionettejs/backbone.radio/releases/tag/1.0.5)
+
+- Updated Backbone dep to allow v1.3.3
+
+### [1.0.4](https://github.com/marionettejs/backbone.radio/releases/tag/1.0.4)
+
+- **Bug fix**: The UMD generated from rollup was setting `global` to `undefined`.
+
+### [1.0.3](https://github.com/marionettejs/backbone.radio/releases/tag/1.0.3)
+
+- Updated Backbone dep to allow v1.3.2
+
+### [1.0.2](https://github.com/marionettejs/backbone.radio/releases/tag/1.0.2)
+
+- Updated Backbone dep to allow v1.2.3
+
+### [1.0.1](https://github.com/marionettejs/backbone.radio/releases/tag/1.0.1)
+
+- Updated Backbone dep to allow v1.2.2
+
+### [1.0.0](https://github.com/jmeas/backbone.radio/releases/tag/v1.0.0)
+
+- **Breaking change**: Commands have been removed. ([see explanation](https://github.com/marionettejs/backbone.radio/pull/221#issuecomment-104782925))
+
+### [0.9.1](https://github.com/jmeas/backbone.radio/releases/tag/v0.9.1)
+
+- **Refactor**: Structure and build using babel-boilerplate
+- Update Underscore and Backbone dependencies to 1.8.3 and 1.2.1 respectively to match Marionette.
+
+### [0.9.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.9.0)
+
+- **Breaking change**: Space-separated requests no longer return an Array. Instead, an Object is returned.
+ ```js
+ // old
+ myChannel.request('thingOne thingTwo');
+ // => [replyOne, replyTwo]
+
+ // new
+ myChannel.request('thingOne thingTwo');
+ // => { thingOne: replyOne, thingTwo: replyTwo }
+ ```
+
+- **New feature**: `Radio.reset()` is now a top-level API method that can be used to reset a channel, or all channels. Do note that channels continue to have their own `reset` method.
+- **New feature**: `Radio.debugLog()` is now exposed...go forth and customize how Radio logs potential errors!
+
+### [0.8.2](https://github.com/jmeas/backbone.radio/releases/tag/v0.8.2)
+
+- **Refactor**: A small refactor to support Underscore 1.4.4 (the lowest version that Marionette supports)
+
+### [0.8.1](https://github.com/jmeas/backbone.radio/releases/tag/v0.8.1)
+
+- **Bug fix**: Fixes bug where `stopComplying` and `stopReplying` would not remove the correct
+ callbacks in certain situations
+
+### [0.8.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.8.0)
+
+- **Feature**: DEBUG now warns when an already-registered Command or Request is overwritten
+- **Feature**: `stopComplying` and `stopReplying` now accept the same arguments as `off`
+
+### [0.7.2](https://github.com/jmeas/backbone.radio/releases/tag/v0.7.2)
+
+- Corrects Underscore dependency in bower.json.
+
+### [0.7.1](https://github.com/jmeas/backbone.radio/releases/tag/v0.7.1)
+
+- Corrects Underscore dependency.
+
+### [0.7.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.7.0)
+
+- **Feature**: All API methods of Commands ands Requests now support the space-separated syntax.
+- **Enhancement**: Only Channels created through Radio's factory method will register themselves on the internal
+ store of Channels
+- **Enhancement**: Callback execution has been optimized
+
+### [0.6.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.6.0)
+
+*This update is not backwards compatible.*
+
+- **Feature:** `channelName` is now a public property on each Channel.
+- **Feature:** Requests and Commands can now have `"default"` handlers which will be called when the specified event isn't registered.
+- **API Change:** The convenience connectX methods have been removed. In their place, the object syntax can be used for registering
+ multiple events on channels. This makes the API of Radio more consistent with Backbone.Events. For instance,
+
+ ```js
+ myChannel.reply({
+ oneRequest: myCallback,
+ anotherRequest: myCallback
+ }, myContext);
+ ```
+
+### [0.5.2](https://github.com/jmeas/backbone.radio/releases/tag/v0.5.2)
+
+- Fixes a bug where the top-level API would not pass the correct arguments to the underlying methods.
+
+### [0.5.1](https://github.com/jmeas/backbone.radio/releases/tag/v0.5.1)
+
+- Fixes Radio.VERSION in the built library
+
+### [0.5.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.5.0)
+
+- Commands.react has been renamed to Commands.comply
+
+### [0.4.1](https://github.com/jmeas/backbone.radio/releases/tag/v0.4.1)
+
+- The Channel convenience methods no longer bind the context, instead deferring that
+responsibility to the wrapped methods themselves. This aids in stack traces and gives you
+the ability to unregister the methods individually.
+
+### [0.4.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.4.0)
+
+- Debug mode now informs you when you attempt to unregister an event that was never registered. This is to help prevent memory leaks.
+- `respond` has been renamed to `reply`
+- More methods now return `this`, making the API more consistent internally, and with Backbone.Events
+
+### [0.3.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.3.0)
+
+- More test coverage
+- Tests completely rewritten
+- Numerous bug fixes; more work on the library
diff --git a/js/vendor/backbone.radio/LICENSE b/js/vendor/backbone.radio/LICENSE
new file mode 100644
index 000000000..eff6bfc6c
--- /dev/null
+++ b/js/vendor/backbone.radio/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 James Smith
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE. \ No newline at end of file
diff --git a/js/vendor/backbone.radio/README.md b/js/vendor/backbone.radio/README.md
new file mode 100644
index 000000000..0eec8c17e
--- /dev/null
+++ b/js/vendor/backbone.radio/README.md
@@ -0,0 +1,353 @@
+# Backbone.Radio
+
+[![Travis Build Status](http://img.shields.io/travis/marionettejs/backbone.radio.svg?style=flat)](https://travis-ci.org/marionettejs/backbone.radio)
+[![Coverage](http://img.shields.io/codeclimate/coverage/github/marionettejs/backbone.radio.svg?style=flat)](https://codeclimate.com/github/marionettejs/backbone.radio)
+[![Dependency Status](http://img.shields.io/david/marionettejs/backbone.radio.svg?style=flat)](https://david-dm.org/marionettejs/backbone.radio)
+[![Gitter chat room](https://img.shields.io/badge/gitter-backbone.radio-brightgreen.svg?style=flat)](https://gitter.im/marionettejs/backbone.radio)
+
+
+Backbone.Radio provides additional messaging patterns for Backbone applications.
+
+Backbone includes an event system, Backbone.Events, which is an implementation of the publish-subscribe pattern. Pub-sub is by far the most
+common event pattern in client-side applications, and for good reason: it is incredibly useful. It should also be familiar to web developers
+in particular, because the DOM relies heavily on pub-sub. Consider, for instance, registering a handler on an element's `click` event. This isn't
+so much different than listening to a Model's `change` event, as both of these situations are using pub-sub.
+
+Backbone.Radio adds two additional messaging-related features. The first is Requests, an implementation of the request-reply pattern. Request-reply
+should also be familiar to web developers, as it's the messaging pattern that backs HTTP communications. The other feature are Channels: explicit
+namespaces to your communications.
+
+## Installation
+
+Clone this repository or install via [Bower](http://bower.io/) or [npm](https://www.npmjs.org/).
+
+```
+bower install backbone.radio
+npm install backbone.radio
+```
+
+You must also ensure that Backbone.Radio's dependencies on Underscore (or Lodash) and Backbone are installed.
+
+## Documentation
+
+- [Getting Started](#getting-started)
+ - [Backbone.Events](#backboneevents)
+ - [Radio.Requests](#backboneradiorequests)
+ - [Channels](#channels)
+ - [Using With Marionette](#using-with-marionette)
+- [API](#api)
+ - [Radio.Requests](#requests)
+ - [Channel](#channel)
+ - [Radio](#radio)
+ - [Top-level API](#top-level-api)
+
+## Getting Started
+
+### Backbone.Events
+
+Anyone who has used Backbone should be quite familiar with Backbone.Events. Backbone.Events is what facilitates
+communications between objects in your application. The quintessential example of this is listening in on a
+Model's change event.
+
+```js
+// Listen in on a model's change events
+this.listenTo(someModel, 'change', myCallback);
+
+// Later on, the model triggers a change event when it has been changed
+someModel.trigger('change');
+```
+
+Let's look at a diagram for Backbone.Events:
+
+<p align='center'>
+ <img src='https://cloud.githubusercontent.com/assets/10248067/11762943/5a927e54-a0bd-11e5-8aa5-e0fafae0e559.png' alt='Backbone.Events diagram'>
+</p>
+
+It goes without saying that Backbone.Events is incredibly useful when you mix it into instances of Classes. But what
+if you had a standalone Object with an instance of Backbone.Events on it? This gives you a powerful message bus to utilize.
+
+```js
+// Create a message bus
+var myBus = _.extend({}, Backbone.Events);
+
+// Listen in on the message bus
+this.listenTo(myBus, 'some:event', myCallback);
+
+// Trigger an event on the bus
+myBus.trigger('some:event');
+```
+
+As long as there was an easy way to access this message bus throughout your entire application, then you would have a central
+place to store a collection of events. This is the idea behind Channels. But before we go more into that, let's take a look at Requests.
+
+### Backbone.Radio.Requests
+
+Requests is similar to Events in that it's another event system. And it has a similar API, too. For this reason, you *could* mix
+it into an object.
+
+```js
+_.extend(myView, Backbone.Radio.Requests);
+```
+
+Although this works, I wouldn't recommend it. Requests are most useful, I think, when they're used with a Channel.
+
+Perhaps the biggest difference between Events and Requests is that Requests have *intention*. Unlike Events, which notify
+nothing in particular about an occurrence, Requests are asking for a very specific thing to occur. As a consequence of this,
+requests are 'one-to-one,' which means that you cannot have multiple 'listeners' to a single request.
+
+Let's look at a basic example.
+
+```js
+// Set up an object to reply to a request. In this case, whether or not its visible.
+myObject.reply('visible', this.isVisible);
+
+// Get whether it's visible or not.
+var isViewVisible = myObject.request('visible');
+```
+
+The handler in `reply` can either return a flat value, like `true` or `false`, or a function to be executed. Either way, the value is sent back to
+the requester.
+
+Here's a diagram of the Requests pattern:
+
+<p align='center'>
+ <img src='https://cloud.githubusercontent.com/assets/10248067/11762945/5c302a36-a0bd-11e5-8e4e-0eee7cacbef1.png' alt='Backbone.Requests diagram'>
+</p>
+
+Although the name is 'Requests,' you can just as easily request information as you can request that an action be completed. Just like HTTP,
+where you can both make GET requests for information, or DELETE requests to order than a resource be deleted, Requests can be used for a variety
+of purposes.
+
+One thing to note is that this pattern is **identical** to a simple method call. One can just as easily rewrite the above example as:
+
+```js
+// Set up a method...
+myObject.isVisible = function() {
+ return this.viewIsVisible;
+}
+
+// Call that method
+var isViewVisible = myObject.isVisible();
+```
+
+This is why mixing Requests into something like a View or Model does not make much sense. If you have access to the View or Model, then
+you might as well just use methods.
+
+### Channels
+
+The real draw of Backbone.Radio are Channels. A Channel is simply an object that has Backbone.Events and Radio.Requests mixed into it:
+it's a standalone message bus comprised of both systems.
+
+Getting a handle of a Channel is easy.
+
+```js
+// Get a reference to the channel named 'user'
+var userChannel = Backbone.Radio.channel('user');
+```
+
+Once you've got a channel, you can attach handlers to it.
+
+```js
+userChannel.on('some:event', function() {
+ console.log('An event has happened!');
+});
+
+userChannel.reply('some:request', 'food is good');
+```
+
+You can also use the 'trigger' methods on the Channel.
+
+```js
+userChannel.trigger('some:event');
+
+userChannel.request('some:request');
+```
+
+You can have as many channels as you'd like
+
+```js
+// Maybe you have a channel for the profile section of your app
+var profileChannel = Backbone.Radio.channel('profile');
+
+// And another one for settings
+var settingsChannel = Backbone.Radio.channel('settings');
+```
+
+The whole point of Channels is that they provide a way to explicitly namespace events in your application, and a means to easily access
+any of those namespaces.
+
+### Using With Marionette
+
+[Marionette](https://github.com/marionettejs/backbone.marionette) does not use Radio by default, although it will in the next major release: v3. However, you can use Radio today by including a small shim after you load Marionette, but before you load your application's code. To get the shim, refer to [this Gist](https://gist.github.com/jmeas/7992474cdb1c5672d88b).
+
+## API
+
+Like Backbone.Events, **all** of the following methods support both the object-syntax and space-separated syntax. For the sake of brevity,
+I only provide examples for these alternate syntaxes in the most common use cases.
+
+### Requests
+
+#### `request( requestName [, args...] )`
+
+Make a request for `requestName`. Optionally pass arguments to send along to the callback. Returns the reply, if one
+exists. If there is no reply registered then `undefined` will be returned.
+
+You can make multiple requests at once by using the space-separated syntax.
+
+```js
+myChannel.request('requestOne requestTwo');
+```
+
+When using the space-separated syntax, the responses will be returned to you as an object, where
+the keys are the name of the request, and the values are the replies.
+
+#### `reply( requestName, callback [, context] )`
+
+Register a handler for `requestName` on this object. `callback` will be executed whenever the request is made. Optionally
+pass a `context` for the callback, defaulting to `this`.
+
+To register a default handler for Requests use the `default` requestName. The unhandled `requestName` will be passed as the first argument.
+
+```js
+myChannel.reply('default', function(requestName) {
+ console.log('No reply exists for this request: ' + requestName);
+});
+
+// This will be handled by the default request
+myChannel.request('someUnhandledRequest');
+```
+
+To register multiple requests at once you may also pass in a hash.
+
+```js
+// Connect all of the replies at once
+myChannel.reply({
+ 'some:request': myCallback,
+ 'some:other:request': someOtherCallback
+}, context);
+```
+
+Returns the instance of Requests.
+
+#### `replyOnce( requestName, callback [, context] )`
+
+Register a handler for `requestName` that will only be called a single time.
+
+Like `reply`, you may also pass a hash of replies to register many at once. Refer to the `reply` documentation above
+for an example.
+
+Returns the instance of Requests.
+
+#### `stopReplying( [requestName] [, callback] [, context] )`
+
+If `context` is passed, then all replies with that context will be removed from the object. If `callback` is
+passed then all requests with that callback will be removed. If `requestName` is passed then this method will
+remove that reply. If no arguments are passed then all replies are removed from the object.
+
+You may also pass a hash of replies or space-separated replies to remove many at once.
+
+Returns the instance of Requests.
+
+### Channel
+
+#### `channelName`
+
+The name of the channel.
+
+#### `reset()`
+
+Destroy all handlers from Backbone.Events and Radio.Requests from the channel. Returns the channel.
+
+### Radio
+
+#### `channel( channelName )`
+
+Get a reference to a channel by name. If a name is not provided an Error will be thrown.
+
+```js
+var authChannel = Backbone.Radio.channel('auth');
+```
+
+#### `DEBUG`
+
+This is a Boolean property. Setting it to `true` will cause console warnings to be issued
+whenever you interact with a `request` that isn't registered. This is useful in development when you want to
+ensure that you've got your event names in order.
+
+```js
+// Turn on debug mode
+Backbone.Radio.DEBUG = true;
+
+// This will log a warning to the console if it goes unhandled
+myChannel.request('show:view');
+
+// Likewise, this will too, helping to prevent memory leaks
+myChannel.stopReplying('startTime');
+```
+
+#### `debugLog(warning, eventName, channelName)`
+
+A function executed whenever an unregistered request is interacted with on a Channel. Only
+called when `DEBUG` is set to `true`. By overriding this you could, for instance, make unhandled
+events throw Errors.
+
+The warning is a string describing the type of problem, such as:
+
+> Attempted to remove the unregistered request
+
+while the `eventName` and `channelName` are what you would expect.
+
+#### `tuneIn( channelName )`
+
+Tuning into a Channel is another useful tool for debugging. It passes all
+triggers and requests made on the channel to
+
+[`Radio.log`](https://github.com/jmeas/backbone.radio#log-channelname-eventname--args-).
+Returns `Backbone.Radio`.
+
+```js
+Backbone.Radio.tuneIn('calendar');
+```
+
+#### `tuneOut( channelName )`
+
+Once you're done tuning in you can call `tuneOut` to stop the logging. Returns `Backbone.Radio`.
+
+```js
+Backbone.Radio.tuneOut('calendar');
+```
+
+#### `log( channelName, eventName [, args...] )`
+
+When tuned into a Channel, this method will be called for all activity on
+a channel. The default implementation is to `console.log` the following message:
+
+```js
+'[channelName] "eventName" args1 arg2 arg3...'
+```
+
+where args are all of the arguments passed with the message. It is exposed so that you
+may overwrite it with your own logging message if you wish.
+
+### 'Top-level' API
+
+If you'd like to execute a method on a channel, yet you don't need to keep a handle of the
+channel around, you can do so with the proxy functions directly on the `Backbone.Radio` object.
+
+```js
+// Trigger 'some:event' on the settings channel
+Backbone.Radio.trigger('settings', 'some:event');
+```
+
+All of the methods for both messaging systems are available from the top-level API.
+
+#### `reset( [channelName] )`
+
+You can also reset a single channel, or all Channels, from the `Radio` object directly. Pass a
+`channelName` to reset just that specific channel, or call the method without any arguments
+to reset every channel.
+
+```js
+// Reset all channels
+Radio.reset();
+```
diff --git a/js/vendor/backbone.radio/bower.json b/js/vendor/backbone.radio/bower.json
new file mode 100644
index 000000000..6ec053ee8
--- /dev/null
+++ b/js/vendor/backbone.radio/bower.json
@@ -0,0 +1,29 @@
+{
+ "name": "backbone.radio",
+ "version": "2.0.0",
+ "homepage": "https://github.com/marionettejs/backbone.radio",
+ "authors": [
+ "Jmeas <jellyes2@gmail.com>"
+ ],
+ "description": "Messaging patterns for Backbone applications.",
+ "main": "build/backbone.radio.js",
+ "keywords": [
+ "backbone",
+ "marionette",
+ "decoupled",
+ "pubsub",
+ "publish",
+ "subscribe",
+ "messaging",
+ "architecture",
+ "spa"
+ ],
+ "license": "MIT",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ]
+}
diff --git a/js/vendor/backbone.radio/build/backbone.radio.js b/js/vendor/backbone.radio/build/backbone.radio.js
new file mode 100644
index 000000000..b95fc47a7
--- /dev/null
+++ b/js/vendor/backbone.radio/build/backbone.radio.js
@@ -0,0 +1,350 @@
+// Backbone.Radio v2.0.0
+
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('underscore'), require('backbone')) :
+ typeof define === 'function' && define.amd ? define(['underscore', 'backbone'], factory) :
+ (global.Backbone = global.Backbone || {}, global.Backbone.Radio = factory(global._,global.Backbone));
+}(this, function (_,Backbone) { 'use strict';
+
+ _ = 'default' in _ ? _['default'] : _;
+ Backbone = 'default' in Backbone ? Backbone['default'] : Backbone;
+
+ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
+ return typeof obj;
+ } : function (obj) {
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
+ };
+
+ var previousRadio = Backbone.Radio;
+
+ var Radio = Backbone.Radio = {};
+
+ Radio.VERSION = '2.0.0';
+
+ // This allows you to run multiple instances of Radio on the same
+ // webapp. After loading the new version, call `noConflict()` to
+ // get a reference to it. At the same time the old version will be
+ // returned to Backbone.Radio.
+ Radio.noConflict = function () {
+ Backbone.Radio = previousRadio;
+ return this;
+ };
+
+ // Whether or not we're in DEBUG mode or not. DEBUG mode helps you
+ // get around the issues of lack of warnings when events are mis-typed.
+ Radio.DEBUG = false;
+
+ // Format debug text.
+ Radio._debugText = function (warning, eventName, channelName) {
+ return warning + (channelName ? ' on the ' + channelName + ' channel' : '') + ': "' + eventName + '"';
+ };
+
+ // This is the method that's called when an unregistered event was called.
+ // By default, it logs warning to the console. By overriding this you could
+ // make it throw an Error, for instance. This would make firing a nonexistent event
+ // have the same consequence as firing a nonexistent method on an Object.
+ Radio.debugLog = function (warning, eventName, channelName) {
+ if (Radio.DEBUG && console && console.warn) {
+ console.warn(Radio._debugText(warning, eventName, channelName));
+ }
+ };
+
+ var eventSplitter = /\s+/;
+
+ // An internal method used to handle Radio's method overloading for Requests.
+ // It's borrowed from Backbone.Events. It differs from Backbone's overload
+ // API (which is used in Backbone.Events) in that it doesn't support space-separated
+ // event names.
+ Radio._eventsApi = function (obj, action, name, rest) {
+ if (!name) {
+ return false;
+ }
+
+ var results = {};
+
+ // Handle event maps.
+ if ((typeof name === 'undefined' ? 'undefined' : _typeof(name)) === 'object') {
+ for (var key in name) {
+ var result = obj[action].apply(obj, [key, name[key]].concat(rest));
+ eventSplitter.test(key) ? _.extend(results, result) : results[key] = result;
+ }
+ return results;
+ }
+
+ // Handle space separated event names.
+ if (eventSplitter.test(name)) {
+ var names = name.split(eventSplitter);
+ for (var i = 0, l = names.length; i < l; i++) {
+ results[names[i]] = obj[action].apply(obj, [names[i]].concat(rest));
+ }
+ return results;
+ }
+
+ return false;
+ };
+
+ // An optimized way to execute callbacks.
+ Radio._callHandler = function (callback, context, args) {
+ var a1 = args[0],
+ a2 = args[1],
+ a3 = args[2];
+ switch (args.length) {
+ case 0:
+ return callback.call(context);
+ case 1:
+ return callback.call(context, a1);
+ case 2:
+ return callback.call(context, a1, a2);
+ case 3:
+ return callback.call(context, a1, a2, a3);
+ default:
+ return callback.apply(context, args);
+ }
+ };
+
+ // A helper used by `off` methods to the handler from the store
+ function removeHandler(store, name, callback, context) {
+ var event = store[name];
+ if ((!callback || callback === event.callback || callback === event.callback._callback) && (!context || context === event.context)) {
+ delete store[name];
+ return true;
+ }
+ }
+
+ function removeHandlers(store, name, callback, context) {
+ store || (store = {});
+ var names = name ? [name] : _.keys(store);
+ var matched = false;
+
+ for (var i = 0, length = names.length; i < length; i++) {
+ name = names[i];
+
+ // If there's no event by this name, log it and continue
+ // with the loop
+ if (!store[name]) {
+ continue;
+ }
+
+ if (removeHandler(store, name, callback, context)) {
+ matched = true;
+ }
+ }
+
+ return matched;
+ }
+
+ /*
+ * tune-in
+ * -------
+ * Get console logs of a channel's activity
+ *
+ */
+
+ var _logs = {};
+
+ // This is to produce an identical function in both tuneIn and tuneOut,
+ // so that Backbone.Events unregisters it.
+ function _partial(channelName) {
+ return _logs[channelName] || (_logs[channelName] = _.bind(Radio.log, Radio, channelName));
+ }
+
+ _.extend(Radio, {
+
+ // Log information about the channel and event
+ log: function log(channelName, eventName) {
+ if (typeof console === 'undefined') {
+ return;
+ }
+ var args = _.toArray(arguments).slice(2);
+ console.log('[' + channelName + '] "' + eventName + '"', args);
+ },
+
+ // Logs all events on this channel to the console. It sets an
+ // internal value on the channel telling it we're listening,
+ // then sets a listener on the Backbone.Events
+ tuneIn: function tuneIn(channelName) {
+ var channel = Radio.channel(channelName);
+ channel._tunedIn = true;
+ channel.on('all', _partial(channelName));
+ return this;
+ },
+
+ // Stop logging all of the activities on this channel to the console
+ tuneOut: function tuneOut(channelName) {
+ var channel = Radio.channel(channelName);
+ channel._tunedIn = false;
+ channel.off('all', _partial(channelName));
+ delete _logs[channelName];
+ return this;
+ }
+ });
+
+ /*
+ * Backbone.Radio.Requests
+ * -----------------------
+ * A messaging system for requesting data.
+ *
+ */
+
+ function makeCallback(callback) {
+ return _.isFunction(callback) ? callback : function () {
+ return callback;
+ };
+ }
+
+ Radio.Requests = {
+
+ // Make a request
+ request: function request(name) {
+ var args = _.toArray(arguments).slice(1);
+ var results = Radio._eventsApi(this, 'request', name, args);
+ if (results) {
+ return results;
+ }
+ var channelName = this.channelName;
+ var requests = this._requests;
+
+ // Check if we should log the request, and if so, do it
+ if (channelName && this._tunedIn) {
+ Radio.log.apply(this, [channelName, name].concat(args));
+ }
+
+ // If the request isn't handled, log it in DEBUG mode and exit
+ if (requests && (requests[name] || requests['default'])) {
+ var handler = requests[name] || requests['default'];
+ args = requests[name] ? args : arguments;
+ return Radio._callHandler(handler.callback, handler.context, args);
+ } else {
+ Radio.debugLog('An unhandled request was fired', name, channelName);
+ }
+ },
+
+ // Set up a handler for a request
+ reply: function reply(name, callback, context) {
+ if (Radio._eventsApi(this, 'reply', name, [callback, context])) {
+ return this;
+ }
+
+ this._requests || (this._requests = {});
+
+ if (this._requests[name]) {
+ Radio.debugLog('A request was overwritten', name, this.channelName);
+ }
+
+ this._requests[name] = {
+ callback: makeCallback(callback),
+ context: context || this
+ };
+
+ return this;
+ },
+
+ // Set up a handler that can only be requested once
+ replyOnce: function replyOnce(name, callback, context) {
+ if (Radio._eventsApi(this, 'replyOnce', name, [callback, context])) {
+ return this;
+ }
+
+ var self = this;
+
+ var once = _.once(function () {
+ self.stopReplying(name);
+ return makeCallback(callback).apply(this, arguments);
+ });
+
+ return this.reply(name, once, context);
+ },
+
+ // Remove handler(s)
+ stopReplying: function stopReplying(name, callback, context) {
+ if (Radio._eventsApi(this, 'stopReplying', name)) {
+ return this;
+ }
+
+ // Remove everything if there are no arguments passed
+ if (!name && !callback && !context) {
+ delete this._requests;
+ } else if (!removeHandlers(this._requests, name, callback, context)) {
+ Radio.debugLog('Attempted to remove the unregistered request', name, this.channelName);
+ }
+
+ return this;
+ }
+ };
+
+ /*
+ * Backbone.Radio.channel
+ * ----------------------
+ * Get a reference to a channel by name.
+ *
+ */
+
+ Radio._channels = {};
+
+ Radio.channel = function (channelName) {
+ if (!channelName) {
+ throw new Error('You must provide a name for the channel.');
+ }
+
+ if (Radio._channels[channelName]) {
+ return Radio._channels[channelName];
+ } else {
+ return Radio._channels[channelName] = new Radio.Channel(channelName);
+ }
+ };
+
+ /*
+ * Backbone.Radio.Channel
+ * ----------------------
+ * A Channel is an object that extends from Backbone.Events,
+ * and Radio.Requests.
+ *
+ */
+
+ Radio.Channel = function (channelName) {
+ this.channelName = channelName;
+ };
+
+ _.extend(Radio.Channel.prototype, Backbone.Events, Radio.Requests, {
+
+ // Remove all handlers from the messaging systems of this channel
+ reset: function reset() {
+ this.off();
+ this.stopListening();
+ this.stopReplying();
+ return this;
+ }
+ });
+
+ /*
+ * Top-level API
+ * -------------
+ * Supplies the 'top-level API' for working with Channels directly
+ * from Backbone.Radio.
+ *
+ */
+
+ var channel;
+ var args;
+ var systems = [Backbone.Events, Radio.Requests];
+ _.each(systems, function (system) {
+ _.each(system, function (method, methodName) {
+ Radio[methodName] = function (channelName) {
+ args = _.toArray(arguments).slice(1);
+ channel = this.channel(channelName);
+ return channel[methodName].apply(channel, args);
+ };
+ });
+ });
+
+ Radio.reset = function (channelName) {
+ var channels = !channelName ? this._channels : [this._channels[channelName]];
+ _.each(channels, function (channel) {
+ channel.reset();
+ });
+ };
+
+ return Radio;
+
+}));
+//# sourceMappingURL=./backbone.radio.js.map \ No newline at end of file
diff --git a/js/vendor/backbone.radio/build/backbone.radio.js.map b/js/vendor/backbone.radio/build/backbone.radio.js.map
new file mode 100644
index 000000000..feb2e83f7
--- /dev/null
+++ b/js/vendor/backbone.radio/build/backbone.radio.js.map
@@ -0,0 +1 @@
+{"version":3,"names":[],"mappings":"","sources":["backbone.radio.js"],"sourcesContent":["// Backbone.Radio v2.0.0\n\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('underscore'), require('backbone')) :\n typeof define === 'function' && define.amd ? define(['underscore', 'backbone'], factory) :\n (global.Backbone = global.Backbone || {}, global.Backbone.Radio = factory(global._,global.Backbone));\n}(this, function (_,Backbone) { 'use strict';\n\n _ = 'default' in _ ? _['default'] : _;\n Backbone = 'default' in Backbone ? Backbone['default'] : Backbone;\n\n var _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj;\n };\n\n var previousRadio = Backbone.Radio;\n\n var Radio = Backbone.Radio = {};\n\n Radio.VERSION = '2.0.0';\n\n // This allows you to run multiple instances of Radio on the same\n // webapp. After loading the new version, call `noConflict()` to\n // get a reference to it. At the same time the old version will be\n // returned to Backbone.Radio.\n Radio.noConflict = function () {\n Backbone.Radio = previousRadio;\n return this;\n };\n\n // Whether or not we're in DEBUG mode or not. DEBUG mode helps you\n // get around the issues of lack of warnings when events are mis-typed.\n Radio.DEBUG = false;\n\n // Format debug text.\n Radio._debugText = function (warning, eventName, channelName) {\n return warning + (channelName ? ' on the ' + channelName + ' channel' : '') + ': \"' + eventName + '\"';\n };\n\n // This is the method that's called when an unregistered event was called.\n // By default, it logs warning to the console. By overriding this you could\n // make it throw an Error, for instance. This would make firing a nonexistent event\n // have the same consequence as firing a nonexistent method on an Object.\n Radio.debugLog = function (warning, eventName, channelName) {\n if (Radio.DEBUG && console && console.warn) {\n console.warn(Radio._debugText(warning, eventName, channelName));\n }\n };\n\n var eventSplitter = /\\s+/;\n\n // An internal method used to handle Radio's method overloading for Requests.\n // It's borrowed from Backbone.Events. It differs from Backbone's overload\n // API (which is used in Backbone.Events) in that it doesn't support space-separated\n // event names.\n Radio._eventsApi = function (obj, action, name, rest) {\n if (!name) {\n return false;\n }\n\n var results = {};\n\n // Handle event maps.\n if ((typeof name === 'undefined' ? 'undefined' : _typeof(name)) === 'object') {\n for (var key in name) {\n var result = obj[action].apply(obj, [key, name[key]].concat(rest));\n eventSplitter.test(key) ? _.extend(results, result) : results[key] = result;\n }\n return results;\n }\n\n // Handle space separated event names.\n if (eventSplitter.test(name)) {\n var names = name.split(eventSplitter);\n for (var i = 0, l = names.length; i < l; i++) {\n results[names[i]] = obj[action].apply(obj, [names[i]].concat(rest));\n }\n return results;\n }\n\n return false;\n };\n\n // An optimized way to execute callbacks.\n Radio._callHandler = function (callback, context, args) {\n var a1 = args[0],\n a2 = args[1],\n a3 = args[2];\n switch (args.length) {\n case 0:\n return callback.call(context);\n case 1:\n return callback.call(context, a1);\n case 2:\n return callback.call(context, a1, a2);\n case 3:\n return callback.call(context, a1, a2, a3);\n default:\n return callback.apply(context, args);\n }\n };\n\n // A helper used by `off` methods to the handler from the store\n function removeHandler(store, name, callback, context) {\n var event = store[name];\n if ((!callback || callback === event.callback || callback === event.callback._callback) && (!context || context === event.context)) {\n delete store[name];\n return true;\n }\n }\n\n function removeHandlers(store, name, callback, context) {\n store || (store = {});\n var names = name ? [name] : _.keys(store);\n var matched = false;\n\n for (var i = 0, length = names.length; i < length; i++) {\n name = names[i];\n\n // If there's no event by this name, log it and continue\n // with the loop\n if (!store[name]) {\n continue;\n }\n\n if (removeHandler(store, name, callback, context)) {\n matched = true;\n }\n }\n\n return matched;\n }\n\n /*\n * tune-in\n * -------\n * Get console logs of a channel's activity\n *\n */\n\n var _logs = {};\n\n // This is to produce an identical function in both tuneIn and tuneOut,\n // so that Backbone.Events unregisters it.\n function _partial(channelName) {\n return _logs[channelName] || (_logs[channelName] = _.bind(Radio.log, Radio, channelName));\n }\n\n _.extend(Radio, {\n\n // Log information about the channel and event\n log: function log(channelName, eventName) {\n if (typeof console === 'undefined') {\n return;\n }\n var args = _.toArray(arguments).slice(2);\n console.log('[' + channelName + '] \"' + eventName + '\"', args);\n },\n\n // Logs all events on this channel to the console. It sets an\n // internal value on the channel telling it we're listening,\n // then sets a listener on the Backbone.Events\n tuneIn: function tuneIn(channelName) {\n var channel = Radio.channel(channelName);\n channel._tunedIn = true;\n channel.on('all', _partial(channelName));\n return this;\n },\n\n // Stop logging all of the activities on this channel to the console\n tuneOut: function tuneOut(channelName) {\n var channel = Radio.channel(channelName);\n channel._tunedIn = false;\n channel.off('all', _partial(channelName));\n delete _logs[channelName];\n return this;\n }\n });\n\n /*\n * Backbone.Radio.Requests\n * -----------------------\n * A messaging system for requesting data.\n *\n */\n\n function makeCallback(callback) {\n return _.isFunction(callback) ? callback : function () {\n return callback;\n };\n }\n\n Radio.Requests = {\n\n // Make a request\n request: function request(name) {\n var args = _.toArray(arguments).slice(1);\n var results = Radio._eventsApi(this, 'request', name, args);\n if (results) {\n return results;\n }\n var channelName = this.channelName;\n var requests = this._requests;\n\n // Check if we should log the request, and if so, do it\n if (channelName && this._tunedIn) {\n Radio.log.apply(this, [channelName, name].concat(args));\n }\n\n // If the request isn't handled, log it in DEBUG mode and exit\n if (requests && (requests[name] || requests['default'])) {\n var handler = requests[name] || requests['default'];\n args = requests[name] ? args : arguments;\n return Radio._callHandler(handler.callback, handler.context, args);\n } else {\n Radio.debugLog('An unhandled request was fired', name, channelName);\n }\n },\n\n // Set up a handler for a request\n reply: function reply(name, callback, context) {\n if (Radio._eventsApi(this, 'reply', name, [callback, context])) {\n return this;\n }\n\n this._requests || (this._requests = {});\n\n if (this._requests[name]) {\n Radio.debugLog('A request was overwritten', name, this.channelName);\n }\n\n this._requests[name] = {\n callback: makeCallback(callback),\n context: context || this\n };\n\n return this;\n },\n\n // Set up a handler that can only be requested once\n replyOnce: function replyOnce(name, callback, context) {\n if (Radio._eventsApi(this, 'replyOnce', name, [callback, context])) {\n return this;\n }\n\n var self = this;\n\n var once = _.once(function () {\n self.stopReplying(name);\n return makeCallback(callback).apply(this, arguments);\n });\n\n return this.reply(name, once, context);\n },\n\n // Remove handler(s)\n stopReplying: function stopReplying(name, callback, context) {\n if (Radio._eventsApi(this, 'stopReplying', name)) {\n return this;\n }\n\n // Remove everything if there are no arguments passed\n if (!name && !callback && !context) {\n delete this._requests;\n } else if (!removeHandlers(this._requests, name, callback, context)) {\n Radio.debugLog('Attempted to remove the unregistered request', name, this.channelName);\n }\n\n return this;\n }\n };\n\n /*\n * Backbone.Radio.channel\n * ----------------------\n * Get a reference to a channel by name.\n *\n */\n\n Radio._channels = {};\n\n Radio.channel = function (channelName) {\n if (!channelName) {\n throw new Error('You must provide a name for the channel.');\n }\n\n if (Radio._channels[channelName]) {\n return Radio._channels[channelName];\n } else {\n return Radio._channels[channelName] = new Radio.Channel(channelName);\n }\n };\n\n /*\n * Backbone.Radio.Channel\n * ----------------------\n * A Channel is an object that extends from Backbone.Events,\n * and Radio.Requests.\n *\n */\n\n Radio.Channel = function (channelName) {\n this.channelName = channelName;\n };\n\n _.extend(Radio.Channel.prototype, Backbone.Events, Radio.Requests, {\n\n // Remove all handlers from the messaging systems of this channel\n reset: function reset() {\n this.off();\n this.stopListening();\n this.stopReplying();\n return this;\n }\n });\n\n /*\n * Top-level API\n * -------------\n * Supplies the 'top-level API' for working with Channels directly\n * from Backbone.Radio.\n *\n */\n\n var channel;\n var args;\n var systems = [Backbone.Events, Radio.Requests];\n _.each(systems, function (system) {\n _.each(system, function (method, methodName) {\n Radio[methodName] = function (channelName) {\n args = _.toArray(arguments).slice(1);\n channel = this.channel(channelName);\n return channel[methodName].apply(channel, args);\n };\n });\n });\n\n Radio.reset = function (channelName) {\n var channels = !channelName ? this._channels : [this._channels[channelName]];\n _.each(channels, function (channel) {\n channel.reset();\n });\n };\n\n return Radio;\n\n}));\n"],"file":"backbone.radio.js","sourceRoot":"/source/"} \ No newline at end of file
diff --git a/js/vendor/backbone.radio/build/backbone.radio.min.js b/js/vendor/backbone.radio/build/backbone.radio.min.js
new file mode 100644
index 000000000..7fa28b0ba
--- /dev/null
+++ b/js/vendor/backbone.radio/build/backbone.radio.min.js
@@ -0,0 +1,3 @@
+// Backbone.Radio v2.0.0
+!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n(require("underscore"),require("backbone")):"function"==typeof define&&define.amd?define(["underscore","backbone"],n):(e.Backbone=e.Backbone||{},e.Backbone.Radio=n(e._,e.Backbone))}(this,function(e,n){"use strict";function t(e,n,t,r){var o=e[n];if(!(t&&t!==o.callback&&t!==o.callback._callback||r&&r!==o.context))return delete e[n],!0}function r(n,r,o,i){n||(n={});for(var s=r?[r]:e.keys(n),u=!1,c=0,a=s.length;c<a;c++)r=s[c],n[r]&&t(n,r,o,i)&&(u=!0);return u}function o(n){return l[n]||(l[n]=e.bind(c.log,c,n))}function i(n){return e.isFunction(n)?n:function(){return n}}e="default"in e?e["default"]:e,n="default"in n?n["default"]:n;var s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e},u=n.Radio,c=n.Radio={};c.VERSION="2.0.0",c.noConflict=function(){return n.Radio=u,this},c.DEBUG=!1,c._debugText=function(e,n,t){return e+(t?" on the "+t+" channel":"")+': "'+n+'"'},c.debugLog=function(e,n,t){c.DEBUG&&console&&console.warn&&console.warn(c._debugText(e,n,t))};var a=/\s+/;c._eventsApi=function(n,t,r,o){if(!r)return!1;var i={};if("object"===("undefined"==typeof r?"undefined":s(r))){for(var u in r){var c=n[t].apply(n,[u,r[u]].concat(o));a.test(u)?e.extend(i,c):i[u]=c}return i}if(a.test(r)){for(var l=r.split(a),f=0,h=l.length;f<h;f++)i[l[f]]=n[t].apply(n,[l[f]].concat(o));return i}return!1},c._callHandler=function(e,n,t){var r=t[0],o=t[1],i=t[2];switch(t.length){case 0:return e.call(n);case 1:return e.call(n,r);case 2:return e.call(n,r,o);case 3:return e.call(n,r,o,i);default:return e.apply(n,t)}};var l={};e.extend(c,{log:function(n,t){if("undefined"!=typeof console){var r=e.toArray(arguments).slice(2);console.log("["+n+'] "'+t+'"',r)}},tuneIn:function(e){var n=c.channel(e);return n._tunedIn=!0,n.on("all",o(e)),this},tuneOut:function(e){var n=c.channel(e);return n._tunedIn=!1,n.off("all",o(e)),delete l[e],this}}),c.Requests={request:function(n){var t=e.toArray(arguments).slice(1),r=c._eventsApi(this,"request",n,t);if(r)return r;var o=this.channelName,i=this._requests;if(o&&this._tunedIn&&c.log.apply(this,[o,n].concat(t)),i&&(i[n]||i["default"])){var s=i[n]||i["default"];return t=i[n]?t:arguments,c._callHandler(s.callback,s.context,t)}c.debugLog("An unhandled request was fired",n,o)},reply:function(e,n,t){return c._eventsApi(this,"reply",e,[n,t])?this:(this._requests||(this._requests={}),this._requests[e]&&c.debugLog("A request was overwritten",e,this.channelName),this._requests[e]={callback:i(n),context:t||this},this)},replyOnce:function(n,t,r){if(c._eventsApi(this,"replyOnce",n,[t,r]))return this;var o=this,s=e.once(function(){return o.stopReplying(n),i(t).apply(this,arguments)});return this.reply(n,s,r)},stopReplying:function(e,n,t){return c._eventsApi(this,"stopReplying",e)?this:(e||n||t?r(this._requests,e,n,t)||c.debugLog("Attempted to remove the unregistered request",e,this.channelName):delete this._requests,this)}},c._channels={},c.channel=function(e){if(!e)throw new Error("You must provide a name for the channel.");return c._channels[e]?c._channels[e]:c._channels[e]=new c.Channel(e)},c.Channel=function(e){this.channelName=e},e.extend(c.Channel.prototype,n.Events,c.Requests,{reset:function(){return this.off(),this.stopListening(),this.stopReplying(),this}});var f,h,d=[n.Events,c.Requests];return e.each(d,function(n){e.each(n,function(n,t){c[t]=function(n){return h=e.toArray(arguments).slice(1),f=this.channel(n),f[t].apply(f,h)}})}),c.reset=function(n){var t=n?[this._channels[n]]:this._channels;e.each(t,function(e){e.reset()})},c});
+//# sourceMappingURL=backbone.radio.min.js.map
diff --git a/js/vendor/backbone.radio/build/backbone.radio.min.js.map b/js/vendor/backbone.radio/build/backbone.radio.min.js.map
new file mode 100644
index 000000000..7a97db0b3
--- /dev/null
+++ b/js/vendor/backbone.radio/build/backbone.radio.min.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["backbone.radio.min.js"],"names":["global","factory","exports","module","require","define","amd","Backbone","Radio","_","this","removeHandler","store","name","callback","context","event","_callback","removeHandlers","names","keys","matched","i","length","_partial","channelName","_logs","bind","log","makeCallback","isFunction","_typeof","Symbol","iterator","obj","constructor","previousRadio","VERSION","noConflict","DEBUG","_debugText","warning","eventName","debugLog","console","warn","eventSplitter","_eventsApi","action","rest","results","key","result","apply","concat","test","extend","split","l","_callHandler","args","a1","a2","a3","call","toArray","arguments","slice","tuneIn","channel","_tunedIn","on","tuneOut","off","Requests","request","requests","_requests","handler","reply","replyOnce","self","once","stopReplying","_channels","Error","Channel","prototype","Events","reset","stopListening","systems","each","system","method","methodName","channels"],"mappings":"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","file":"backbone.radio.min.js","sourcesContent":["// Backbone.Radio v2.0.0\n\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('underscore'), require('backbone')) :\n typeof define === 'function' && define.amd ? define(['underscore', 'backbone'], factory) :\n (global.Backbone = global.Backbone || {}, global.Backbone.Radio = factory(global._,global.Backbone));\n}(this, function (_,Backbone) { 'use strict';\n\n _ = 'default' in _ ? _['default'] : _;\n Backbone = 'default' in Backbone ? Backbone['default'] : Backbone;\n\n var _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj;\n };\n\n var previousRadio = Backbone.Radio;\n\n var Radio = Backbone.Radio = {};\n\n Radio.VERSION = '2.0.0';\n\n // This allows you to run multiple instances of Radio on the same\n // webapp. After loading the new version, call `noConflict()` to\n // get a reference to it. At the same time the old version will be\n // returned to Backbone.Radio.\n Radio.noConflict = function () {\n Backbone.Radio = previousRadio;\n return this;\n };\n\n // Whether or not we're in DEBUG mode or not. DEBUG mode helps you\n // get around the issues of lack of warnings when events are mis-typed.\n Radio.DEBUG = false;\n\n // Format debug text.\n Radio._debugText = function (warning, eventName, channelName) {\n return warning + (channelName ? ' on the ' + channelName + ' channel' : '') + ': \"' + eventName + '\"';\n };\n\n // This is the method that's called when an unregistered event was called.\n // By default, it logs warning to the console. By overriding this you could\n // make it throw an Error, for instance. This would make firing a nonexistent event\n // have the same consequence as firing a nonexistent method on an Object.\n Radio.debugLog = function (warning, eventName, channelName) {\n if (Radio.DEBUG && console && console.warn) {\n console.warn(Radio._debugText(warning, eventName, channelName));\n }\n };\n\n var eventSplitter = /\\s+/;\n\n // An internal method used to handle Radio's method overloading for Requests.\n // It's borrowed from Backbone.Events. It differs from Backbone's overload\n // API (which is used in Backbone.Events) in that it doesn't support space-separated\n // event names.\n Radio._eventsApi = function (obj, action, name, rest) {\n if (!name) {\n return false;\n }\n\n var results = {};\n\n // Handle event maps.\n if ((typeof name === 'undefined' ? 'undefined' : _typeof(name)) === 'object') {\n for (var key in name) {\n var result = obj[action].apply(obj, [key, name[key]].concat(rest));\n eventSplitter.test(key) ? _.extend(results, result) : results[key] = result;\n }\n return results;\n }\n\n // Handle space separated event names.\n if (eventSplitter.test(name)) {\n var names = name.split(eventSplitter);\n for (var i = 0, l = names.length; i < l; i++) {\n results[names[i]] = obj[action].apply(obj, [names[i]].concat(rest));\n }\n return results;\n }\n\n return false;\n };\n\n // An optimized way to execute callbacks.\n Radio._callHandler = function (callback, context, args) {\n var a1 = args[0],\n a2 = args[1],\n a3 = args[2];\n switch (args.length) {\n case 0:\n return callback.call(context);\n case 1:\n return callback.call(context, a1);\n case 2:\n return callback.call(context, a1, a2);\n case 3:\n return callback.call(context, a1, a2, a3);\n default:\n return callback.apply(context, args);\n }\n };\n\n // A helper used by `off` methods to the handler from the store\n function removeHandler(store, name, callback, context) {\n var event = store[name];\n if ((!callback || callback === event.callback || callback === event.callback._callback) && (!context || context === event.context)) {\n delete store[name];\n return true;\n }\n }\n\n function removeHandlers(store, name, callback, context) {\n store || (store = {});\n var names = name ? [name] : _.keys(store);\n var matched = false;\n\n for (var i = 0, length = names.length; i < length; i++) {\n name = names[i];\n\n // If there's no event by this name, log it and continue\n // with the loop\n if (!store[name]) {\n continue;\n }\n\n if (removeHandler(store, name, callback, context)) {\n matched = true;\n }\n }\n\n return matched;\n }\n\n /*\n * tune-in\n * -------\n * Get console logs of a channel's activity\n *\n */\n\n var _logs = {};\n\n // This is to produce an identical function in both tuneIn and tuneOut,\n // so that Backbone.Events unregisters it.\n function _partial(channelName) {\n return _logs[channelName] || (_logs[channelName] = _.bind(Radio.log, Radio, channelName));\n }\n\n _.extend(Radio, {\n\n // Log information about the channel and event\n log: function log(channelName, eventName) {\n if (typeof console === 'undefined') {\n return;\n }\n var args = _.toArray(arguments).slice(2);\n console.log('[' + channelName + '] \"' + eventName + '\"', args);\n },\n\n // Logs all events on this channel to the console. It sets an\n // internal value on the channel telling it we're listening,\n // then sets a listener on the Backbone.Events\n tuneIn: function tuneIn(channelName) {\n var channel = Radio.channel(channelName);\n channel._tunedIn = true;\n channel.on('all', _partial(channelName));\n return this;\n },\n\n // Stop logging all of the activities on this channel to the console\n tuneOut: function tuneOut(channelName) {\n var channel = Radio.channel(channelName);\n channel._tunedIn = false;\n channel.off('all', _partial(channelName));\n delete _logs[channelName];\n return this;\n }\n });\n\n /*\n * Backbone.Radio.Requests\n * -----------------------\n * A messaging system for requesting data.\n *\n */\n\n function makeCallback(callback) {\n return _.isFunction(callback) ? callback : function () {\n return callback;\n };\n }\n\n Radio.Requests = {\n\n // Make a request\n request: function request(name) {\n var args = _.toArray(arguments).slice(1);\n var results = Radio._eventsApi(this, 'request', name, args);\n if (results) {\n return results;\n }\n var channelName = this.channelName;\n var requests = this._requests;\n\n // Check if we should log the request, and if so, do it\n if (channelName && this._tunedIn) {\n Radio.log.apply(this, [channelName, name].concat(args));\n }\n\n // If the request isn't handled, log it in DEBUG mode and exit\n if (requests && (requests[name] || requests['default'])) {\n var handler = requests[name] || requests['default'];\n args = requests[name] ? args : arguments;\n return Radio._callHandler(handler.callback, handler.context, args);\n } else {\n Radio.debugLog('An unhandled request was fired', name, channelName);\n }\n },\n\n // Set up a handler for a request\n reply: function reply(name, callback, context) {\n if (Radio._eventsApi(this, 'reply', name, [callback, context])) {\n return this;\n }\n\n this._requests || (this._requests = {});\n\n if (this._requests[name]) {\n Radio.debugLog('A request was overwritten', name, this.channelName);\n }\n\n this._requests[name] = {\n callback: makeCallback(callback),\n context: context || this\n };\n\n return this;\n },\n\n // Set up a handler that can only be requested once\n replyOnce: function replyOnce(name, callback, context) {\n if (Radio._eventsApi(this, 'replyOnce', name, [callback, context])) {\n return this;\n }\n\n var self = this;\n\n var once = _.once(function () {\n self.stopReplying(name);\n return makeCallback(callback).apply(this, arguments);\n });\n\n return this.reply(name, once, context);\n },\n\n // Remove handler(s)\n stopReplying: function stopReplying(name, callback, context) {\n if (Radio._eventsApi(this, 'stopReplying', name)) {\n return this;\n }\n\n // Remove everything if there are no arguments passed\n if (!name && !callback && !context) {\n delete this._requests;\n } else if (!removeHandlers(this._requests, name, callback, context)) {\n Radio.debugLog('Attempted to remove the unregistered request', name, this.channelName);\n }\n\n return this;\n }\n };\n\n /*\n * Backbone.Radio.channel\n * ----------------------\n * Get a reference to a channel by name.\n *\n */\n\n Radio._channels = {};\n\n Radio.channel = function (channelName) {\n if (!channelName) {\n throw new Error('You must provide a name for the channel.');\n }\n\n if (Radio._channels[channelName]) {\n return Radio._channels[channelName];\n } else {\n return Radio._channels[channelName] = new Radio.Channel(channelName);\n }\n };\n\n /*\n * Backbone.Radio.Channel\n * ----------------------\n * A Channel is an object that extends from Backbone.Events,\n * and Radio.Requests.\n *\n */\n\n Radio.Channel = function (channelName) {\n this.channelName = channelName;\n };\n\n _.extend(Radio.Channel.prototype, Backbone.Events, Radio.Requests, {\n\n // Remove all handlers from the messaging systems of this channel\n reset: function reset() {\n this.off();\n this.stopListening();\n this.stopReplying();\n return this;\n }\n });\n\n /*\n * Top-level API\n * -------------\n * Supplies the 'top-level API' for working with Channels directly\n * from Backbone.Radio.\n *\n */\n\n var channel;\n var args;\n var systems = [Backbone.Events, Radio.Requests];\n _.each(systems, function (system) {\n _.each(system, function (method, methodName) {\n Radio[methodName] = function (channelName) {\n args = _.toArray(arguments).slice(1);\n channel = this.channel(channelName);\n return channel[methodName].apply(channel, args);\n };\n });\n });\n\n Radio.reset = function (channelName) {\n var channels = !channelName ? this._channels : [this._channels[channelName]];\n _.each(channels, function (channel) {\n channel.reset();\n });\n };\n\n return Radio;\n\n}));\n//# sourceMappingURL=./backbone.radio.js.map"],"sourceRoot":"/source/"} \ No newline at end of file
diff --git a/js/vendor/backbone.radio/gulpfile.babel.js b/js/vendor/backbone.radio/gulpfile.babel.js
new file mode 100644
index 000000000..f86bb477f
--- /dev/null
+++ b/js/vendor/backbone.radio/gulpfile.babel.js
@@ -0,0 +1,233 @@
+import gulp from 'gulp';
+import loadPlugins from 'gulp-load-plugins';
+import del from 'del';
+import glob from 'glob';
+import path from 'path';
+import {Instrumenter} from 'isparta';
+import webpack from 'webpack';
+import webpackStream from 'webpack-stream';
+
+import _ from 'underscore';
+import rollup from 'rollup';
+import babel from 'rollup-plugin-babel';
+import preset from 'babel-preset-es2015-rollup';
+import fs from 'fs';
+import mkdirp from 'mkdirp';
+
+import mochaGlobals from './test/setup/.globals';
+import manifest from './package.json';
+
+// Load all of our Gulp plugins
+const $ = loadPlugins();
+
+// Gather the library data from `package.json`
+const config = manifest.babelBoilerplateOptions;
+const mainFile = manifest.main;
+const destinationFolder = path.dirname(mainFile);
+const exportFileName = path.basename(mainFile, path.extname(mainFile));
+
+function cleanDist(done) {
+ del([destinationFolder]).then(() => done());
+}
+
+function cleanTmp(done) {
+ del(['tmp']).then(() => done());
+}
+
+function onError() {
+ $.util.beep();
+}
+
+// Lint a set of files
+function lint(files) {
+ return gulp.src(files)
+ .pipe($.plumber())
+ .pipe($.eslint())
+ .pipe($.eslint.format())
+ .pipe($.eslint.failOnError())
+ .pipe($.jscs())
+ .pipe($.jscs.reporter())
+ .pipe($.jscs.reporter('fail'))
+ .on('error', onError);
+}
+
+function lintSrc() {
+ return lint('src/**/*.js');
+}
+
+function lintTest() {
+ return lint('test/**/*.js');
+}
+
+function lintGulpfile() {
+ return lint('gulpfile.babel.js');
+}
+
+function getBanner() {
+ var banner = '// Backbone.Radio v<%= version %>\n';
+ return _.template(banner)(manifest);
+}
+
+function build(done) {
+ rollup.rollup({
+ entry: path.join('src', config.entryFileName),
+ plugins: [
+ babel({
+ sourceMaps: true,
+ presets: [preset],
+ babelrc: false
+ })
+ ]
+ }).then(function(bundle) {
+ var banner = getBanner();
+
+ var result = bundle.generate({
+ banner: banner,
+ format: 'umd',
+ sourceMap: 'inline',
+ sourceMapSource: config.entryFileName + '.js',
+ sourceMapFile: exportFileName + '.js',
+ moduleName: config.mainVarName
+ });
+ var code = _.template(result.code.toString())(manifest) +
+ `\n//# sourceMappingURL=./${exportFileName}.js.map`;
+
+ // Write the generated sourcemap
+ mkdirp.sync(destinationFolder);
+ fs.writeFileSync(path.join(destinationFolder, exportFileName + '.js'), code);
+ fs.writeFileSync(path.join(destinationFolder, `${exportFileName}.js.map`), result.map.toString());
+
+ $.file(exportFileName + '.js', code, { src: true })
+ .pipe($.plumber())
+ .pipe($.sourcemaps.init({ loadMaps: true }))
+ .pipe($.sourcemaps.write('./', {addComment: false}))
+ .pipe(gulp.dest(destinationFolder))
+ .pipe($.filter(['*', '!**/*.js.map']))
+ .pipe($.rename(exportFileName + '.min.js'))
+ .pipe($.sourcemaps.init({ loadMaps: true }))
+ .pipe($.uglify())
+ .pipe($.header(banner))
+ .pipe($.sourcemaps.write('./'))
+ .pipe(gulp.dest(destinationFolder))
+ .on('end', done);
+ }).catch(console.error);
+}
+
+function _mocha() {
+ return gulp.src(['test/setup/node.js', 'test/unit/**/*.js'], {read: false})
+ .pipe($.mocha({
+ reporter: 'dot',
+ globals: Object.keys(mochaGlobals.globals),
+ ignoreLeaks: false
+ }));
+}
+
+function _registerBabel() {
+ require('babel-register');
+}
+
+function test() {
+ _registerBabel();
+ return _mocha();
+}
+
+function coverage(done) {
+ _registerBabel();
+ gulp.src(['src/**/*.js'])
+ .pipe($.istanbul({ instrumenter: Instrumenter }))
+ .pipe($.istanbul.hookRequire())
+ .on('finish', () => {
+ return test()
+ .pipe($.istanbul.writeReports())
+ .on('end', done);
+ });
+}
+
+const watchFiles = ['src/**/*', 'test/**/*', 'package.json', '**/.eslintrc', '.jscsrc'];
+
+// Run the headless unit tests as you make changes.
+function watch() {
+ gulp.watch(watchFiles, ['test']);
+}
+
+function testBrowser() {
+ // Our testing bundle is made up of our unit tests, which
+ // should individually load up pieces of our application.
+ // We also include the browser setup file.
+ const testFiles = glob.sync('./test/unit/**/*.js');
+ const allFiles = ['./test/setup/browser.js'].concat(testFiles);
+
+ // Lets us differentiate between the first build and subsequent builds
+ var firstBuild = true;
+
+ // This empty stream might seem like a hack, but we need to specify all of our files through
+ // the `entry` option of webpack. Otherwise, it ignores whatever file(s) are placed in here.
+ return gulp.src('')
+ .pipe($.plumber())
+ .pipe(webpackStream({
+ watch: true,
+ entry: allFiles,
+ output: {
+ filename: '__spec-build.js'
+ },
+ module: {
+ loaders: [
+ // This is what allows us to author in future JavaScript
+ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' },
+ // This allows the test setup scripts to load `package.json`
+ { test: /\.json$/, exclude: /node_modules/, loader: 'json-loader' }
+ ]
+ },
+ plugins: [
+ // By default, webpack does `n=>n` compilation with entry files. This concatenates
+ // them into a single chunk.
+ new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })
+ ],
+ devtool: 'inline-source-map'
+ }, null, function() {
+ if (firstBuild) {
+ $.livereload.listen({port: 35729, host: 'localhost', start: true});
+ var watcher = gulp.watch(watchFiles, ['lint']);
+ } else {
+ $.livereload.reload('./tmp/__spec-build.js');
+ }
+ firstBuild = false;
+ }))
+ .pipe(gulp.dest('./tmp'));
+}
+
+// Remove the built files
+gulp.task('clean', cleanDist);
+
+// Remove our temporary files
+gulp.task('clean-tmp', cleanTmp);
+
+// Lint our source code
+gulp.task('lint-src', lintSrc);
+
+// Lint our test code
+gulp.task('lint-test', lintTest);
+
+// Lint this file
+gulp.task('lint-gulpfile', lintGulpfile);
+
+// Lint everything
+gulp.task('lint', ['lint-src', 'lint-test', 'lint-gulpfile']);
+
+// Build two versions of the library
+gulp.task('build', ['lint', 'clean'], build);
+
+// Lint and run our tests
+gulp.task('test', ['lint'], test);
+
+// Set up coverage and run tests
+gulp.task('coverage', ['lint'], coverage);
+
+// Set up a livereload environment for our spec runner `test/runner.html`
+gulp.task('test-browser', ['lint', 'clean-tmp'], testBrowser);
+
+// Run the headless unit tests as you make changes.
+gulp.task('watch', watch);
+
+// An alias of test
+gulp.task('default', ['test']);
diff --git a/js/vendor/backbone.radio/package.json b/js/vendor/backbone.radio/package.json
new file mode 100644
index 000000000..e415214c0
--- /dev/null
+++ b/js/vendor/backbone.radio/package.json
@@ -0,0 +1,91 @@
+{
+ "name": "backbone.radio",
+ "description": "Messaging patterns for Backbone applications.",
+ "homepage": "https://github.com/marionettejs/backbone.radio",
+ "version": "2.0.0",
+ "main": "build/backbone.radio.js",
+ "keywords": [
+ "backbone",
+ "marionette",
+ "decoupled",
+ "pubsub",
+ "publish",
+ "subscribe",
+ "messaging",
+ "architecture",
+ "spa"
+ ],
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "https://github.com/marionettejs/backbone.radio/blob/master/LICENSE"
+ }
+ ],
+ "scripts": {
+ "test": "gulp",
+ "test-browser": "gulp test-browser",
+ "build": "gulp build",
+ "coverage": "gulp coverage"
+ },
+ "author": {
+ "name": "Jmeas",
+ "email": "jellyes2@gmail.com",
+ "web": "http://jmeas.com"
+ },
+ "bugs": {
+ "url": "https://github.com/marionettejs/backbone.radio/issues"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/marionettejs/backbone.radio.git"
+ },
+ "github": "https://github.com/marionettejs/backbone.radio",
+ "peerDependencies": {
+ "backbone": "^1.3.3",
+ "underscore": "^1.8.3"
+ },
+ "devDependencies": {
+ "babel-core": "6.7.0",
+ "babel-eslint": "6.0.4",
+ "babel-loader": "6.2.0",
+ "babel-polyfill": "6.6.1",
+ "babel-preset-es2015": "6.3.13",
+ "babel-preset-es2015-rollup": "1.1.1",
+ "babel-register": "6.4.3",
+ "backbone": ">=1.3.3 <1.4.0",
+ "chai": "3.4.1",
+ "del": "2.2.0",
+ "eslint": "3.2.2",
+ "glob": "6.0.3",
+ "gulp": "3.9.0",
+ "gulp-eslint": "3.0.1",
+ "gulp-file": "0.2.0",
+ "gulp-filter": "3.0.0",
+ "gulp-header": "1.7.1",
+ "gulp-istanbul": "0.10.3",
+ "gulp-jscs": "3.0.0",
+ "gulp-livereload": "3.8.1",
+ "gulp-load-plugins": "1.1.0",
+ "gulp-mocha": "2.2.0",
+ "gulp-plumber": "1.0.1",
+ "gulp-rename": "1.2.2",
+ "gulp-sourcemaps": "1.6.0",
+ "gulp-uglify": "1.5.1",
+ "gulp-util": "3.0.7",
+ "isparta": "4.0.0",
+ "json-loader": "0.5.3",
+ "mkdirp": "0.5.1",
+ "mocha": "2.3.4",
+ "rollup": "0.25.4",
+ "rollup-plugin-babel": "2.4.0",
+ "sinon": "1.17.2",
+ "sinon-chai": "2.8.0",
+ "underscore": "1.8.3",
+ "webpack": "1.12.9",
+ "webpack-stream": "3.1.0"
+ },
+ "babelBoilerplateOptions": {
+ "entryFileName": "backbone.radio",
+ "mainVarName": "Backbone.Radio"
+ }
+}
diff --git a/js/vendor/backbone.radio/src/backbone.radio.js b/js/vendor/backbone.radio/src/backbone.radio.js
new file mode 100644
index 000000000..f4483334b
--- /dev/null
+++ b/js/vendor/backbone.radio/src/backbone.radio.js
@@ -0,0 +1,323 @@
+import _ from 'underscore';
+import Backbone from 'backbone';
+
+var previousRadio = Backbone.Radio;
+
+var Radio = Backbone.Radio = {};
+
+Radio.VERSION = '<%= version %>';
+
+// This allows you to run multiple instances of Radio on the same
+// webapp. After loading the new version, call `noConflict()` to
+// get a reference to it. At the same time the old version will be
+// returned to Backbone.Radio.
+Radio.noConflict = function() {
+ Backbone.Radio = previousRadio;
+ return this;
+};
+
+// Whether or not we're in DEBUG mode or not. DEBUG mode helps you
+// get around the issues of lack of warnings when events are mis-typed.
+Radio.DEBUG = false;
+
+// Format debug text.
+Radio._debugText = function(warning, eventName, channelName) {
+ return warning + (channelName ? ' on the ' + channelName + ' channel' : '') +
+ ': "' + eventName + '"';
+};
+
+// This is the method that's called when an unregistered event was called.
+// By default, it logs warning to the console. By overriding this you could
+// make it throw an Error, for instance. This would make firing a nonexistent event
+// have the same consequence as firing a nonexistent method on an Object.
+Radio.debugLog = function(warning, eventName, channelName) {
+ if (Radio.DEBUG && console && console.warn) {
+ console.warn(Radio._debugText(warning, eventName, channelName));
+ }
+};
+
+var eventSplitter = /\s+/;
+
+// An internal method used to handle Radio's method overloading for Requests.
+// It's borrowed from Backbone.Events. It differs from Backbone's overload
+// API (which is used in Backbone.Events) in that it doesn't support space-separated
+// event names.
+Radio._eventsApi = function(obj, action, name, rest) {
+ if (!name) {
+ return false;
+ }
+
+ var results = {};
+
+ // Handle event maps.
+ if (typeof name === 'object') {
+ for (var key in name) {
+ var result = obj[action].apply(obj, [key, name[key]].concat(rest));
+ eventSplitter.test(key) ? _.extend(results, result) : results[key] = result;
+ }
+ return results;
+ }
+
+ // Handle space separated event names.
+ if (eventSplitter.test(name)) {
+ var names = name.split(eventSplitter);
+ for (var i = 0, l = names.length; i < l; i++) {
+ results[names[i]] = obj[action].apply(obj, [names[i]].concat(rest));
+ }
+ return results;
+ }
+
+ return false;
+};
+
+// An optimized way to execute callbacks.
+Radio._callHandler = function(callback, context, args) {
+ var a1 = args[0], a2 = args[1], a3 = args[2];
+ switch (args.length) {
+ case 0: return callback.call(context);
+ case 1: return callback.call(context, a1);
+ case 2: return callback.call(context, a1, a2);
+ case 3: return callback.call(context, a1, a2, a3);
+ default: return callback.apply(context, args);
+ }
+};
+
+// A helper used by `off` methods to the handler from the store
+function removeHandler(store, name, callback, context) {
+ var event = store[name];
+ if (
+ (!callback || (callback === event.callback || callback === event.callback._callback)) &&
+ (!context || (context === event.context))
+ ) {
+ delete store[name];
+ return true;
+ }
+}
+
+function removeHandlers(store, name, callback, context) {
+ store || (store = {});
+ var names = name ? [name] : _.keys(store);
+ var matched = false;
+
+ for (var i = 0, length = names.length; i < length; i++) {
+ name = names[i];
+
+ // If there's no event by this name, log it and continue
+ // with the loop
+ if (!store[name]) {
+ continue;
+ }
+
+ if (removeHandler(store, name, callback, context)) {
+ matched = true;
+ }
+ }
+
+ return matched;
+}
+
+/*
+ * tune-in
+ * -------
+ * Get console logs of a channel's activity
+ *
+ */
+
+var _logs = {};
+
+// This is to produce an identical function in both tuneIn and tuneOut,
+// so that Backbone.Events unregisters it.
+function _partial(channelName) {
+ return _logs[channelName] || (_logs[channelName] = _.bind(Radio.log, Radio, channelName));
+}
+
+_.extend(Radio, {
+
+ // Log information about the channel and event
+ log: function(channelName, eventName) {
+ if (typeof console === 'undefined') { return; }
+ var args = _.toArray(arguments).slice(2);
+ console.log('[' + channelName + '] "' + eventName + '"', args);
+ },
+
+ // Logs all events on this channel to the console. It sets an
+ // internal value on the channel telling it we're listening,
+ // then sets a listener on the Backbone.Events
+ tuneIn: function(channelName) {
+ var channel = Radio.channel(channelName);
+ channel._tunedIn = true;
+ channel.on('all', _partial(channelName));
+ return this;
+ },
+
+ // Stop logging all of the activities on this channel to the console
+ tuneOut: function(channelName) {
+ var channel = Radio.channel(channelName);
+ channel._tunedIn = false;
+ channel.off('all', _partial(channelName));
+ delete _logs[channelName];
+ return this;
+ }
+});
+
+/*
+ * Backbone.Radio.Requests
+ * -----------------------
+ * A messaging system for requesting data.
+ *
+ */
+
+function makeCallback(callback) {
+ return _.isFunction(callback) ? callback : function() { return callback; };
+}
+
+Radio.Requests = {
+
+ // Make a request
+ request: function(name) {
+ var args = _.toArray(arguments).slice(1);
+ var results = Radio._eventsApi(this, 'request', name, args);
+ if (results) {
+ return results;
+ }
+ var channelName = this.channelName;
+ var requests = this._requests;
+
+ // Check if we should log the request, and if so, do it
+ if (channelName && this._tunedIn) {
+ Radio.log.apply(this, [channelName, name].concat(args));
+ }
+
+ // If the request isn't handled, log it in DEBUG mode and exit
+ if (requests && (requests[name] || requests['default'])) {
+ var handler = requests[name] || requests['default'];
+ args = requests[name] ? args : arguments;
+ return Radio._callHandler(handler.callback, handler.context, args);
+ } else {
+ Radio.debugLog('An unhandled request was fired', name, channelName);
+ }
+ },
+
+ // Set up a handler for a request
+ reply: function(name, callback, context) {
+ if (Radio._eventsApi(this, 'reply', name, [callback, context])) {
+ return this;
+ }
+
+ this._requests || (this._requests = {});
+
+ if (this._requests[name]) {
+ Radio.debugLog('A request was overwritten', name, this.channelName);
+ }
+
+ this._requests[name] = {
+ callback: makeCallback(callback),
+ context: context || this
+ };
+
+ return this;
+ },
+
+ // Set up a handler that can only be requested once
+ replyOnce: function(name, callback, context) {
+ if (Radio._eventsApi(this, 'replyOnce', name, [callback, context])) {
+ return this;
+ }
+
+ var self = this;
+
+ var once = _.once(function() {
+ self.stopReplying(name);
+ return makeCallback(callback).apply(this, arguments);
+ });
+
+ return this.reply(name, once, context);
+ },
+
+ // Remove handler(s)
+ stopReplying: function(name, callback, context) {
+ if (Radio._eventsApi(this, 'stopReplying', name)) {
+ return this;
+ }
+
+ // Remove everything if there are no arguments passed
+ if (!name && !callback && !context) {
+ delete this._requests;
+ } else if (!removeHandlers(this._requests, name, callback, context)) {
+ Radio.debugLog('Attempted to remove the unregistered request', name, this.channelName);
+ }
+
+ return this;
+ }
+};
+
+/*
+ * Backbone.Radio.channel
+ * ----------------------
+ * Get a reference to a channel by name.
+ *
+ */
+
+Radio._channels = {};
+
+Radio.channel = function(channelName) {
+ if (!channelName) {
+ throw new Error('You must provide a name for the channel.');
+ }
+
+ if (Radio._channels[channelName]) {
+ return Radio._channels[channelName];
+ } else {
+ return (Radio._channels[channelName] = new Radio.Channel(channelName));
+ }
+};
+
+/*
+ * Backbone.Radio.Channel
+ * ----------------------
+ * A Channel is an object that extends from Backbone.Events,
+ * and Radio.Requests.
+ *
+ */
+
+Radio.Channel = function(channelName) {
+ this.channelName = channelName;
+};
+
+_.extend(Radio.Channel.prototype, Backbone.Events, Radio.Requests, {
+
+ // Remove all handlers from the messaging systems of this channel
+ reset: function() {
+ this.off();
+ this.stopListening();
+ this.stopReplying();
+ return this;
+ }
+});
+
+/*
+ * Top-level API
+ * -------------
+ * Supplies the 'top-level API' for working with Channels directly
+ * from Backbone.Radio.
+ *
+ */
+
+var channel, args, systems = [Backbone.Events, Radio.Requests];
+
+_.each(systems, function(system) {
+ _.each(system, function(method, methodName) {
+ Radio[methodName] = function(channelName) {
+ args = _.toArray(arguments).slice(1);
+ channel = this.channel(channelName);
+ return channel[methodName].apply(channel, args);
+ };
+ });
+});
+
+Radio.reset = function(channelName) {
+ var channels = !channelName ? this._channels : [this._channels[channelName]];
+ _.each(channels, function(channel) { channel.reset();});
+};
+
+export default Radio;
diff --git a/js/vendor/backbone/.bower.json b/js/vendor/backbone/.bower.json
new file mode 100644
index 000000000..14b5ba14e
--- /dev/null
+++ b/js/vendor/backbone/.bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "backbone",
+ "main": "backbone.js",
+ "dependencies": {
+ "underscore": ">=1.7.0"
+ },
+ "ignore": [
+ "docs",
+ "examples",
+ "test",
+ "*.yml",
+ "*.html",
+ "*.ico",
+ "*.md",
+ "CNAME",
+ ".*",
+ "karma.*",
+ "component.json",
+ "package.json"
+ ],
+ "homepage": "https://github.com/jashkenas/backbone",
+ "version": "1.2.3",
+ "_release": "1.2.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "1.2.3",
+ "commit": "05fde9e201f7e2137796663081105cd6dad12a98"
+ },
+ "_source": "https://github.com/jashkenas/backbone.git",
+ "_target": "1.2.3",
+ "_originalSource": "backbone"
+} \ No newline at end of file
diff --git a/js/vendor/backbone/LICENSE b/js/vendor/backbone/LICENSE
new file mode 100644
index 000000000..184d1b996
--- /dev/null
+++ b/js/vendor/backbone/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2010-2015 Jeremy Ashkenas, DocumentCloud
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/js/vendor/backbone/backbone-min.js b/js/vendor/backbone/backbone-min.js
new file mode 100644
index 000000000..1a1f708da
--- /dev/null
+++ b/js/vendor/backbone/backbone-min.js
@@ -0,0 +1,2 @@
+(function(t){var e=typeof self=="object"&&self.self==self&&self||typeof global=="object"&&global.global==global&&global;if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,n){e.Backbone=t(e,n,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore"),r;try{r=require("jquery")}catch(n){}t(e,exports,i,r)}else{e.Backbone=t(e,{},e._,e.jQuery||e.Zepto||e.ender||e.$)}})(function(t,e,i,r){var n=t.Backbone;var s=Array.prototype.slice;e.VERSION="1.2.3";e.$=r;e.noConflict=function(){t.Backbone=n;return this};e.emulateHTTP=false;e.emulateJSON=false;var a=function(t,e,r){switch(t){case 1:return function(){return i[e](this[r])};case 2:return function(t){return i[e](this[r],t)};case 3:return function(t,n){return i[e](this[r],h(t,this),n)};case 4:return function(t,n,s){return i[e](this[r],h(t,this),n,s)};default:return function(){var t=s.call(arguments);t.unshift(this[r]);return i[e].apply(i,t)}}};var o=function(t,e,r){i.each(e,function(e,n){if(i[n])t.prototype[n]=a(e,n,r)})};var h=function(t,e){if(i.isFunction(t))return t;if(i.isObject(t)&&!e._isModel(t))return u(t);if(i.isString(t))return function(e){return e.get(t)};return t};var u=function(t){var e=i.matches(t);return function(t){return e(t.attributes)}};var l=e.Events={};var c=/\s+/;var f=function(t,e,r,n,s){var a=0,o;if(r&&typeof r==="object"){if(n!==void 0&&"context"in s&&s.context===void 0)s.context=n;for(o=i.keys(r);a<o.length;a++){e=f(t,e,o[a],r[o[a]],s)}}else if(r&&c.test(r)){for(o=r.split(c);a<o.length;a++){e=t(e,o[a],n,s)}}else{e=t(e,r,n,s)}return e};l.on=function(t,e,i){return d(this,t,e,i)};var d=function(t,e,i,r,n){t._events=f(v,t._events||{},e,i,{context:r,ctx:t,listening:n});if(n){var s=t._listeners||(t._listeners={});s[n.id]=n}return t};l.listenTo=function(t,e,r){if(!t)return this;var n=t._listenId||(t._listenId=i.uniqueId("l"));var s=this._listeningTo||(this._listeningTo={});var a=s[n];if(!a){var o=this._listenId||(this._listenId=i.uniqueId("l"));a=s[n]={obj:t,objId:n,id:o,listeningTo:s,count:0}}d(t,e,r,this,a);return this};var v=function(t,e,i,r){if(i){var n=t[e]||(t[e]=[]);var s=r.context,a=r.ctx,o=r.listening;if(o)o.count++;n.push({callback:i,context:s,ctx:s||a,listening:o})}return t};l.off=function(t,e,i){if(!this._events)return this;this._events=f(g,this._events,t,e,{context:i,listeners:this._listeners});return this};l.stopListening=function(t,e,r){var n=this._listeningTo;if(!n)return this;var s=t?[t._listenId]:i.keys(n);for(var a=0;a<s.length;a++){var o=n[s[a]];if(!o)break;o.obj.off(e,r,this)}if(i.isEmpty(n))this._listeningTo=void 0;return this};var g=function(t,e,r,n){if(!t)return;var s=0,a;var o=n.context,h=n.listeners;if(!e&&!r&&!o){var u=i.keys(h);for(;s<u.length;s++){a=h[u[s]];delete h[a.id];delete a.listeningTo[a.objId]}return}var l=e?[e]:i.keys(t);for(;s<l.length;s++){e=l[s];var c=t[e];if(!c)break;var f=[];for(var d=0;d<c.length;d++){var v=c[d];if(r&&r!==v.callback&&r!==v.callback._callback||o&&o!==v.context){f.push(v)}else{a=v.listening;if(a&&--a.count===0){delete h[a.id];delete a.listeningTo[a.objId]}}}if(f.length){t[e]=f}else{delete t[e]}}if(i.size(t))return t};l.once=function(t,e,r){var n=f(p,{},t,e,i.bind(this.off,this));return this.on(n,void 0,r)};l.listenToOnce=function(t,e,r){var n=f(p,{},e,r,i.bind(this.stopListening,this,t));return this.listenTo(t,n)};var p=function(t,e,r,n){if(r){var s=t[e]=i.once(function(){n(e,s);r.apply(this,arguments)});s._callback=r}return t};l.trigger=function(t){if(!this._events)return this;var e=Math.max(0,arguments.length-1);var i=Array(e);for(var r=0;r<e;r++)i[r]=arguments[r+1];f(m,this._events,t,void 0,i);return this};var m=function(t,e,i,r){if(t){var n=t[e];var s=t.all;if(n&&s)s=s.slice();if(n)_(n,r);if(s)_(s,[e].concat(r))}return t};var _=function(t,e){var i,r=-1,n=t.length,s=e[0],a=e[1],o=e[2];switch(e.length){case 0:while(++r<n)(i=t[r]).callback.call(i.ctx);return;case 1:while(++r<n)(i=t[r]).callback.call(i.ctx,s);return;case 2:while(++r<n)(i=t[r]).callback.call(i.ctx,s,a);return;case 3:while(++r<n)(i=t[r]).callback.call(i.ctx,s,a,o);return;default:while(++r<n)(i=t[r]).callback.apply(i.ctx,e);return}};l.bind=l.on;l.unbind=l.off;i.extend(e,l);var y=e.Model=function(t,e){var r=t||{};e||(e={});this.cid=i.uniqueId(this.cidPrefix);this.attributes={};if(e.collection)this.collection=e.collection;if(e.parse)r=this.parse(r,e)||{};r=i.defaults({},r,i.result(this,"defaults"));this.set(r,e);this.changed={};this.initialize.apply(this,arguments)};i.extend(y.prototype,l,{changed:null,validationError:null,idAttribute:"id",cidPrefix:"c",initialize:function(){},toJSON:function(t){return i.clone(this.attributes)},sync:function(){return e.sync.apply(this,arguments)},get:function(t){return this.attributes[t]},escape:function(t){return i.escape(this.get(t))},has:function(t){return this.get(t)!=null},matches:function(t){return!!i.iteratee(t,this)(this.attributes)},set:function(t,e,r){if(t==null)return this;var n;if(typeof t==="object"){n=t;r=e}else{(n={})[t]=e}r||(r={});if(!this._validate(n,r))return false;var s=r.unset;var a=r.silent;var o=[];var h=this._changing;this._changing=true;if(!h){this._previousAttributes=i.clone(this.attributes);this.changed={}}var u=this.attributes;var l=this.changed;var c=this._previousAttributes;for(var f in n){e=n[f];if(!i.isEqual(u[f],e))o.push(f);if(!i.isEqual(c[f],e)){l[f]=e}else{delete l[f]}s?delete u[f]:u[f]=e}this.id=this.get(this.idAttribute);if(!a){if(o.length)this._pending=r;for(var d=0;d<o.length;d++){this.trigger("change:"+o[d],this,u[o[d]],r)}}if(h)return this;if(!a){while(this._pending){r=this._pending;this._pending=false;this.trigger("change",this,r)}}this._pending=false;this._changing=false;return this},unset:function(t,e){return this.set(t,void 0,i.extend({},e,{unset:true}))},clear:function(t){var e={};for(var r in this.attributes)e[r]=void 0;return this.set(e,i.extend({},t,{unset:true}))},hasChanged:function(t){if(t==null)return!i.isEmpty(this.changed);return i.has(this.changed,t)},changedAttributes:function(t){if(!t)return this.hasChanged()?i.clone(this.changed):false;var e=this._changing?this._previousAttributes:this.attributes;var r={};for(var n in t){var s=t[n];if(i.isEqual(e[n],s))continue;r[n]=s}return i.size(r)?r:false},previous:function(t){if(t==null||!this._previousAttributes)return null;return this._previousAttributes[t]},previousAttributes:function(){return i.clone(this._previousAttributes)},fetch:function(t){t=i.extend({parse:true},t);var e=this;var r=t.success;t.success=function(i){var n=t.parse?e.parse(i,t):i;if(!e.set(n,t))return false;if(r)r.call(t.context,e,i,t);e.trigger("sync",e,i,t)};z(this,t);return this.sync("read",this,t)},save:function(t,e,r){var n;if(t==null||typeof t==="object"){n=t;r=e}else{(n={})[t]=e}r=i.extend({validate:true,parse:true},r);var s=r.wait;if(n&&!s){if(!this.set(n,r))return false}else{if(!this._validate(n,r))return false}var a=this;var o=r.success;var h=this.attributes;r.success=function(t){a.attributes=h;var e=r.parse?a.parse(t,r):t;if(s)e=i.extend({},n,e);if(e&&!a.set(e,r))return false;if(o)o.call(r.context,a,t,r);a.trigger("sync",a,t,r)};z(this,r);if(n&&s)this.attributes=i.extend({},h,n);var u=this.isNew()?"create":r.patch?"patch":"update";if(u==="patch"&&!r.attrs)r.attrs=n;var l=this.sync(u,this,r);this.attributes=h;return l},destroy:function(t){t=t?i.clone(t):{};var e=this;var r=t.success;var n=t.wait;var s=function(){e.stopListening();e.trigger("destroy",e,e.collection,t)};t.success=function(i){if(n)s();if(r)r.call(t.context,e,i,t);if(!e.isNew())e.trigger("sync",e,i,t)};var a=false;if(this.isNew()){i.defer(t.success)}else{z(this,t);a=this.sync("delete",this,t)}if(!n)s();return a},url:function(){var t=i.result(this,"urlRoot")||i.result(this.collection,"url")||F();if(this.isNew())return t;var e=this.get(this.idAttribute);return t.replace(/[^\/]$/,"$&/")+encodeURIComponent(e)},parse:function(t,e){return t},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.has(this.idAttribute)},isValid:function(t){return this._validate({},i.defaults({validate:true},t))},_validate:function(t,e){if(!e.validate||!this.validate)return true;t=i.extend({},this.attributes,t);var r=this.validationError=this.validate(t,e)||null;if(!r)return true;this.trigger("invalid",this,r,i.extend(e,{validationError:r}));return false}});var b={keys:1,values:1,pairs:1,invert:1,pick:0,omit:0,chain:1,isEmpty:1};o(y,b,"attributes");var x=e.Collection=function(t,e){e||(e={});if(e.model)this.model=e.model;if(e.comparator!==void 0)this.comparator=e.comparator;this._reset();this.initialize.apply(this,arguments);if(t)this.reset(t,i.extend({silent:true},e))};var w={add:true,remove:true,merge:true};var E={add:true,remove:false};var k=function(t,e,i){i=Math.min(Math.max(i,0),t.length);var r=Array(t.length-i);var n=e.length;for(var s=0;s<r.length;s++)r[s]=t[s+i];for(s=0;s<n;s++)t[s+i]=e[s];for(s=0;s<r.length;s++)t[s+n+i]=r[s]};i.extend(x.prototype,l,{model:y,initialize:function(){},toJSON:function(t){return this.map(function(e){return e.toJSON(t)})},sync:function(){return e.sync.apply(this,arguments)},add:function(t,e){return this.set(t,i.extend({merge:false},e,E))},remove:function(t,e){e=i.extend({},e);var r=!i.isArray(t);t=r?[t]:i.clone(t);var n=this._removeModels(t,e);if(!e.silent&&n)this.trigger("update",this,e);return r?n[0]:n},set:function(t,e){if(t==null)return;e=i.defaults({},e,w);if(e.parse&&!this._isModel(t))t=this.parse(t,e);var r=!i.isArray(t);t=r?[t]:t.slice();var n=e.at;if(n!=null)n=+n;if(n<0)n+=this.length+1;var s=[];var a=[];var o=[];var h={};var u=e.add;var l=e.merge;var c=e.remove;var f=false;var d=this.comparator&&n==null&&e.sort!==false;var v=i.isString(this.comparator)?this.comparator:null;var g;for(var p=0;p<t.length;p++){g=t[p];var m=this.get(g);if(m){if(l&&g!==m){var _=this._isModel(g)?g.attributes:g;if(e.parse)_=m.parse(_,e);m.set(_,e);if(d&&!f)f=m.hasChanged(v)}if(!h[m.cid]){h[m.cid]=true;s.push(m)}t[p]=m}else if(u){g=t[p]=this._prepareModel(g,e);if(g){a.push(g);this._addReference(g,e);h[g.cid]=true;s.push(g)}}}if(c){for(p=0;p<this.length;p++){g=this.models[p];if(!h[g.cid])o.push(g)}if(o.length)this._removeModels(o,e)}var y=false;var b=!d&&u&&c;if(s.length&&b){y=this.length!=s.length||i.some(this.models,function(t,e){return t!==s[e]});this.models.length=0;k(this.models,s,0);this.length=this.models.length}else if(a.length){if(d)f=true;k(this.models,a,n==null?this.length:n);this.length=this.models.length}if(f)this.sort({silent:true});if(!e.silent){for(p=0;p<a.length;p++){if(n!=null)e.index=n+p;g=a[p];g.trigger("add",g,this,e)}if(f||y)this.trigger("sort",this,e);if(a.length||o.length)this.trigger("update",this,e)}return r?t[0]:t},reset:function(t,e){e=e?i.clone(e):{};for(var r=0;r<this.models.length;r++){this._removeReference(this.models[r],e)}e.previousModels=this.models;this._reset();t=this.add(t,i.extend({silent:true},e));if(!e.silent)this.trigger("reset",this,e);return t},push:function(t,e){return this.add(t,i.extend({at:this.length},e))},pop:function(t){var e=this.at(this.length-1);return this.remove(e,t)},unshift:function(t,e){return this.add(t,i.extend({at:0},e))},shift:function(t){var e=this.at(0);return this.remove(e,t)},slice:function(){return s.apply(this.models,arguments)},get:function(t){if(t==null)return void 0;var e=this.modelId(this._isModel(t)?t.attributes:t);return this._byId[t]||this._byId[e]||this._byId[t.cid]},at:function(t){if(t<0)t+=this.length;return this.models[t]},where:function(t,e){return this[e?"find":"filter"](t)},findWhere:function(t){return this.where(t,true)},sort:function(t){var e=this.comparator;if(!e)throw new Error("Cannot sort a set without a comparator");t||(t={});var r=e.length;if(i.isFunction(e))e=i.bind(e,this);if(r===1||i.isString(e)){this.models=this.sortBy(e)}else{this.models.sort(e)}if(!t.silent)this.trigger("sort",this,t);return this},pluck:function(t){return i.invoke(this.models,"get",t)},fetch:function(t){t=i.extend({parse:true},t);var e=t.success;var r=this;t.success=function(i){var n=t.reset?"reset":"set";r[n](i,t);if(e)e.call(t.context,r,i,t);r.trigger("sync",r,i,t)};z(this,t);return this.sync("read",this,t)},create:function(t,e){e=e?i.clone(e):{};var r=e.wait;t=this._prepareModel(t,e);if(!t)return false;if(!r)this.add(t,e);var n=this;var s=e.success;e.success=function(t,e,i){if(r)n.add(t,i);if(s)s.call(i.context,t,e,i)};t.save(null,e);return t},parse:function(t,e){return t},clone:function(){return new this.constructor(this.models,{model:this.model,comparator:this.comparator})},modelId:function(t){return t[this.model.prototype.idAttribute||"id"]},_reset:function(){this.length=0;this.models=[];this._byId={}},_prepareModel:function(t,e){if(this._isModel(t)){if(!t.collection)t.collection=this;return t}e=e?i.clone(e):{};e.collection=this;var r=new this.model(t,e);if(!r.validationError)return r;this.trigger("invalid",this,r.validationError,e);return false},_removeModels:function(t,e){var i=[];for(var r=0;r<t.length;r++){var n=this.get(t[r]);if(!n)continue;var s=this.indexOf(n);this.models.splice(s,1);this.length--;if(!e.silent){e.index=s;n.trigger("remove",n,this,e)}i.push(n);this._removeReference(n,e)}return i.length?i:false},_isModel:function(t){return t instanceof y},_addReference:function(t,e){this._byId[t.cid]=t;var i=this.modelId(t.attributes);if(i!=null)this._byId[i]=t;t.on("all",this._onModelEvent,this)},_removeReference:function(t,e){delete this._byId[t.cid];var i=this.modelId(t.attributes);if(i!=null)delete this._byId[i];if(this===t.collection)delete t.collection;t.off("all",this._onModelEvent,this)},_onModelEvent:function(t,e,i,r){if((t==="add"||t==="remove")&&i!==this)return;if(t==="destroy")this.remove(e,r);if(t==="change"){var n=this.modelId(e.previousAttributes());var s=this.modelId(e.attributes);if(n!==s){if(n!=null)delete this._byId[n];if(s!=null)this._byId[s]=e}}this.trigger.apply(this,arguments)}});var S={forEach:3,each:3,map:3,collect:3,reduce:4,foldl:4,inject:4,reduceRight:4,foldr:4,find:3,detect:3,filter:3,select:3,reject:3,every:3,all:3,some:3,any:3,include:3,includes:3,contains:3,invoke:0,max:3,min:3,toArray:1,size:1,first:3,head:3,take:3,initial:3,rest:3,tail:3,drop:3,last:3,without:0,difference:0,indexOf:3,shuffle:1,lastIndexOf:3,isEmpty:1,chain:1,sample:3,partition:3,groupBy:3,countBy:3,sortBy:3,indexBy:3};o(x,S,"models");var I=e.View=function(t){this.cid=i.uniqueId("view");i.extend(this,i.pick(t,P));this._ensureElement();this.initialize.apply(this,arguments)};var T=/^(\S+)\s*(.*)$/;var P=["model","collection","el","id","attributes","className","tagName","events"];i.extend(I.prototype,l,{tagName:"div",$:function(t){return this.$el.find(t)},initialize:function(){},render:function(){return this},remove:function(){this._removeElement();this.stopListening();return this},_removeElement:function(){this.$el.remove()},setElement:function(t){this.undelegateEvents();this._setElement(t);this.delegateEvents();return this},_setElement:function(t){this.$el=t instanceof e.$?t:e.$(t);this.el=this.$el[0]},delegateEvents:function(t){t||(t=i.result(this,"events"));if(!t)return this;this.undelegateEvents();for(var e in t){var r=t[e];if(!i.isFunction(r))r=this[r];if(!r)continue;var n=e.match(T);this.delegate(n[1],n[2],i.bind(r,this))}return this},delegate:function(t,e,i){this.$el.on(t+".delegateEvents"+this.cid,e,i);return this},undelegateEvents:function(){if(this.$el)this.$el.off(".delegateEvents"+this.cid);return this},undelegate:function(t,e,i){this.$el.off(t+".delegateEvents"+this.cid,e,i);return this},_createElement:function(t){return document.createElement(t)},_ensureElement:function(){if(!this.el){var t=i.extend({},i.result(this,"attributes"));if(this.id)t.id=i.result(this,"id");if(this.className)t["class"]=i.result(this,"className");this.setElement(this._createElement(i.result(this,"tagName")));this._setAttributes(t)}else{this.setElement(i.result(this,"el"))}},_setAttributes:function(t){this.$el.attr(t)}});e.sync=function(t,r,n){var s=H[t];i.defaults(n||(n={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:s,dataType:"json"};if(!n.url){a.url=i.result(r,"url")||F()}if(n.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(n.attrs||r.toJSON(n))}if(n.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(n.emulateHTTP&&(s==="PUT"||s==="DELETE"||s==="PATCH")){a.type="POST";if(n.emulateJSON)a.data._method=s;var o=n.beforeSend;n.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",s);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!n.emulateJSON){a.processData=false}var h=n.error;n.error=function(t,e,i){n.textStatus=e;n.errorThrown=i;if(h)h.call(n.context,t,e,i)};var u=n.xhr=e.ajax(i.extend(a,n));r.trigger("request",r,u,n);return u};var H={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var A=/\((.*?)\)/g;var C=/(\(\?)?:\w+/g;var R=/\*\w+/g;var j=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,l,{initialize:function(){},route:function(t,r,n){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){n=r;r=""}if(!n)n=this[r];var s=this;e.history.route(t,function(i){var a=s._extractParameters(t,i);if(s.execute(n,a,r)!==false){s.trigger.apply(s,["route:"+r].concat(a));s.trigger("route",r,a);e.history.trigger("route",s,r,a)}});return this},execute:function(t,e,i){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(j,"\\$&").replace(A,"(?:$1)?").replace(C,function(t,e){return e?t:"([^/?]+)"}).replace(R,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var M=e.History=function(){this.handlers=[];this.checkUrl=i.bind(this.checkUrl,this);if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var N=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var U=/#.*$/;M.started=false;i.extend(M.prototype,l,{interval:50,atRoot:function(){var t=this.location.pathname.replace(/[^\/]$/,"$&/");return t===this.root&&!this.getSearch()},matchRoot:function(){var t=this.decodeFragment(this.location.pathname);var e=t.slice(0,this.root.length-1)+"/";return e===this.root},decodeFragment:function(t){return decodeURI(t.replace(/%25/g,"%2525"))},getSearch:function(){var t=this.location.href.replace(/#.*/,"").match(/\?.+/);return t?t[0]:""},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getPath:function(){var t=this.decodeFragment(this.location.pathname+this.getSearch()).slice(this.root.length-1);return t.charAt(0)==="/"?t.slice(1):t},getFragment:function(t){if(t==null){if(this._usePushState||!this._wantsHashChange){t=this.getPath()}else{t=this.getHash()}}return t.replace(N,"")},start:function(t){if(M.started)throw new Error("Backbone.history has already been started");M.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._hasHashChange="onhashchange"in window&&(document.documentMode===void 0||document.documentMode>7);this._useHashChange=this._wantsHashChange&&this._hasHashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.history&&this.history.pushState);this._usePushState=this._wantsPushState&&this._hasPushState;this.fragment=this.getFragment();this.root=("/"+this.root+"/").replace(O,"/");if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){var e=this.root.slice(0,-1)||"/";this.location.replace(e+"#"+this.getPath());return true}else if(this._hasPushState&&this.atRoot()){this.navigate(this.getHash(),{replace:true})}}if(!this._hasHashChange&&this._wantsHashChange&&!this._usePushState){this.iframe=document.createElement("iframe");this.iframe.src="javascript:0";this.iframe.style.display="none";this.iframe.tabIndex=-1;var r=document.body;var n=r.insertBefore(this.iframe,r.firstChild).contentWindow;n.document.open();n.document.close();n.location.hash="#"+this.fragment}var s=window.addEventListener||function(t,e){return attachEvent("on"+t,e)};if(this._usePushState){s("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){s("hashchange",this.checkUrl,false)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}if(!this.options.silent)return this.loadUrl()},stop:function(){var t=window.removeEventListener||function(t,e){return detachEvent("on"+t,e)};if(this._usePushState){t("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){t("hashchange",this.checkUrl,false)}if(this.iframe){document.body.removeChild(this.iframe);this.iframe=null}if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);M.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getHash(this.iframe.contentWindow)}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(t){if(!this.matchRoot())return false;t=this.fragment=this.getFragment(t);return i.some(this.handlers,function(e){if(e.route.test(t)){e.callback(t);return true}})},navigate:function(t,e){if(!M.started)return false;if(!e||e===true)e={trigger:!!e};t=this.getFragment(t||"");var i=this.root;if(t===""||t.charAt(0)==="?"){i=i.slice(0,-1)||"/"}var r=i+t;t=this.decodeFragment(t.replace(U,""));if(this.fragment===t)return;this.fragment=t;if(this._usePushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,r)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getHash(this.iframe.contentWindow)){var n=this.iframe.contentWindow;if(!e.replace){n.document.open();n.document.close()}this._updateHash(n.location,t,e.replace)}}else{return this.location.assign(r)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,"");t.replace(r+"#"+e)}else{t.hash="#"+e}}});e.history=new M;var q=function(t,e){var r=this;var n;if(t&&i.has(t,"constructor")){n=t.constructor}else{n=function(){return r.apply(this,arguments)}}i.extend(n,r,e);var s=function(){this.constructor=n};s.prototype=r.prototype;n.prototype=new s;if(t)i.extend(n.prototype,t);n.__super__=r.prototype;return n};y.extend=x.extend=$.extend=I.extend=M.extend=q;var F=function(){throw new Error('A "url" property or function must be specified')};var z=function(t,e){var i=e.error;e.error=function(r){if(i)i.call(e.context,t,r,e);t.trigger("error",t,r,e)}};return e});
+//# sourceMappingURL=backbone-min.map \ No newline at end of file
diff --git a/js/vendor/backbone/backbone-min.map b/js/vendor/backbone/backbone-min.map
new file mode 100644
index 000000000..b728f9b3d
--- /dev/null
+++ b/js/vendor/backbone/backbone-min.map
@@ -0,0 +1 @@
+{"version":3,"file":"backbone-min.js","sources":["backbone.js"],"names":["factory","root","self","global","define","amd","_","$","exports","Backbone","require","e","jQuery","Zepto","ender","previousBackbone","slice","Array","prototype","VERSION","noConflict","this","emulateHTTP","emulateJSON","addMethod","length","method","attribute","value","iteratee","context","cb","defaultVal","args","call","arguments","unshift","apply","addUnderscoreMethods","Class","methods","each","instance","isFunction","isObject","_isModel","modelMatcher","isString","model","get","attrs","matcher","matches","attributes","Events","eventSplitter","eventsApi","events","name","callback","opts","i","names","keys","test","split","on","internalOn","obj","listening","_events","onApi","ctx","listeners","_listeners","id","listenTo","_listenId","uniqueId","listeningTo","_listeningTo","thisId","objId","count","options","handlers","push","off","offApi","stopListening","ids","isEmpty","remaining","j","handler","_callback","size","once","onceMap","bind","listenToOnce","map","offer","trigger","Math","max","triggerApi","objEvents","allEvents","all","triggerEvents","concat","ev","l","a1","a2","a3","unbind","extend","Model","cid","cidPrefix","collection","parse","defaults","result","set","changed","initialize","validationError","idAttribute","toJSON","clone","sync","attr","escape","has","key","val","_validate","unset","silent","changes","changing","_changing","_previousAttributes","current","prev","isEqual","_pending","clear","hasChanged","changedAttributes","diff","old","previous","previousAttributes","fetch","success","resp","serverAttrs","wrapError","save","validate","wait","isNew","patch","xhr","destroy","defer","url","base","urlError","replace","encodeURIComponent","constructor","isValid","error","modelMethods","values","pairs","invert","pick","omit","chain","Collection","models","comparator","_reset","reset","setOptions","add","remove","merge","addOptions","splice","array","insert","at","min","tail","singular","isArray","removed","_removeModels","toAdd","toRemove","modelMap","sort","sortable","sortAttr","existing","_prepareModel","_addReference","orderChanged","some","index","_removeReference","previousModels","pop","shift","modelId","_byId","where","first","findWhere","Error","sortBy","pluck","invoke","create","callbackOpts","indexOf","_onModelEvent","event","prevId","collectionMethods","forEach","collect","reduce","foldl","inject","reduceRight","foldr","find","detect","filter","select","reject","every","any","include","includes","contains","toArray","head","take","initial","rest","drop","last","without","difference","shuffle","lastIndexOf","sample","partition","groupBy","countBy","indexBy","View","viewOptions","_ensureElement","delegateEventSplitter","tagName","selector","$el","render","_removeElement","setElement","element","undelegateEvents","_setElement","delegateEvents","el","match","delegate","eventName","listener","undelegate","_createElement","document","createElement","className","_setAttributes","type","methodMap","params","dataType","data","contentType","JSON","stringify","_method","beforeSend","setRequestHeader","processData","textStatus","errorThrown","ajax","update","delete","read","Router","routes","_bindRoutes","optionalParam","namedParam","splatParam","escapeRegExp","route","isRegExp","_routeToRegExp","router","history","fragment","_extractParameters","execute","navigate","optional","RegExp","exec","param","decodeURIComponent","History","checkUrl","window","location","routeStripper","rootStripper","pathStripper","started","interval","atRoot","path","pathname","getSearch","matchRoot","decodeFragment","decodeURI","href","getHash","getPath","charAt","getFragment","_usePushState","_wantsHashChange","start","hashChange","_hasHashChange","documentMode","_useHashChange","_wantsPushState","pushState","_hasPushState","iframe","src","style","display","tabIndex","body","iWindow","insertBefore","firstChild","contentWindow","open","close","hash","addEventListener","attachEvent","_checkUrlInterval","setInterval","loadUrl","stop","removeEventListener","detachEvent","removeChild","clearInterval","title","_updateHash","assign","protoProps","staticProps","parent","child","Surrogate","__super__"],"mappings":"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"} \ No newline at end of file
diff --git a/js/vendor/backbone/backbone.js b/js/vendor/backbone/backbone.js
new file mode 100644
index 000000000..c92496562
--- /dev/null
+++ b/js/vendor/backbone/backbone.js
@@ -0,0 +1,1894 @@
+// Backbone.js 1.2.3
+
+// (c) 2010-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Backbone may be freely distributed under the MIT license.
+// For all details and documentation:
+// http://backbonejs.org
+
+(function(factory) {
+
+ // Establish the root object, `window` (`self`) in the browser, or `global` on the server.
+ // We use `self` instead of `window` for `WebWorker` support.
+ var root = (typeof self == 'object' && self.self == self && self) ||
+ (typeof global == 'object' && global.global == global && global);
+
+ // Set up Backbone appropriately for the environment. Start with AMD.
+ if (typeof define === 'function' && define.amd) {
+ define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
+ // Export global even in AMD case in case this script is loaded with
+ // others that may still expect a global Backbone.
+ root.Backbone = factory(root, exports, _, $);
+ });
+
+ // Next for Node.js or CommonJS. jQuery may not be needed as a module.
+ } else if (typeof exports !== 'undefined') {
+ var _ = require('underscore'), $;
+ try { $ = require('jquery'); } catch(e) {}
+ factory(root, exports, _, $);
+
+ // Finally, as a browser global.
+ } else {
+ root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
+ }
+
+}(function(root, Backbone, _, $) {
+
+ // Initial Setup
+ // -------------
+
+ // Save the previous value of the `Backbone` variable, so that it can be
+ // restored later on, if `noConflict` is used.
+ var previousBackbone = root.Backbone;
+
+ // Create a local reference to a common array method we'll want to use later.
+ var slice = Array.prototype.slice;
+
+ // Current version of the library. Keep in sync with `package.json`.
+ Backbone.VERSION = '1.2.3';
+
+ // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
+ // the `$` variable.
+ Backbone.$ = $;
+
+ // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
+ // to its previous owner. Returns a reference to this Backbone object.
+ Backbone.noConflict = function() {
+ root.Backbone = previousBackbone;
+ return this;
+ };
+
+ // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
+ // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
+ // set a `X-Http-Method-Override` header.
+ Backbone.emulateHTTP = false;
+
+ // Turn on `emulateJSON` to support legacy servers that can't deal with direct
+ // `application/json` requests ... this will encode the body as
+ // `application/x-www-form-urlencoded` instead and will send the model in a
+ // form param named `model`.
+ Backbone.emulateJSON = false;
+
+ // Proxy Backbone class methods to Underscore functions, wrapping the model's
+ // `attributes` object or collection's `models` array behind the scenes.
+ //
+ // collection.filter(function(model) { return model.get('age') > 10 });
+ // collection.each(this.addView);
+ //
+ // `Function#apply` can be slow so we use the method's arg count, if we know it.
+ var addMethod = function(length, method, attribute) {
+ switch (length) {
+ case 1: return function() {
+ return _[method](this[attribute]);
+ };
+ case 2: return function(value) {
+ return _[method](this[attribute], value);
+ };
+ case 3: return function(iteratee, context) {
+ return _[method](this[attribute], cb(iteratee, this), context);
+ };
+ case 4: return function(iteratee, defaultVal, context) {
+ return _[method](this[attribute], cb(iteratee, this), defaultVal, context);
+ };
+ default: return function() {
+ var args = slice.call(arguments);
+ args.unshift(this[attribute]);
+ return _[method].apply(_, args);
+ };
+ }
+ };
+ var addUnderscoreMethods = function(Class, methods, attribute) {
+ _.each(methods, function(length, method) {
+ if (_[method]) Class.prototype[method] = addMethod(length, method, attribute);
+ });
+ };
+
+ // Support `collection.sortBy('attr')` and `collection.findWhere({id: 1})`.
+ var cb = function(iteratee, instance) {
+ if (_.isFunction(iteratee)) return iteratee;
+ if (_.isObject(iteratee) && !instance._isModel(iteratee)) return modelMatcher(iteratee);
+ if (_.isString(iteratee)) return function(model) { return model.get(iteratee); };
+ return iteratee;
+ };
+ var modelMatcher = function(attrs) {
+ var matcher = _.matches(attrs);
+ return function(model) {
+ return matcher(model.attributes);
+ };
+ };
+
+ // Backbone.Events
+ // ---------------
+
+ // A module that can be mixed in to *any object* in order to provide it with
+ // a custom event channel. You may bind a callback to an event with `on` or
+ // remove with `off`; `trigger`-ing an event fires all callbacks in
+ // succession.
+ //
+ // var object = {};
+ // _.extend(object, Backbone.Events);
+ // object.on('expand', function(){ alert('expanded'); });
+ // object.trigger('expand');
+ //
+ var Events = Backbone.Events = {};
+
+ // Regular expression used to split event strings.
+ var eventSplitter = /\s+/;
+
+ // Iterates over the standard `event, callback` (as well as the fancy multiple
+ // space-separated events `"change blur", callback` and jQuery-style event
+ // maps `{event: callback}`).
+ var eventsApi = function(iteratee, events, name, callback, opts) {
+ var i = 0, names;
+ if (name && typeof name === 'object') {
+ // Handle event maps.
+ if (callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback;
+ for (names = _.keys(name); i < names.length ; i++) {
+ events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
+ }
+ } else if (name && eventSplitter.test(name)) {
+ // Handle space separated event names by delegating them individually.
+ for (names = name.split(eventSplitter); i < names.length; i++) {
+ events = iteratee(events, names[i], callback, opts);
+ }
+ } else {
+ // Finally, standard events.
+ events = iteratee(events, name, callback, opts);
+ }
+ return events;
+ };
+
+ // Bind an event to a `callback` function. Passing `"all"` will bind
+ // the callback to all events fired.
+ Events.on = function(name, callback, context) {
+ return internalOn(this, name, callback, context);
+ };
+
+ // Guard the `listening` argument from the public API.
+ var internalOn = function(obj, name, callback, context, listening) {
+ obj._events = eventsApi(onApi, obj._events || {}, name, callback, {
+ context: context,
+ ctx: obj,
+ listening: listening
+ });
+
+ if (listening) {
+ var listeners = obj._listeners || (obj._listeners = {});
+ listeners[listening.id] = listening;
+ }
+
+ return obj;
+ };
+
+ // Inversion-of-control versions of `on`. Tell *this* object to listen to
+ // an event in another object... keeping track of what it's listening to
+ // for easier unbinding later.
+ Events.listenTo = function(obj, name, callback) {
+ if (!obj) return this;
+ var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
+ var listeningTo = this._listeningTo || (this._listeningTo = {});
+ var listening = listeningTo[id];
+
+ // This object is not listening to any other events on `obj` yet.
+ // Setup the necessary references to track the listening callbacks.
+ if (!listening) {
+ var thisId = this._listenId || (this._listenId = _.uniqueId('l'));
+ listening = listeningTo[id] = {obj: obj, objId: id, id: thisId, listeningTo: listeningTo, count: 0};
+ }
+
+ // Bind callbacks on obj, and keep track of them on listening.
+ internalOn(obj, name, callback, this, listening);
+ return this;
+ };
+
+ // The reducing API that adds a callback to the `events` object.
+ var onApi = function(events, name, callback, options) {
+ if (callback) {
+ var handlers = events[name] || (events[name] = []);
+ var context = options.context, ctx = options.ctx, listening = options.listening;
+ if (listening) listening.count++;
+
+ handlers.push({ callback: callback, context: context, ctx: context || ctx, listening: listening });
+ }
+ return events;
+ };
+
+ // Remove one or many callbacks. If `context` is null, removes all
+ // callbacks with that function. If `callback` is null, removes all
+ // callbacks for the event. If `name` is null, removes all bound
+ // callbacks for all events.
+ Events.off = function(name, callback, context) {
+ if (!this._events) return this;
+ this._events = eventsApi(offApi, this._events, name, callback, {
+ context: context,
+ listeners: this._listeners
+ });
+ return this;
+ };
+
+ // Tell this object to stop listening to either specific events ... or
+ // to every object it's currently listening to.
+ Events.stopListening = function(obj, name, callback) {
+ var listeningTo = this._listeningTo;
+ if (!listeningTo) return this;
+
+ var ids = obj ? [obj._listenId] : _.keys(listeningTo);
+
+ for (var i = 0; i < ids.length; i++) {
+ var listening = listeningTo[ids[i]];
+
+ // If listening doesn't exist, this object is not currently
+ // listening to obj. Break out early.
+ if (!listening) break;
+
+ listening.obj.off(name, callback, this);
+ }
+ if (_.isEmpty(listeningTo)) this._listeningTo = void 0;
+
+ return this;
+ };
+
+ // The reducing API that removes a callback from the `events` object.
+ var offApi = function(events, name, callback, options) {
+ if (!events) return;
+
+ var i = 0, listening;
+ var context = options.context, listeners = options.listeners;
+
+ // Delete all events listeners and "drop" events.
+ if (!name && !callback && !context) {
+ var ids = _.keys(listeners);
+ for (; i < ids.length; i++) {
+ listening = listeners[ids[i]];
+ delete listeners[listening.id];
+ delete listening.listeningTo[listening.objId];
+ }
+ return;
+ }
+
+ var names = name ? [name] : _.keys(events);
+ for (; i < names.length; i++) {
+ name = names[i];
+ var handlers = events[name];
+
+ // Bail out if there are no events stored.
+ if (!handlers) break;
+
+ // Replace events if there are any remaining. Otherwise, clean up.
+ var remaining = [];
+ for (var j = 0; j < handlers.length; j++) {
+ var handler = handlers[j];
+ if (
+ callback && callback !== handler.callback &&
+ callback !== handler.callback._callback ||
+ context && context !== handler.context
+ ) {
+ remaining.push(handler);
+ } else {
+ listening = handler.listening;
+ if (listening && --listening.count === 0) {
+ delete listeners[listening.id];
+ delete listening.listeningTo[listening.objId];
+ }
+ }
+ }
+
+ // Update tail event if the list has any events. Otherwise, clean up.
+ if (remaining.length) {
+ events[name] = remaining;
+ } else {
+ delete events[name];
+ }
+ }
+ if (_.size(events)) return events;
+ };
+
+ // Bind an event to only be triggered a single time. After the first time
+ // the callback is invoked, its listener will be removed. If multiple events
+ // are passed in using the space-separated syntax, the handler will fire
+ // once for each event, not once for a combination of all events.
+ Events.once = function(name, callback, context) {
+ // Map the event into a `{event: once}` object.
+ var events = eventsApi(onceMap, {}, name, callback, _.bind(this.off, this));
+ return this.on(events, void 0, context);
+ };
+
+ // Inversion-of-control versions of `once`.
+ Events.listenToOnce = function(obj, name, callback) {
+ // Map the event into a `{event: once}` object.
+ var events = eventsApi(onceMap, {}, name, callback, _.bind(this.stopListening, this, obj));
+ return this.listenTo(obj, events);
+ };
+
+ // Reduces the event callbacks into a map of `{event: onceWrapper}`.
+ // `offer` unbinds the `onceWrapper` after it has been called.
+ var onceMap = function(map, name, callback, offer) {
+ if (callback) {
+ var once = map[name] = _.once(function() {
+ offer(name, once);
+ callback.apply(this, arguments);
+ });
+ once._callback = callback;
+ }
+ return map;
+ };
+
+ // Trigger one or many events, firing all bound callbacks. Callbacks are
+ // passed the same arguments as `trigger` is, apart from the event name
+ // (unless you're listening on `"all"`, which will cause your callback to
+ // receive the true name of the event as the first argument).
+ Events.trigger = function(name) {
+ if (!this._events) return this;
+
+ var length = Math.max(0, arguments.length - 1);
+ var args = Array(length);
+ for (var i = 0; i < length; i++) args[i] = arguments[i + 1];
+
+ eventsApi(triggerApi, this._events, name, void 0, args);
+ return this;
+ };
+
+ // Handles triggering the appropriate event callbacks.
+ var triggerApi = function(objEvents, name, cb, args) {
+ if (objEvents) {
+ var events = objEvents[name];
+ var allEvents = objEvents.all;
+ if (events && allEvents) allEvents = allEvents.slice();
+ if (events) triggerEvents(events, args);
+ if (allEvents) triggerEvents(allEvents, [name].concat(args));
+ }
+ return objEvents;
+ };
+
+ // A difficult-to-believe, but optimized internal dispatch function for
+ // triggering events. Tries to keep the usual cases speedy (most internal
+ // Backbone events have 3 arguments).
+ var triggerEvents = function(events, args) {
+ var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
+ switch (args.length) {
+ case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
+ case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
+ case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
+ case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
+ default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
+ }
+ };
+
+ // Aliases for backwards compatibility.
+ Events.bind = Events.on;
+ Events.unbind = Events.off;
+
+ // Allow the `Backbone` object to serve as a global event bus, for folks who
+ // want global "pubsub" in a convenient place.
+ _.extend(Backbone, Events);
+
+ // Backbone.Model
+ // --------------
+
+ // Backbone **Models** are the basic data object in the framework --
+ // frequently representing a row in a table in a database on your server.
+ // A discrete chunk of data and a bunch of useful, related methods for
+ // performing computations and transformations on that data.
+
+ // Create a new model with the specified attributes. A client id (`cid`)
+ // is automatically generated and assigned for you.
+ var Model = Backbone.Model = function(attributes, options) {
+ var attrs = attributes || {};
+ options || (options = {});
+ this.cid = _.uniqueId(this.cidPrefix);
+ this.attributes = {};
+ if (options.collection) this.collection = options.collection;
+ if (options.parse) attrs = this.parse(attrs, options) || {};
+ attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
+ this.set(attrs, options);
+ this.changed = {};
+ this.initialize.apply(this, arguments);
+ };
+
+ // Attach all inheritable methods to the Model prototype.
+ _.extend(Model.prototype, Events, {
+
+ // A hash of attributes whose current and previous value differ.
+ changed: null,
+
+ // The value returned during the last failed validation.
+ validationError: null,
+
+ // The default name for the JSON `id` attribute is `"id"`. MongoDB and
+ // CouchDB users may want to set this to `"_id"`.
+ idAttribute: 'id',
+
+ // The prefix is used to create the client id which is used to identify models locally.
+ // You may want to override this if you're experiencing name clashes with model ids.
+ cidPrefix: 'c',
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // Return a copy of the model's `attributes` object.
+ toJSON: function(options) {
+ return _.clone(this.attributes);
+ },
+
+ // Proxy `Backbone.sync` by default -- but override this if you need
+ // custom syncing semantics for *this* particular model.
+ sync: function() {
+ return Backbone.sync.apply(this, arguments);
+ },
+
+ // Get the value of an attribute.
+ get: function(attr) {
+ return this.attributes[attr];
+ },
+
+ // Get the HTML-escaped value of an attribute.
+ escape: function(attr) {
+ return _.escape(this.get(attr));
+ },
+
+ // Returns `true` if the attribute contains a value that is not null
+ // or undefined.
+ has: function(attr) {
+ return this.get(attr) != null;
+ },
+
+ // Special-cased proxy to underscore's `_.matches` method.
+ matches: function(attrs) {
+ return !!_.iteratee(attrs, this)(this.attributes);
+ },
+
+ // Set a hash of model attributes on the object, firing `"change"`. This is
+ // the core primitive operation of a model, updating the data and notifying
+ // anyone who needs to know about the change in state. The heart of the beast.
+ set: function(key, val, options) {
+ if (key == null) return this;
+
+ // Handle both `"key", value` and `{key: value}` -style arguments.
+ var attrs;
+ if (typeof key === 'object') {
+ attrs = key;
+ options = val;
+ } else {
+ (attrs = {})[key] = val;
+ }
+
+ options || (options = {});
+
+ // Run validation.
+ if (!this._validate(attrs, options)) return false;
+
+ // Extract attributes and options.
+ var unset = options.unset;
+ var silent = options.silent;
+ var changes = [];
+ var changing = this._changing;
+ this._changing = true;
+
+ if (!changing) {
+ this._previousAttributes = _.clone(this.attributes);
+ this.changed = {};
+ }
+
+ var current = this.attributes;
+ var changed = this.changed;
+ var prev = this._previousAttributes;
+
+ // For each `set` attribute, update or delete the current value.
+ for (var attr in attrs) {
+ val = attrs[attr];
+ if (!_.isEqual(current[attr], val)) changes.push(attr);
+ if (!_.isEqual(prev[attr], val)) {
+ changed[attr] = val;
+ } else {
+ delete changed[attr];
+ }
+ unset ? delete current[attr] : current[attr] = val;
+ }
+
+ // Update the `id`.
+ this.id = this.get(this.idAttribute);
+
+ // Trigger all relevant attribute changes.
+ if (!silent) {
+ if (changes.length) this._pending = options;
+ for (var i = 0; i < changes.length; i++) {
+ this.trigger('change:' + changes[i], this, current[changes[i]], options);
+ }
+ }
+
+ // You might be wondering why there's a `while` loop here. Changes can
+ // be recursively nested within `"change"` events.
+ if (changing) return this;
+ if (!silent) {
+ while (this._pending) {
+ options = this._pending;
+ this._pending = false;
+ this.trigger('change', this, options);
+ }
+ }
+ this._pending = false;
+ this._changing = false;
+ return this;
+ },
+
+ // Remove an attribute from the model, firing `"change"`. `unset` is a noop
+ // if the attribute doesn't exist.
+ unset: function(attr, options) {
+ return this.set(attr, void 0, _.extend({}, options, {unset: true}));
+ },
+
+ // Clear all attributes on the model, firing `"change"`.
+ clear: function(options) {
+ var attrs = {};
+ for (var key in this.attributes) attrs[key] = void 0;
+ return this.set(attrs, _.extend({}, options, {unset: true}));
+ },
+
+ // Determine if the model has changed since the last `"change"` event.
+ // If you specify an attribute name, determine if that attribute has changed.
+ hasChanged: function(attr) {
+ if (attr == null) return !_.isEmpty(this.changed);
+ return _.has(this.changed, attr);
+ },
+
+ // Return an object containing all the attributes that have changed, or
+ // false if there are no changed attributes. Useful for determining what
+ // parts of a view need to be updated and/or what attributes need to be
+ // persisted to the server. Unset attributes will be set to undefined.
+ // You can also pass an attributes object to diff against the model,
+ // determining if there *would be* a change.
+ changedAttributes: function(diff) {
+ if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
+ var old = this._changing ? this._previousAttributes : this.attributes;
+ var changed = {};
+ for (var attr in diff) {
+ var val = diff[attr];
+ if (_.isEqual(old[attr], val)) continue;
+ changed[attr] = val;
+ }
+ return _.size(changed) ? changed : false;
+ },
+
+ // Get the previous value of an attribute, recorded at the time the last
+ // `"change"` event was fired.
+ previous: function(attr) {
+ if (attr == null || !this._previousAttributes) return null;
+ return this._previousAttributes[attr];
+ },
+
+ // Get all of the attributes of the model at the time of the previous
+ // `"change"` event.
+ previousAttributes: function() {
+ return _.clone(this._previousAttributes);
+ },
+
+ // Fetch the model from the server, merging the response with the model's
+ // local attributes. Any changed attributes will trigger a "change" event.
+ fetch: function(options) {
+ options = _.extend({parse: true}, options);
+ var model = this;
+ var success = options.success;
+ options.success = function(resp) {
+ var serverAttrs = options.parse ? model.parse(resp, options) : resp;
+ if (!model.set(serverAttrs, options)) return false;
+ if (success) success.call(options.context, model, resp, options);
+ model.trigger('sync', model, resp, options);
+ };
+ wrapError(this, options);
+ return this.sync('read', this, options);
+ },
+
+ // Set a hash of model attributes, and sync the model to the server.
+ // If the server returns an attributes hash that differs, the model's
+ // state will be `set` again.
+ save: function(key, val, options) {
+ // Handle both `"key", value` and `{key: value}` -style arguments.
+ var attrs;
+ if (key == null || typeof key === 'object') {
+ attrs = key;
+ options = val;
+ } else {
+ (attrs = {})[key] = val;
+ }
+
+ options = _.extend({validate: true, parse: true}, options);
+ var wait = options.wait;
+
+ // If we're not waiting and attributes exist, save acts as
+ // `set(attr).save(null, opts)` with validation. Otherwise, check if
+ // the model will be valid when the attributes, if any, are set.
+ if (attrs && !wait) {
+ if (!this.set(attrs, options)) return false;
+ } else {
+ if (!this._validate(attrs, options)) return false;
+ }
+
+ // After a successful server-side save, the client is (optionally)
+ // updated with the server-side state.
+ var model = this;
+ var success = options.success;
+ var attributes = this.attributes;
+ options.success = function(resp) {
+ // Ensure attributes are restored during synchronous saves.
+ model.attributes = attributes;
+ var serverAttrs = options.parse ? model.parse(resp, options) : resp;
+ if (wait) serverAttrs = _.extend({}, attrs, serverAttrs);
+ if (serverAttrs && !model.set(serverAttrs, options)) return false;
+ if (success) success.call(options.context, model, resp, options);
+ model.trigger('sync', model, resp, options);
+ };
+ wrapError(this, options);
+
+ // Set temporary attributes if `{wait: true}` to properly find new ids.
+ if (attrs && wait) this.attributes = _.extend({}, attributes, attrs);
+
+ var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
+ if (method === 'patch' && !options.attrs) options.attrs = attrs;
+ var xhr = this.sync(method, this, options);
+
+ // Restore attributes.
+ this.attributes = attributes;
+
+ return xhr;
+ },
+
+ // Destroy this model on the server if it was already persisted.
+ // Optimistically removes the model from its collection, if it has one.
+ // If `wait: true` is passed, waits for the server to respond before removal.
+ destroy: function(options) {
+ options = options ? _.clone(options) : {};
+ var model = this;
+ var success = options.success;
+ var wait = options.wait;
+
+ var destroy = function() {
+ model.stopListening();
+ model.trigger('destroy', model, model.collection, options);
+ };
+
+ options.success = function(resp) {
+ if (wait) destroy();
+ if (success) success.call(options.context, model, resp, options);
+ if (!model.isNew()) model.trigger('sync', model, resp, options);
+ };
+
+ var xhr = false;
+ if (this.isNew()) {
+ _.defer(options.success);
+ } else {
+ wrapError(this, options);
+ xhr = this.sync('delete', this, options);
+ }
+ if (!wait) destroy();
+ return xhr;
+ },
+
+ // Default URL for the model's representation on the server -- if you're
+ // using Backbone's restful methods, override this to change the endpoint
+ // that will be called.
+ url: function() {
+ var base =
+ _.result(this, 'urlRoot') ||
+ _.result(this.collection, 'url') ||
+ urlError();
+ if (this.isNew()) return base;
+ var id = this.get(this.idAttribute);
+ return base.replace(/[^\/]$/, '$&/') + encodeURIComponent(id);
+ },
+
+ // **parse** converts a response into the hash of attributes to be `set` on
+ // the model. The default implementation is just to pass the response along.
+ parse: function(resp, options) {
+ return resp;
+ },
+
+ // Create a new model with identical attributes to this one.
+ clone: function() {
+ return new this.constructor(this.attributes);
+ },
+
+ // A model is new if it has never been saved to the server, and lacks an id.
+ isNew: function() {
+ return !this.has(this.idAttribute);
+ },
+
+ // Check if the model is currently in a valid state.
+ isValid: function(options) {
+ return this._validate({}, _.defaults({validate: true}, options));
+ },
+
+ // Run validation against the next complete set of model attributes,
+ // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
+ _validate: function(attrs, options) {
+ if (!options.validate || !this.validate) return true;
+ attrs = _.extend({}, this.attributes, attrs);
+ var error = this.validationError = this.validate(attrs, options) || null;
+ if (!error) return true;
+ this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
+ return false;
+ }
+
+ });
+
+ // Underscore methods that we want to implement on the Model, mapped to the
+ // number of arguments they take.
+ var modelMethods = { keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
+ omit: 0, chain: 1, isEmpty: 1 };
+
+ // Mix in each Underscore method as a proxy to `Model#attributes`.
+ addUnderscoreMethods(Model, modelMethods, 'attributes');
+
+ // Backbone.Collection
+ // -------------------
+
+ // If models tend to represent a single row of data, a Backbone Collection is
+ // more analogous to a table full of data ... or a small slice or page of that
+ // table, or a collection of rows that belong together for a particular reason
+ // -- all of the messages in this particular folder, all of the documents
+ // belonging to this particular author, and so on. Collections maintain
+ // indexes of their models, both in order, and for lookup by `id`.
+
+ // Create a new **Collection**, perhaps to contain a specific type of `model`.
+ // If a `comparator` is specified, the Collection will maintain
+ // its models in sort order, as they're added and removed.
+ var Collection = Backbone.Collection = function(models, options) {
+ options || (options = {});
+ if (options.model) this.model = options.model;
+ if (options.comparator !== void 0) this.comparator = options.comparator;
+ this._reset();
+ this.initialize.apply(this, arguments);
+ if (models) this.reset(models, _.extend({silent: true}, options));
+ };
+
+ // Default options for `Collection#set`.
+ var setOptions = {add: true, remove: true, merge: true};
+ var addOptions = {add: true, remove: false};
+
+ // Splices `insert` into `array` at index `at`.
+ var splice = function(array, insert, at) {
+ at = Math.min(Math.max(at, 0), array.length);
+ var tail = Array(array.length - at);
+ var length = insert.length;
+ for (var i = 0; i < tail.length; i++) tail[i] = array[i + at];
+ for (i = 0; i < length; i++) array[i + at] = insert[i];
+ for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];
+ };
+
+ // Define the Collection's inheritable methods.
+ _.extend(Collection.prototype, Events, {
+
+ // The default model for a collection is just a **Backbone.Model**.
+ // This should be overridden in most cases.
+ model: Model,
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // The JSON representation of a Collection is an array of the
+ // models' attributes.
+ toJSON: function(options) {
+ return this.map(function(model) { return model.toJSON(options); });
+ },
+
+ // Proxy `Backbone.sync` by default.
+ sync: function() {
+ return Backbone.sync.apply(this, arguments);
+ },
+
+ // Add a model, or list of models to the set. `models` may be Backbone
+ // Models or raw JavaScript objects to be converted to Models, or any
+ // combination of the two.
+ add: function(models, options) {
+ return this.set(models, _.extend({merge: false}, options, addOptions));
+ },
+
+ // Remove a model, or a list of models from the set.
+ remove: function(models, options) {
+ options = _.extend({}, options);
+ var singular = !_.isArray(models);
+ models = singular ? [models] : _.clone(models);
+ var removed = this._removeModels(models, options);
+ if (!options.silent && removed) this.trigger('update', this, options);
+ return singular ? removed[0] : removed;
+ },
+
+ // Update a collection by `set`-ing a new list of models, adding new ones,
+ // removing models that are no longer present, and merging models that
+ // already exist in the collection, as necessary. Similar to **Model#set**,
+ // the core operation for updating the data contained by the collection.
+ set: function(models, options) {
+ if (models == null) return;
+
+ options = _.defaults({}, options, setOptions);
+ if (options.parse && !this._isModel(models)) models = this.parse(models, options);
+
+ var singular = !_.isArray(models);
+ models = singular ? [models] : models.slice();
+
+ var at = options.at;
+ if (at != null) at = +at;
+ if (at < 0) at += this.length + 1;
+
+ var set = [];
+ var toAdd = [];
+ var toRemove = [];
+ var modelMap = {};
+
+ var add = options.add;
+ var merge = options.merge;
+ var remove = options.remove;
+
+ var sort = false;
+ var sortable = this.comparator && (at == null) && options.sort !== false;
+ var sortAttr = _.isString(this.comparator) ? this.comparator : null;
+
+ // Turn bare objects into model references, and prevent invalid models
+ // from being added.
+ var model;
+ for (var i = 0; i < models.length; i++) {
+ model = models[i];
+
+ // If a duplicate is found, prevent it from being added and
+ // optionally merge it into the existing model.
+ var existing = this.get(model);
+ if (existing) {
+ if (merge && model !== existing) {
+ var attrs = this._isModel(model) ? model.attributes : model;
+ if (options.parse) attrs = existing.parse(attrs, options);
+ existing.set(attrs, options);
+ if (sortable && !sort) sort = existing.hasChanged(sortAttr);
+ }
+ if (!modelMap[existing.cid]) {
+ modelMap[existing.cid] = true;
+ set.push(existing);
+ }
+ models[i] = existing;
+
+ // If this is a new, valid model, push it to the `toAdd` list.
+ } else if (add) {
+ model = models[i] = this._prepareModel(model, options);
+ if (model) {
+ toAdd.push(model);
+ this._addReference(model, options);
+ modelMap[model.cid] = true;
+ set.push(model);
+ }
+ }
+ }
+
+ // Remove stale models.
+ if (remove) {
+ for (i = 0; i < this.length; i++) {
+ model = this.models[i];
+ if (!modelMap[model.cid]) toRemove.push(model);
+ }
+ if (toRemove.length) this._removeModels(toRemove, options);
+ }
+
+ // See if sorting is needed, update `length` and splice in new models.
+ var orderChanged = false;
+ var replace = !sortable && add && remove;
+ if (set.length && replace) {
+ orderChanged = this.length != set.length || _.some(this.models, function(model, index) {
+ return model !== set[index];
+ });
+ this.models.length = 0;
+ splice(this.models, set, 0);
+ this.length = this.models.length;
+ } else if (toAdd.length) {
+ if (sortable) sort = true;
+ splice(this.models, toAdd, at == null ? this.length : at);
+ this.length = this.models.length;
+ }
+
+ // Silently sort the collection if appropriate.
+ if (sort) this.sort({silent: true});
+
+ // Unless silenced, it's time to fire all appropriate add/sort events.
+ if (!options.silent) {
+ for (i = 0; i < toAdd.length; i++) {
+ if (at != null) options.index = at + i;
+ model = toAdd[i];
+ model.trigger('add', model, this, options);
+ }
+ if (sort || orderChanged) this.trigger('sort', this, options);
+ if (toAdd.length || toRemove.length) this.trigger('update', this, options);
+ }
+
+ // Return the added (or merged) model (or models).
+ return singular ? models[0] : models;
+ },
+
+ // When you have more items than you want to add or remove individually,
+ // you can reset the entire set with a new list of models, without firing
+ // any granular `add` or `remove` events. Fires `reset` when finished.
+ // Useful for bulk operations and optimizations.
+ reset: function(models, options) {
+ options = options ? _.clone(options) : {};
+ for (var i = 0; i < this.models.length; i++) {
+ this._removeReference(this.models[i], options);
+ }
+ options.previousModels = this.models;
+ this._reset();
+ models = this.add(models, _.extend({silent: true}, options));
+ if (!options.silent) this.trigger('reset', this, options);
+ return models;
+ },
+
+ // Add a model to the end of the collection.
+ push: function(model, options) {
+ return this.add(model, _.extend({at: this.length}, options));
+ },
+
+ // Remove a model from the end of the collection.
+ pop: function(options) {
+ var model = this.at(this.length - 1);
+ return this.remove(model, options);
+ },
+
+ // Add a model to the beginning of the collection.
+ unshift: function(model, options) {
+ return this.add(model, _.extend({at: 0}, options));
+ },
+
+ // Remove a model from the beginning of the collection.
+ shift: function(options) {
+ var model = this.at(0);
+ return this.remove(model, options);
+ },
+
+ // Slice out a sub-array of models from the collection.
+ slice: function() {
+ return slice.apply(this.models, arguments);
+ },
+
+ // Get a model from the set by id.
+ get: function(obj) {
+ if (obj == null) return void 0;
+ var id = this.modelId(this._isModel(obj) ? obj.attributes : obj);
+ return this._byId[obj] || this._byId[id] || this._byId[obj.cid];
+ },
+
+ // Get the model at the given index.
+ at: function(index) {
+ if (index < 0) index += this.length;
+ return this.models[index];
+ },
+
+ // Return models with matching attributes. Useful for simple cases of
+ // `filter`.
+ where: function(attrs, first) {
+ return this[first ? 'find' : 'filter'](attrs);
+ },
+
+ // Return the first model with matching attributes. Useful for simple cases
+ // of `find`.
+ findWhere: function(attrs) {
+ return this.where(attrs, true);
+ },
+
+ // Force the collection to re-sort itself. You don't need to call this under
+ // normal circumstances, as the set will maintain sort order as each item
+ // is added.
+ sort: function(options) {
+ var comparator = this.comparator;
+ if (!comparator) throw new Error('Cannot sort a set without a comparator');
+ options || (options = {});
+
+ var length = comparator.length;
+ if (_.isFunction(comparator)) comparator = _.bind(comparator, this);
+
+ // Run sort based on type of `comparator`.
+ if (length === 1 || _.isString(comparator)) {
+ this.models = this.sortBy(comparator);
+ } else {
+ this.models.sort(comparator);
+ }
+ if (!options.silent) this.trigger('sort', this, options);
+ return this;
+ },
+
+ // Pluck an attribute from each model in the collection.
+ pluck: function(attr) {
+ return _.invoke(this.models, 'get', attr);
+ },
+
+ // Fetch the default set of models for this collection, resetting the
+ // collection when they arrive. If `reset: true` is passed, the response
+ // data will be passed through the `reset` method instead of `set`.
+ fetch: function(options) {
+ options = _.extend({parse: true}, options);
+ var success = options.success;
+ var collection = this;
+ options.success = function(resp) {
+ var method = options.reset ? 'reset' : 'set';
+ collection[method](resp, options);
+ if (success) success.call(options.context, collection, resp, options);
+ collection.trigger('sync', collection, resp, options);
+ };
+ wrapError(this, options);
+ return this.sync('read', this, options);
+ },
+
+ // Create a new instance of a model in this collection. Add the model to the
+ // collection immediately, unless `wait: true` is passed, in which case we
+ // wait for the server to agree.
+ create: function(model, options) {
+ options = options ? _.clone(options) : {};
+ var wait = options.wait;
+ model = this._prepareModel(model, options);
+ if (!model) return false;
+ if (!wait) this.add(model, options);
+ var collection = this;
+ var success = options.success;
+ options.success = function(model, resp, callbackOpts) {
+ if (wait) collection.add(model, callbackOpts);
+ if (success) success.call(callbackOpts.context, model, resp, callbackOpts);
+ };
+ model.save(null, options);
+ return model;
+ },
+
+ // **parse** converts a response into a list of models to be added to the
+ // collection. The default implementation is just to pass it through.
+ parse: function(resp, options) {
+ return resp;
+ },
+
+ // Create a new collection with an identical list of models as this one.
+ clone: function() {
+ return new this.constructor(this.models, {
+ model: this.model,
+ comparator: this.comparator
+ });
+ },
+
+ // Define how to uniquely identify models in the collection.
+ modelId: function (attrs) {
+ return attrs[this.model.prototype.idAttribute || 'id'];
+ },
+
+ // Private method to reset all internal state. Called when the collection
+ // is first initialized or reset.
+ _reset: function() {
+ this.length = 0;
+ this.models = [];
+ this._byId = {};
+ },
+
+ // Prepare a hash of attributes (or other model) to be added to this
+ // collection.
+ _prepareModel: function(attrs, options) {
+ if (this._isModel(attrs)) {
+ if (!attrs.collection) attrs.collection = this;
+ return attrs;
+ }
+ options = options ? _.clone(options) : {};
+ options.collection = this;
+ var model = new this.model(attrs, options);
+ if (!model.validationError) return model;
+ this.trigger('invalid', this, model.validationError, options);
+ return false;
+ },
+
+ // Internal method called by both remove and set.
+ _removeModels: function(models, options) {
+ var removed = [];
+ for (var i = 0; i < models.length; i++) {
+ var model = this.get(models[i]);
+ if (!model) continue;
+
+ var index = this.indexOf(model);
+ this.models.splice(index, 1);
+ this.length--;
+
+ if (!options.silent) {
+ options.index = index;
+ model.trigger('remove', model, this, options);
+ }
+
+ removed.push(model);
+ this._removeReference(model, options);
+ }
+ return removed.length ? removed : false;
+ },
+
+ // Method for checking whether an object should be considered a model for
+ // the purposes of adding to the collection.
+ _isModel: function (model) {
+ return model instanceof Model;
+ },
+
+ // Internal method to create a model's ties to a collection.
+ _addReference: function(model, options) {
+ this._byId[model.cid] = model;
+ var id = this.modelId(model.attributes);
+ if (id != null) this._byId[id] = model;
+ model.on('all', this._onModelEvent, this);
+ },
+
+ // Internal method to sever a model's ties to a collection.
+ _removeReference: function(model, options) {
+ delete this._byId[model.cid];
+ var id = this.modelId(model.attributes);
+ if (id != null) delete this._byId[id];
+ if (this === model.collection) delete model.collection;
+ model.off('all', this._onModelEvent, this);
+ },
+
+ // Internal method called every time a model in the set fires an event.
+ // Sets need to update their indexes when models change ids. All other
+ // events simply proxy through. "add" and "remove" events that originate
+ // in other collections are ignored.
+ _onModelEvent: function(event, model, collection, options) {
+ if ((event === 'add' || event === 'remove') && collection !== this) return;
+ if (event === 'destroy') this.remove(model, options);
+ if (event === 'change') {
+ var prevId = this.modelId(model.previousAttributes());
+ var id = this.modelId(model.attributes);
+ if (prevId !== id) {
+ if (prevId != null) delete this._byId[prevId];
+ if (id != null) this._byId[id] = model;
+ }
+ }
+ this.trigger.apply(this, arguments);
+ }
+
+ });
+
+ // Underscore methods that we want to implement on the Collection.
+ // 90% of the core usefulness of Backbone Collections is actually implemented
+ // right here:
+ var collectionMethods = { forEach: 3, each: 3, map: 3, collect: 3, reduce: 4,
+ foldl: 4, inject: 4, reduceRight: 4, foldr: 4, find: 3, detect: 3, filter: 3,
+ select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,
+ contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
+ head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
+ without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
+ isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,
+ sortBy: 3, indexBy: 3};
+
+ // Mix in each Underscore method as a proxy to `Collection#models`.
+ addUnderscoreMethods(Collection, collectionMethods, 'models');
+
+ // Backbone.View
+ // -------------
+
+ // Backbone Views are almost more convention than they are actual code. A View
+ // is simply a JavaScript object that represents a logical chunk of UI in the
+ // DOM. This might be a single item, an entire list, a sidebar or panel, or
+ // even the surrounding frame which wraps your whole app. Defining a chunk of
+ // UI as a **View** allows you to define your DOM events declaratively, without
+ // having to worry about render order ... and makes it easy for the view to
+ // react to specific changes in the state of your models.
+
+ // Creating a Backbone.View creates its initial element outside of the DOM,
+ // if an existing element is not provided...
+ var View = Backbone.View = function(options) {
+ this.cid = _.uniqueId('view');
+ _.extend(this, _.pick(options, viewOptions));
+ this._ensureElement();
+ this.initialize.apply(this, arguments);
+ };
+
+ // Cached regex to split keys for `delegate`.
+ var delegateEventSplitter = /^(\S+)\s*(.*)$/;
+
+ // List of view options to be set as properties.
+ var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
+
+ // Set up all inheritable **Backbone.View** properties and methods.
+ _.extend(View.prototype, Events, {
+
+ // The default `tagName` of a View's element is `"div"`.
+ tagName: 'div',
+
+ // jQuery delegate for element lookup, scoped to DOM elements within the
+ // current view. This should be preferred to global lookups where possible.
+ $: function(selector) {
+ return this.$el.find(selector);
+ },
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // **render** is the core function that your view should override, in order
+ // to populate its element (`this.el`), with the appropriate HTML. The
+ // convention is for **render** to always return `this`.
+ render: function() {
+ return this;
+ },
+
+ // Remove this view by taking the element out of the DOM, and removing any
+ // applicable Backbone.Events listeners.
+ remove: function() {
+ this._removeElement();
+ this.stopListening();
+ return this;
+ },
+
+ // Remove this view's element from the document and all event listeners
+ // attached to it. Exposed for subclasses using an alternative DOM
+ // manipulation API.
+ _removeElement: function() {
+ this.$el.remove();
+ },
+
+ // Change the view's element (`this.el` property) and re-delegate the
+ // view's events on the new element.
+ setElement: function(element) {
+ this.undelegateEvents();
+ this._setElement(element);
+ this.delegateEvents();
+ return this;
+ },
+
+ // Creates the `this.el` and `this.$el` references for this view using the
+ // given `el`. `el` can be a CSS selector or an HTML string, a jQuery
+ // context or an element. Subclasses can override this to utilize an
+ // alternative DOM manipulation API and are only required to set the
+ // `this.el` property.
+ _setElement: function(el) {
+ this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
+ this.el = this.$el[0];
+ },
+
+ // Set callbacks, where `this.events` is a hash of
+ //
+ // *{"event selector": "callback"}*
+ //
+ // {
+ // 'mousedown .title': 'edit',
+ // 'click .button': 'save',
+ // 'click .open': function(e) { ... }
+ // }
+ //
+ // pairs. Callbacks will be bound to the view, with `this` set properly.
+ // Uses event delegation for efficiency.
+ // Omitting the selector binds the event to `this.el`.
+ delegateEvents: function(events) {
+ events || (events = _.result(this, 'events'));
+ if (!events) return this;
+ this.undelegateEvents();
+ for (var key in events) {
+ var method = events[key];
+ if (!_.isFunction(method)) method = this[method];
+ if (!method) continue;
+ var match = key.match(delegateEventSplitter);
+ this.delegate(match[1], match[2], _.bind(method, this));
+ }
+ return this;
+ },
+
+ // Add a single event listener to the view's element (or a child element
+ // using `selector`). This only works for delegate-able events: not `focus`,
+ // `blur`, and not `change`, `submit`, and `reset` in Internet Explorer.
+ delegate: function(eventName, selector, listener) {
+ this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
+ return this;
+ },
+
+ // Clears all callbacks previously bound to the view by `delegateEvents`.
+ // You usually don't need to use this, but may wish to if you have multiple
+ // Backbone views attached to the same DOM element.
+ undelegateEvents: function() {
+ if (this.$el) this.$el.off('.delegateEvents' + this.cid);
+ return this;
+ },
+
+ // A finer-grained `undelegateEvents` for removing a single delegated event.
+ // `selector` and `listener` are both optional.
+ undelegate: function(eventName, selector, listener) {
+ this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);
+ return this;
+ },
+
+ // Produces a DOM element to be assigned to your view. Exposed for
+ // subclasses using an alternative DOM manipulation API.
+ _createElement: function(tagName) {
+ return document.createElement(tagName);
+ },
+
+ // Ensure that the View has a DOM element to render into.
+ // If `this.el` is a string, pass it through `$()`, take the first
+ // matching element, and re-assign it to `el`. Otherwise, create
+ // an element from the `id`, `className` and `tagName` properties.
+ _ensureElement: function() {
+ if (!this.el) {
+ var attrs = _.extend({}, _.result(this, 'attributes'));
+ if (this.id) attrs.id = _.result(this, 'id');
+ if (this.className) attrs['class'] = _.result(this, 'className');
+ this.setElement(this._createElement(_.result(this, 'tagName')));
+ this._setAttributes(attrs);
+ } else {
+ this.setElement(_.result(this, 'el'));
+ }
+ },
+
+ // Set attributes from a hash on this view's element. Exposed for
+ // subclasses using an alternative DOM manipulation API.
+ _setAttributes: function(attributes) {
+ this.$el.attr(attributes);
+ }
+
+ });
+
+ // Backbone.sync
+ // -------------
+
+ // Override this function to change the manner in which Backbone persists
+ // models to the server. You will be passed the type of request, and the
+ // model in question. By default, makes a RESTful Ajax request
+ // to the model's `url()`. Some possible customizations could be:
+ //
+ // * Use `setTimeout` to batch rapid-fire updates into a single request.
+ // * Send up the models as XML instead of JSON.
+ // * Persist models via WebSockets instead of Ajax.
+ //
+ // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
+ // as `POST`, with a `_method` parameter containing the true HTTP method,
+ // as well as all requests with the body as `application/x-www-form-urlencoded`
+ // instead of `application/json` with the model in a param named `model`.
+ // Useful when interfacing with server-side languages like **PHP** that make
+ // it difficult to read the body of `PUT` requests.
+ Backbone.sync = function(method, model, options) {
+ var type = methodMap[method];
+
+ // Default options, unless specified.
+ _.defaults(options || (options = {}), {
+ emulateHTTP: Backbone.emulateHTTP,
+ emulateJSON: Backbone.emulateJSON
+ });
+
+ // Default JSON-request options.
+ var params = {type: type, dataType: 'json'};
+
+ // Ensure that we have a URL.
+ if (!options.url) {
+ params.url = _.result(model, 'url') || urlError();
+ }
+
+ // Ensure that we have the appropriate request data.
+ if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
+ params.contentType = 'application/json';
+ params.data = JSON.stringify(options.attrs || model.toJSON(options));
+ }
+
+ // For older servers, emulate JSON by encoding the request into an HTML-form.
+ if (options.emulateJSON) {
+ params.contentType = 'application/x-www-form-urlencoded';
+ params.data = params.data ? {model: params.data} : {};
+ }
+
+ // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
+ // And an `X-HTTP-Method-Override` header.
+ if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
+ params.type = 'POST';
+ if (options.emulateJSON) params.data._method = type;
+ var beforeSend = options.beforeSend;
+ options.beforeSend = function(xhr) {
+ xhr.setRequestHeader('X-HTTP-Method-Override', type);
+ if (beforeSend) return beforeSend.apply(this, arguments);
+ };
+ }
+
+ // Don't process data on a non-GET request.
+ if (params.type !== 'GET' && !options.emulateJSON) {
+ params.processData = false;
+ }
+
+ // Pass along `textStatus` and `errorThrown` from jQuery.
+ var error = options.error;
+ options.error = function(xhr, textStatus, errorThrown) {
+ options.textStatus = textStatus;
+ options.errorThrown = errorThrown;
+ if (error) error.call(options.context, xhr, textStatus, errorThrown);
+ };
+
+ // Make the request, allowing the user to override any Ajax options.
+ var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
+ model.trigger('request', model, xhr, options);
+ return xhr;
+ };
+
+ // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
+ var methodMap = {
+ 'create': 'POST',
+ 'update': 'PUT',
+ 'patch': 'PATCH',
+ 'delete': 'DELETE',
+ 'read': 'GET'
+ };
+
+ // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
+ // Override this if you'd like to use a different library.
+ Backbone.ajax = function() {
+ return Backbone.$.ajax.apply(Backbone.$, arguments);
+ };
+
+ // Backbone.Router
+ // ---------------
+
+ // Routers map faux-URLs to actions, and fire events when routes are
+ // matched. Creating a new one sets its `routes` hash, if not set statically.
+ var Router = Backbone.Router = function(options) {
+ options || (options = {});
+ if (options.routes) this.routes = options.routes;
+ this._bindRoutes();
+ this.initialize.apply(this, arguments);
+ };
+
+ // Cached regular expressions for matching named param parts and splatted
+ // parts of route strings.
+ var optionalParam = /\((.*?)\)/g;
+ var namedParam = /(\(\?)?:\w+/g;
+ var splatParam = /\*\w+/g;
+ var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
+
+ // Set up all inheritable **Backbone.Router** properties and methods.
+ _.extend(Router.prototype, Events, {
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // Manually bind a single named route to a callback. For example:
+ //
+ // this.route('search/:query/p:num', 'search', function(query, num) {
+ // ...
+ // });
+ //
+ route: function(route, name, callback) {
+ if (!_.isRegExp(route)) route = this._routeToRegExp(route);
+ if (_.isFunction(name)) {
+ callback = name;
+ name = '';
+ }
+ if (!callback) callback = this[name];
+ var router = this;
+ Backbone.history.route(route, function(fragment) {
+ var args = router._extractParameters(route, fragment);
+ if (router.execute(callback, args, name) !== false) {
+ router.trigger.apply(router, ['route:' + name].concat(args));
+ router.trigger('route', name, args);
+ Backbone.history.trigger('route', router, name, args);
+ }
+ });
+ return this;
+ },
+
+ // Execute a route handler with the provided parameters. This is an
+ // excellent place to do pre-route setup or post-route cleanup.
+ execute: function(callback, args, name) {
+ if (callback) callback.apply(this, args);
+ },
+
+ // Simple proxy to `Backbone.history` to save a fragment into the history.
+ navigate: function(fragment, options) {
+ Backbone.history.navigate(fragment, options);
+ return this;
+ },
+
+ // Bind all defined routes to `Backbone.history`. We have to reverse the
+ // order of the routes here to support behavior where the most general
+ // routes can be defined at the bottom of the route map.
+ _bindRoutes: function() {
+ if (!this.routes) return;
+ this.routes = _.result(this, 'routes');
+ var route, routes = _.keys(this.routes);
+ while ((route = routes.pop()) != null) {
+ this.route(route, this.routes[route]);
+ }
+ },
+
+ // Convert a route string into a regular expression, suitable for matching
+ // against the current location hash.
+ _routeToRegExp: function(route) {
+ route = route.replace(escapeRegExp, '\\$&')
+ .replace(optionalParam, '(?:$1)?')
+ .replace(namedParam, function(match, optional) {
+ return optional ? match : '([^/?]+)';
+ })
+ .replace(splatParam, '([^?]*?)');
+ return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
+ },
+
+ // Given a route, and a URL fragment that it matches, return the array of
+ // extracted decoded parameters. Empty or unmatched parameters will be
+ // treated as `null` to normalize cross-browser behavior.
+ _extractParameters: function(route, fragment) {
+ var params = route.exec(fragment).slice(1);
+ return _.map(params, function(param, i) {
+ // Don't decode the search params.
+ if (i === params.length - 1) return param || null;
+ return param ? decodeURIComponent(param) : null;
+ });
+ }
+
+ });
+
+ // Backbone.History
+ // ----------------
+
+ // Handles cross-browser history management, based on either
+ // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
+ // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
+ // and URL fragments. If the browser supports neither (old IE, natch),
+ // falls back to polling.
+ var History = Backbone.History = function() {
+ this.handlers = [];
+ this.checkUrl = _.bind(this.checkUrl, this);
+
+ // Ensure that `History` can be used outside of the browser.
+ if (typeof window !== 'undefined') {
+ this.location = window.location;
+ this.history = window.history;
+ }
+ };
+
+ // Cached regex for stripping a leading hash/slash and trailing space.
+ var routeStripper = /^[#\/]|\s+$/g;
+
+ // Cached regex for stripping leading and trailing slashes.
+ var rootStripper = /^\/+|\/+$/g;
+
+ // Cached regex for stripping urls of hash.
+ var pathStripper = /#.*$/;
+
+ // Has the history handling already been started?
+ History.started = false;
+
+ // Set up all inheritable **Backbone.History** properties and methods.
+ _.extend(History.prototype, Events, {
+
+ // The default interval to poll for hash changes, if necessary, is
+ // twenty times a second.
+ interval: 50,
+
+ // Are we at the app root?
+ atRoot: function() {
+ var path = this.location.pathname.replace(/[^\/]$/, '$&/');
+ return path === this.root && !this.getSearch();
+ },
+
+ // Does the pathname match the root?
+ matchRoot: function() {
+ var path = this.decodeFragment(this.location.pathname);
+ var root = path.slice(0, this.root.length - 1) + '/';
+ return root === this.root;
+ },
+
+ // Unicode characters in `location.pathname` are percent encoded so they're
+ // decoded for comparison. `%25` should not be decoded since it may be part
+ // of an encoded parameter.
+ decodeFragment: function(fragment) {
+ return decodeURI(fragment.replace(/%25/g, '%2525'));
+ },
+
+ // In IE6, the hash fragment and search params are incorrect if the
+ // fragment contains `?`.
+ getSearch: function() {
+ var match = this.location.href.replace(/#.*/, '').match(/\?.+/);
+ return match ? match[0] : '';
+ },
+
+ // Gets the true hash value. Cannot use location.hash directly due to bug
+ // in Firefox where location.hash will always be decoded.
+ getHash: function(window) {
+ var match = (window || this).location.href.match(/#(.*)$/);
+ return match ? match[1] : '';
+ },
+
+ // Get the pathname and search params, without the root.
+ getPath: function() {
+ var path = this.decodeFragment(
+ this.location.pathname + this.getSearch()
+ ).slice(this.root.length - 1);
+ return path.charAt(0) === '/' ? path.slice(1) : path;
+ },
+
+ // Get the cross-browser normalized URL fragment from the path or hash.
+ getFragment: function(fragment) {
+ if (fragment == null) {
+ if (this._usePushState || !this._wantsHashChange) {
+ fragment = this.getPath();
+ } else {
+ fragment = this.getHash();
+ }
+ }
+ return fragment.replace(routeStripper, '');
+ },
+
+ // Start the hash change handling, returning `true` if the current URL matches
+ // an existing route, and `false` otherwise.
+ start: function(options) {
+ if (History.started) throw new Error('Backbone.history has already been started');
+ History.started = true;
+
+ // Figure out the initial configuration. Do we need an iframe?
+ // Is pushState desired ... is it available?
+ this.options = _.extend({root: '/'}, this.options, options);
+ this.root = this.options.root;
+ this._wantsHashChange = this.options.hashChange !== false;
+ this._hasHashChange = 'onhashchange' in window && (document.documentMode === void 0 || document.documentMode > 7);
+ this._useHashChange = this._wantsHashChange && this._hasHashChange;
+ this._wantsPushState = !!this.options.pushState;
+ this._hasPushState = !!(this.history && this.history.pushState);
+ this._usePushState = this._wantsPushState && this._hasPushState;
+ this.fragment = this.getFragment();
+
+ // Normalize root to always include a leading and trailing slash.
+ this.root = ('/' + this.root + '/').replace(rootStripper, '/');
+
+ // Transition from hashChange to pushState or vice versa if both are
+ // requested.
+ if (this._wantsHashChange && this._wantsPushState) {
+
+ // If we've started off with a route from a `pushState`-enabled
+ // browser, but we're currently in a browser that doesn't support it...
+ if (!this._hasPushState && !this.atRoot()) {
+ var root = this.root.slice(0, -1) || '/';
+ this.location.replace(root + '#' + this.getPath());
+ // Return immediately as browser will do redirect to new url
+ return true;
+
+ // Or if we've started out with a hash-based route, but we're currently
+ // in a browser where it could be `pushState`-based instead...
+ } else if (this._hasPushState && this.atRoot()) {
+ this.navigate(this.getHash(), {replace: true});
+ }
+
+ }
+
+ // Proxy an iframe to handle location events if the browser doesn't
+ // support the `hashchange` event, HTML5 history, or the user wants
+ // `hashChange` but not `pushState`.
+ if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) {
+ this.iframe = document.createElement('iframe');
+ this.iframe.src = 'javascript:0';
+ this.iframe.style.display = 'none';
+ this.iframe.tabIndex = -1;
+ var body = document.body;
+ // Using `appendChild` will throw on IE < 9 if the document is not ready.
+ var iWindow = body.insertBefore(this.iframe, body.firstChild).contentWindow;
+ iWindow.document.open();
+ iWindow.document.close();
+ iWindow.location.hash = '#' + this.fragment;
+ }
+
+ // Add a cross-platform `addEventListener` shim for older browsers.
+ var addEventListener = window.addEventListener || function (eventName, listener) {
+ return attachEvent('on' + eventName, listener);
+ };
+
+ // Depending on whether we're using pushState or hashes, and whether
+ // 'onhashchange' is supported, determine how we check the URL state.
+ if (this._usePushState) {
+ addEventListener('popstate', this.checkUrl, false);
+ } else if (this._useHashChange && !this.iframe) {
+ addEventListener('hashchange', this.checkUrl, false);
+ } else if (this._wantsHashChange) {
+ this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
+ }
+
+ if (!this.options.silent) return this.loadUrl();
+ },
+
+ // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
+ // but possibly useful for unit testing Routers.
+ stop: function() {
+ // Add a cross-platform `removeEventListener` shim for older browsers.
+ var removeEventListener = window.removeEventListener || function (eventName, listener) {
+ return detachEvent('on' + eventName, listener);
+ };
+
+ // Remove window listeners.
+ if (this._usePushState) {
+ removeEventListener('popstate', this.checkUrl, false);
+ } else if (this._useHashChange && !this.iframe) {
+ removeEventListener('hashchange', this.checkUrl, false);
+ }
+
+ // Clean up the iframe if necessary.
+ if (this.iframe) {
+ document.body.removeChild(this.iframe);
+ this.iframe = null;
+ }
+
+ // Some environments will throw when clearing an undefined interval.
+ if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
+ History.started = false;
+ },
+
+ // Add a route to be tested when the fragment changes. Routes added later
+ // may override previous routes.
+ route: function(route, callback) {
+ this.handlers.unshift({route: route, callback: callback});
+ },
+
+ // Checks the current URL to see if it has changed, and if it has,
+ // calls `loadUrl`, normalizing across the hidden iframe.
+ checkUrl: function(e) {
+ var current = this.getFragment();
+
+ // If the user pressed the back button, the iframe's hash will have
+ // changed and we should use that for comparison.
+ if (current === this.fragment && this.iframe) {
+ current = this.getHash(this.iframe.contentWindow);
+ }
+
+ if (current === this.fragment) return false;
+ if (this.iframe) this.navigate(current);
+ this.loadUrl();
+ },
+
+ // Attempt to load the current URL fragment. If a route succeeds with a
+ // match, returns `true`. If no defined routes matches the fragment,
+ // returns `false`.
+ loadUrl: function(fragment) {
+ // If the root doesn't match, no routes can match either.
+ if (!this.matchRoot()) return false;
+ fragment = this.fragment = this.getFragment(fragment);
+ return _.some(this.handlers, function(handler) {
+ if (handler.route.test(fragment)) {
+ handler.callback(fragment);
+ return true;
+ }
+ });
+ },
+
+ // Save a fragment into the hash history, or replace the URL state if the
+ // 'replace' option is passed. You are responsible for properly URL-encoding
+ // the fragment in advance.
+ //
+ // The options object can contain `trigger: true` if you wish to have the
+ // route callback be fired (not usually desirable), or `replace: true`, if
+ // you wish to modify the current URL without adding an entry to the history.
+ navigate: function(fragment, options) {
+ if (!History.started) return false;
+ if (!options || options === true) options = {trigger: !!options};
+
+ // Normalize the fragment.
+ fragment = this.getFragment(fragment || '');
+
+ // Don't include a trailing slash on the root.
+ var root = this.root;
+ if (fragment === '' || fragment.charAt(0) === '?') {
+ root = root.slice(0, -1) || '/';
+ }
+ var url = root + fragment;
+
+ // Strip the hash and decode for matching.
+ fragment = this.decodeFragment(fragment.replace(pathStripper, ''));
+
+ if (this.fragment === fragment) return;
+ this.fragment = fragment;
+
+ // If pushState is available, we use it to set the fragment as a real URL.
+ if (this._usePushState) {
+ this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
+
+ // If hash changes haven't been explicitly disabled, update the hash
+ // fragment to store history.
+ } else if (this._wantsHashChange) {
+ this._updateHash(this.location, fragment, options.replace);
+ if (this.iframe && (fragment !== this.getHash(this.iframe.contentWindow))) {
+ var iWindow = this.iframe.contentWindow;
+
+ // Opening and closing the iframe tricks IE7 and earlier to push a
+ // history entry on hash-tag change. When replace is true, we don't
+ // want this.
+ if (!options.replace) {
+ iWindow.document.open();
+ iWindow.document.close();
+ }
+
+ this._updateHash(iWindow.location, fragment, options.replace);
+ }
+
+ // If you've told us that you explicitly don't want fallback hashchange-
+ // based history, then `navigate` becomes a page refresh.
+ } else {
+ return this.location.assign(url);
+ }
+ if (options.trigger) return this.loadUrl(fragment);
+ },
+
+ // Update the hash location, either replacing the current entry, or adding
+ // a new one to the browser history.
+ _updateHash: function(location, fragment, replace) {
+ if (replace) {
+ var href = location.href.replace(/(javascript:|#).*$/, '');
+ location.replace(href + '#' + fragment);
+ } else {
+ // Some browsers require that `hash` contains a leading #.
+ location.hash = '#' + fragment;
+ }
+ }
+
+ });
+
+ // Create the default Backbone.history.
+ Backbone.history = new History;
+
+ // Helpers
+ // -------
+
+ // Helper function to correctly set up the prototype chain for subclasses.
+ // Similar to `goog.inherits`, but uses a hash of prototype properties and
+ // class properties to be extended.
+ var extend = function(protoProps, staticProps) {
+ var parent = this;
+ var child;
+
+ // The constructor function for the new subclass is either defined by you
+ // (the "constructor" property in your `extend` definition), or defaulted
+ // by us to simply call the parent constructor.
+ if (protoProps && _.has(protoProps, 'constructor')) {
+ child = protoProps.constructor;
+ } else {
+ child = function(){ return parent.apply(this, arguments); };
+ }
+
+ // Add static properties to the constructor function, if supplied.
+ _.extend(child, parent, staticProps);
+
+ // Set the prototype chain to inherit from `parent`, without calling
+ // `parent` constructor function.
+ var Surrogate = function(){ this.constructor = child; };
+ Surrogate.prototype = parent.prototype;
+ child.prototype = new Surrogate;
+
+ // Add prototype properties (instance properties) to the subclass,
+ // if supplied.
+ if (protoProps) _.extend(child.prototype, protoProps);
+
+ // Set a convenience property in case the parent's prototype is needed
+ // later.
+ child.__super__ = parent.prototype;
+
+ return child;
+ };
+
+ // Set up inheritance for the model, collection, router, view and history.
+ Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
+
+ // Throw an error when a URL is needed, and none is supplied.
+ var urlError = function() {
+ throw new Error('A "url" property or function must be specified');
+ };
+
+ // Wrap an optional error callback with a fallback error event.
+ var wrapError = function(model, options) {
+ var error = options.error;
+ options.error = function(resp) {
+ if (error) error.call(options.context, model, resp, options);
+ model.trigger('error', model, resp, options);
+ };
+ };
+
+ return Backbone;
+
+}));
diff --git a/js/vendor/backbone/bower.json b/js/vendor/backbone/bower.json
new file mode 100644
index 000000000..9cbf57ba7
--- /dev/null
+++ b/js/vendor/backbone/bower.json
@@ -0,0 +1,8 @@
+{
+ "name" : "backbone",
+ "main" : "backbone.js",
+ "dependencies" : {
+ "underscore" : ">=1.7.0"
+ },
+ "ignore" : ["docs", "examples", "test", "*.yml", "*.html", "*.ico", "*.md", "CNAME", ".*", "karma.*", "component.json", "package.json"]
+}
diff --git a/js/vendor/underscore/.bower.json b/js/vendor/underscore/.bower.json
new file mode 100644
index 000000000..0e30786ad
--- /dev/null
+++ b/js/vendor/underscore/.bower.json
@@ -0,0 +1,35 @@
+{
+ "name": "underscore",
+ "version": "1.8.3",
+ "main": "underscore.js",
+ "keywords": [
+ "util",
+ "functional",
+ "server",
+ "client",
+ "browser"
+ ],
+ "ignore": [
+ "docs",
+ "test",
+ "*.yml",
+ "CNAME",
+ "index.html",
+ "favicon.ico",
+ "CONTRIBUTING.md",
+ ".*",
+ "component.json",
+ "package.json",
+ "karma.*"
+ ],
+ "homepage": "https://github.com/jashkenas/underscore",
+ "_release": "1.8.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "1.8.3",
+ "commit": "e4743ab712b8ab42ad4ccb48b155034d02394e4d"
+ },
+ "_source": "https://github.com/jashkenas/underscore.git",
+ "_target": ">=1.8.3",
+ "_originalSource": "underscore"
+} \ No newline at end of file
diff --git a/js/vendor/underscore/LICENSE b/js/vendor/underscore/LICENSE
new file mode 100644
index 000000000..ad0e71bc4
--- /dev/null
+++ b/js/vendor/underscore/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative
+Reporters & Editors
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/js/vendor/underscore/README.md b/js/vendor/underscore/README.md
new file mode 100644
index 000000000..c2ba2590c
--- /dev/null
+++ b/js/vendor/underscore/README.md
@@ -0,0 +1,22 @@
+ __
+ /\ \ __
+ __ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____
+ /\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\
+ \ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\
+ \ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/
+ \/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/
+ \ \____/
+ \/___/
+
+Underscore.js is a utility-belt library for JavaScript that provides
+support for the usual functional suspects (each, map, reduce, filter...)
+without extending any core JavaScript objects.
+
+For Docs, License, Tests, and pre-packed downloads, see:
+http://underscorejs.org
+
+Underscore is an open-sourced component of DocumentCloud:
+https://github.com/documentcloud
+
+Many thanks to our contributors:
+https://github.com/jashkenas/underscore/contributors
diff --git a/js/vendor/underscore/bower.json b/js/vendor/underscore/bower.json
new file mode 100644
index 000000000..c7b885334
--- /dev/null
+++ b/js/vendor/underscore/bower.json
@@ -0,0 +1,7 @@
+{
+ "name": "underscore",
+ "version": "1.8.3",
+ "main": "underscore.js",
+ "keywords": ["util", "functional", "server", "client", "browser"],
+ "ignore" : ["docs", "test", "*.yml", "CNAME", "index.html", "favicon.ico", "CONTRIBUTING.md", ".*", "component.json", "package.json", "karma.*"]
+}
diff --git a/js/vendor/underscore/underscore-min.js b/js/vendor/underscore/underscore-min.js
new file mode 100644
index 000000000..f01025b7b
--- /dev/null
+++ b/js/vendor/underscore/underscore-min.js
@@ -0,0 +1,6 @@
+// Underscore.js 1.8.3
+// http://underscorejs.org
+// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Underscore may be freely distributed under the MIT license.
+(function(){function n(n){function t(t,r,e,u,i,o){for(;i>=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=b(e,i,4);var o=!k(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=x(r,e);for(var u=O(t),i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t,r){return function(e,u,i){var o=0,a=O(e);if("number"==typeof i)n>0?o=i>=0?i:Math.max(i+a,o):a=i>=0?Math.min(i+1,a):i+a+1;else if(r&&i&&a)return i=r(e,u),e[i]===u?i:-1;if(u!==u)return i=t(l.call(e,o,a),m.isNaN),i>=0?i+o:-1;for(i=n>0?o:a-1;i>=0&&a>i;i+=n)if(e[i]===u)return i;return-1}}function e(n,t){var r=I.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||a,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=I[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var u=this,i=u._,o=Array.prototype,a=Object.prototype,c=Function.prototype,f=o.push,l=o.slice,s=a.toString,p=a.hasOwnProperty,h=Array.isArray,v=Object.keys,g=c.bind,y=Object.create,d=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):u._=m,m.VERSION="1.8.3";var b=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},x=function(n,t,r){return null==n?m.identity:m.isFunction(n)?b(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return x(n,t,1/0)};var _=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var f=o[c];t&&r[f]!==void 0||(r[f]=i[f])}return r}},j=function(n){if(!m.isObject(n))return{};if(y)return y(n);d.prototype=n;var t=new d;return d.prototype=null,t},w=function(n){return function(t){return null==t?void 0:t[n]}},A=Math.pow(2,53)-1,O=w("length"),k=function(n){var t=O(n);return"number"==typeof t&&t>=0&&A>=t};m.each=m.forEach=function(n,t,r){t=b(t,r);var e,u;if(k(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=k(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=x(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(x(t)),r)},m.every=m.all=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r,e){return k(n)||(n=m.values(n)),("number"!=typeof r||e)&&(r=0),m.indexOf(n,t,r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=k(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(k(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=x(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=x(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=F(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=F(function(n,t,r){n[r]=t}),m.countBy=F(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):k(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:k(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=x(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var S=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=O(n);a>o;o++){var c=n[o];if(k(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=S(c,t,r));var f=0,l=c.length;for(u.length+=l;l>f;)u[i++]=c[f++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return S(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=x(r,e));for(var u=[],i=[],o=0,a=O(n);a>o;o++){var c=n[o],f=r?r(c,o,n):c;t?(o&&i===f||u.push(c),i=f):r?m.contains(i,f)||(i.push(f),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(S(arguments,!0,!0))},m.intersection=function(n){for(var t=[],r=arguments.length,e=0,u=O(n);u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=S(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,O).length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=O(n);u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=x(r,e,1);for(var u=r(t),i=0,o=O(n);o>i;){var a=Math.floor((i+o)/2);r(n[a])<u?i=a+1:o=a}return i},m.indexOf=r(1,m.findIndex,m.sortedIndex),m.lastIndexOf=r(-1,m.findLastIndex),m.range=function(n,t,r){null==t&&(t=n||0,n=0),r=r||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=Array(e),i=0;e>i;i++,n+=r)u[i]=n;return u};var E=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=j(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(g&&n.bind===g)return g.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return E(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e<arguments.length;)i.push(arguments[e++]);return E(n,r,this,this,i)};return r},m.bindAll=function(n){var t,r,e=arguments.length;if(1>=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var f=m.now();a||r.leading!==!1||(a=f);var l=t-(f-a);return e=this,u=arguments,0>=l||l>t?(o&&(clearTimeout(o),o=null),a=f,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,l)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var f=m.now()-o;t>f&&f>=0?e=setTimeout(c,t-f):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var f=r&&!e;return e||(e=setTimeout(c,t)),f&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var M=!{toString:null}.propertyIsEnumerable("toString"),I=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(v)return v(n);var t=[];for(var r in n)m.has(n,r)&&t.push(r);return M&&e(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var r in n)t.push(r);return M&&e(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=_(m.allKeys),m.extendOwn=m.assign=_(m.keys),m.findKey=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=b(t,r)):(u=S(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var f=u[a],l=o[f];e(l,f,o)&&(i[f]=l)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(S(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=_(m.allKeys,!0),m.create=function(n,t){var r=j(n);return t&&m.extendOwn(r,t),r},m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=s.call(n);if(u!==s.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!N(n[c],t[c],r,e))return!1}else{var f,l=m.keys(n);if(c=l.length,m.keys(t).length!==c)return!1;for(;c--;)if(f=l[c],!m.has(t,f)||!N(n[f],t[f],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return N(n,t)},m.isEmpty=function(n){return null==n?!0:k(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=h||function(n){return"[object Array]"===s.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return s.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===s.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&p.call(n,t)},m.noConflict=function(){return u._=i,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=w,m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=b(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},T=m.invert(B),R=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=R(B),m.unescape=R(T),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var q=0;m.uniqueId=function(n){var t=++q+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var K=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\u2028|\u2029/g,L=function(n){return"\\"+z[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||K).source,(t.interpolate||K).source,(t.evaluate||K).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(D,L),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},f=t.variable||"obj";return c.source="function("+f+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var P=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return f.apply(n,arguments),P(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=o[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],P(this,r)}}),m.each(["concat","join","slice"],function(n){var t=o[n];m.prototype[n]=function(){return P(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this);
+//# sourceMappingURL=underscore-min.map \ No newline at end of file
diff --git a/js/vendor/underscore/underscore-min.map b/js/vendor/underscore/underscore-min.map
new file mode 100644
index 000000000..cf356bf9a
--- /dev/null
+++ b/js/vendor/underscore/underscore-min.map
@@ -0,0 +1 @@
+{"version":3,"file":"underscore-min.js","sources":["underscore.js"],"names":["createReduce","dir","iterator","obj","iteratee","memo","keys","index","length","currentKey","context","optimizeCb","isArrayLike","_","arguments","createPredicateIndexFinder","array","predicate","cb","getLength","createIndexFinder","predicateFind","sortedIndex","item","idx","i","Math","max","min","slice","call","isNaN","collectNonEnumProps","nonEnumIdx","nonEnumerableProps","constructor","proto","isFunction","prototype","ObjProto","prop","has","contains","push","root","this","previousUnderscore","ArrayProto","Array","Object","FuncProto","Function","toString","hasOwnProperty","nativeIsArray","isArray","nativeKeys","nativeBind","bind","nativeCreate","create","Ctor","_wrapped","exports","module","VERSION","func","argCount","value","other","collection","accumulator","apply","identity","isObject","matcher","property","Infinity","createAssigner","keysFunc","undefinedOnly","source","l","key","baseCreate","result","MAX_ARRAY_INDEX","pow","each","forEach","map","collect","results","reduce","foldl","inject","reduceRight","foldr","find","detect","findIndex","findKey","filter","select","list","reject","negate","every","all","some","any","includes","include","fromIndex","guard","values","indexOf","invoke","method","args","isFunc","pluck","where","attrs","findWhere","computed","lastComputed","shuffle","rand","set","shuffled","random","sample","n","sortBy","criteria","sort","left","right","a","b","group","behavior","groupBy","indexBy","countBy","toArray","size","partition","pass","fail","first","head","take","initial","last","rest","tail","drop","compact","flatten","input","shallow","strict","startIndex","output","isArguments","j","len","without","difference","uniq","unique","isSorted","isBoolean","seen","union","intersection","argsLength","zip","unzip","object","findLastIndex","low","high","mid","floor","lastIndexOf","range","start","stop","step","ceil","executeBound","sourceFunc","boundFunc","callingContext","self","TypeError","bound","concat","partial","boundArgs","position","bindAll","Error","memoize","hasher","cache","address","delay","wait","setTimeout","defer","throttle","options","timeout","previous","later","leading","now","remaining","clearTimeout","trailing","debounce","immediate","timestamp","callNow","wrap","wrapper","compose","after","times","before","once","hasEnumBug","propertyIsEnumerable","allKeys","mapObject","pairs","invert","functions","methods","names","extend","extendOwn","assign","pick","oiteratee","omit","String","defaults","props","clone","tap","interceptor","isMatch","eq","aStack","bStack","className","areArrays","aCtor","bCtor","pop","isEqual","isEmpty","isString","isElement","nodeType","type","name","Int8Array","isFinite","parseFloat","isNumber","isNull","isUndefined","noConflict","constant","noop","propertyOf","matches","accum","Date","getTime","escapeMap","&","<",">","\"","'","`","unescapeMap","createEscaper","escaper","match","join","testRegexp","RegExp","replaceRegexp","string","test","replace","escape","unescape","fallback","idCounter","uniqueId","prefix","id","templateSettings","evaluate","interpolate","noMatch","escapes","\\","\r","\n","
","
","escapeChar","template","text","settings","oldSettings","offset","variable","render","e","data","argument","chain","instance","_chain","mixin","valueOf","toJSON","define","amd"],"mappings":"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"} \ No newline at end of file
diff --git a/js/vendor/underscore/underscore.js b/js/vendor/underscore/underscore.js
new file mode 100644
index 000000000..b29332f94
--- /dev/null
+++ b/js/vendor/underscore/underscore.js
@@ -0,0 +1,1548 @@
+// Underscore.js 1.8.3
+// http://underscorejs.org
+// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Underscore may be freely distributed under the MIT license.
+
+(function() {
+
+ // Baseline setup
+ // --------------
+
+ // Establish the root object, `window` in the browser, or `exports` on the server.
+ var root = this;
+
+ // Save the previous value of the `_` variable.
+ var previousUnderscore = root._;
+
+ // Save bytes in the minified (but not gzipped) version:
+ var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
+
+ // Create quick reference variables for speed access to core prototypes.
+ var
+ push = ArrayProto.push,
+ slice = ArrayProto.slice,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
+
+ // All **ECMAScript 5** native function implementations that we hope to use
+ // are declared here.
+ var
+ nativeIsArray = Array.isArray,
+ nativeKeys = Object.keys,
+ nativeBind = FuncProto.bind,
+ nativeCreate = Object.create;
+
+ // Naked function reference for surrogate-prototype-swapping.
+ var Ctor = function(){};
+
+ // Create a safe reference to the Underscore object for use below.
+ var _ = function(obj) {
+ if (obj instanceof _) return obj;
+ if (!(this instanceof _)) return new _(obj);
+ this._wrapped = obj;
+ };
+
+ // Export the Underscore object for **Node.js**, with
+ // backwards-compatibility for the old `require()` API. If we're in
+ // the browser, add `_` as a global object.
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = _;
+ }
+ exports._ = _;
+ } else {
+ root._ = _;
+ }
+
+ // Current version.
+ _.VERSION = '1.8.3';
+
+ // Internal function that returns an efficient (for current engines) version
+ // of the passed-in callback, to be repeatedly applied in other Underscore
+ // functions.
+ var optimizeCb = function(func, context, argCount) {
+ if (context === void 0) return func;
+ switch (argCount == null ? 3 : argCount) {
+ case 1: return function(value) {
+ return func.call(context, value);
+ };
+ case 2: return function(value, other) {
+ return func.call(context, value, other);
+ };
+ case 3: return function(value, index, collection) {
+ return func.call(context, value, index, collection);
+ };
+ case 4: return function(accumulator, value, index, collection) {
+ return func.call(context, accumulator, value, index, collection);
+ };
+ }
+ return function() {
+ return func.apply(context, arguments);
+ };
+ };
+
+ // A mostly-internal function to generate callbacks that can be applied
+ // to each element in a collection, returning the desired result — either
+ // identity, an arbitrary callback, a property matcher, or a property accessor.
+ var cb = function(value, context, argCount) {
+ if (value == null) return _.identity;
+ if (_.isFunction(value)) return optimizeCb(value, context, argCount);
+ if (_.isObject(value)) return _.matcher(value);
+ return _.property(value);
+ };
+ _.iteratee = function(value, context) {
+ return cb(value, context, Infinity);
+ };
+
+ // An internal function for creating assigner functions.
+ var createAssigner = function(keysFunc, undefinedOnly) {
+ return function(obj) {
+ var length = arguments.length;
+ if (length < 2 || obj == null) return obj;
+ for (var index = 1; index < length; index++) {
+ var source = arguments[index],
+ keys = keysFunc(source),
+ l = keys.length;
+ for (var i = 0; i < l; i++) {
+ var key = keys[i];
+ if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
+ }
+ }
+ return obj;
+ };
+ };
+
+ // An internal function for creating a new object that inherits from another.
+ var baseCreate = function(prototype) {
+ if (!_.isObject(prototype)) return {};
+ if (nativeCreate) return nativeCreate(prototype);
+ Ctor.prototype = prototype;
+ var result = new Ctor;
+ Ctor.prototype = null;
+ return result;
+ };
+
+ var property = function(key) {
+ return function(obj) {
+ return obj == null ? void 0 : obj[key];
+ };
+ };
+
+ // Helper for collection methods to determine whether a collection
+ // should be iterated as an array or as an object
+ // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
+ // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
+ var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
+ var getLength = property('length');
+ var isArrayLike = function(collection) {
+ var length = getLength(collection);
+ return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
+ };
+
+ // Collection Functions
+ // --------------------
+
+ // The cornerstone, an `each` implementation, aka `forEach`.
+ // Handles raw objects in addition to array-likes. Treats all
+ // sparse array-likes as if they were dense.
+ _.each = _.forEach = function(obj, iteratee, context) {
+ iteratee = optimizeCb(iteratee, context);
+ var i, length;
+ if (isArrayLike(obj)) {
+ for (i = 0, length = obj.length; i < length; i++) {
+ iteratee(obj[i], i, obj);
+ }
+ } else {
+ var keys = _.keys(obj);
+ for (i = 0, length = keys.length; i < length; i++) {
+ iteratee(obj[keys[i]], keys[i], obj);
+ }
+ }
+ return obj;
+ };
+
+ // Return the results of applying the iteratee to each element.
+ _.map = _.collect = function(obj, iteratee, context) {
+ iteratee = cb(iteratee, context);
+ var keys = !isArrayLike(obj) && _.keys(obj),
+ length = (keys || obj).length,
+ results = Array(length);
+ for (var index = 0; index < length; index++) {
+ var currentKey = keys ? keys[index] : index;
+ results[index] = iteratee(obj[currentKey], currentKey, obj);
+ }
+ return results;
+ };
+
+ // Create a reducing function iterating left or right.
+ function createReduce(dir) {
+ // Optimized iterator function as using arguments.length
+ // in the main function will deoptimize the, see #1991.
+ function iterator(obj, iteratee, memo, keys, index, length) {
+ for (; index >= 0 && index < length; index += dir) {
+ var currentKey = keys ? keys[index] : index;
+ memo = iteratee(memo, obj[currentKey], currentKey, obj);
+ }
+ return memo;
+ }
+
+ return function(obj, iteratee, memo, context) {
+ iteratee = optimizeCb(iteratee, context, 4);
+ var keys = !isArrayLike(obj) && _.keys(obj),
+ length = (keys || obj).length,
+ index = dir > 0 ? 0 : length - 1;
+ // Determine the initial value if none is provided.
+ if (arguments.length < 3) {
+ memo = obj[keys ? keys[index] : index];
+ index += dir;
+ }
+ return iterator(obj, iteratee, memo, keys, index, length);
+ };
+ }
+
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
+ // or `foldl`.
+ _.reduce = _.foldl = _.inject = createReduce(1);
+
+ // The right-associative version of reduce, also known as `foldr`.
+ _.reduceRight = _.foldr = createReduce(-1);
+
+ // Return the first value which passes a truth test. Aliased as `detect`.
+ _.find = _.detect = function(obj, predicate, context) {
+ var key;
+ if (isArrayLike(obj)) {
+ key = _.findIndex(obj, predicate, context);
+ } else {
+ key = _.findKey(obj, predicate, context);
+ }
+ if (key !== void 0 && key !== -1) return obj[key];
+ };
+
+ // Return all the elements that pass a truth test.
+ // Aliased as `select`.
+ _.filter = _.select = function(obj, predicate, context) {
+ var results = [];
+ predicate = cb(predicate, context);
+ _.each(obj, function(value, index, list) {
+ if (predicate(value, index, list)) results.push(value);
+ });
+ return results;
+ };
+
+ // Return all the elements for which a truth test fails.
+ _.reject = function(obj, predicate, context) {
+ return _.filter(obj, _.negate(cb(predicate)), context);
+ };
+
+ // Determine whether all of the elements match a truth test.
+ // Aliased as `all`.
+ _.every = _.all = function(obj, predicate, context) {
+ predicate = cb(predicate, context);
+ var keys = !isArrayLike(obj) && _.keys(obj),
+ length = (keys || obj).length;
+ for (var index = 0; index < length; index++) {
+ var currentKey = keys ? keys[index] : index;
+ if (!predicate(obj[currentKey], currentKey, obj)) return false;
+ }
+ return true;
+ };
+
+ // Determine if at least one element in the object matches a truth test.
+ // Aliased as `any`.
+ _.some = _.any = function(obj, predicate, context) {
+ predicate = cb(predicate, context);
+ var keys = !isArrayLike(obj) && _.keys(obj),
+ length = (keys || obj).length;
+ for (var index = 0; index < length; index++) {
+ var currentKey = keys ? keys[index] : index;
+ if (predicate(obj[currentKey], currentKey, obj)) return true;
+ }
+ return false;
+ };
+
+ // Determine if the array or object contains a given item (using `===`).
+ // Aliased as `includes` and `include`.
+ _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
+ if (!isArrayLike(obj)) obj = _.values(obj);
+ if (typeof fromIndex != 'number' || guard) fromIndex = 0;
+ return _.indexOf(obj, item, fromIndex) >= 0;
+ };
+
+ // Invoke a method (with arguments) on every item in a collection.
+ _.invoke = function(obj, method) {
+ var args = slice.call(arguments, 2);
+ var isFunc = _.isFunction(method);
+ return _.map(obj, function(value) {
+ var func = isFunc ? method : value[method];
+ return func == null ? func : func.apply(value, args);
+ });
+ };
+
+ // Convenience version of a common use case of `map`: fetching a property.
+ _.pluck = function(obj, key) {
+ return _.map(obj, _.property(key));
+ };
+
+ // Convenience version of a common use case of `filter`: selecting only objects
+ // containing specific `key:value` pairs.
+ _.where = function(obj, attrs) {
+ return _.filter(obj, _.matcher(attrs));
+ };
+
+ // Convenience version of a common use case of `find`: getting the first object
+ // containing specific `key:value` pairs.
+ _.findWhere = function(obj, attrs) {
+ return _.find(obj, _.matcher(attrs));
+ };
+
+ // Return the maximum element (or element-based computation).
+ _.max = function(obj, iteratee, context) {
+ var result = -Infinity, lastComputed = -Infinity,
+ value, computed;
+ if (iteratee == null && obj != null) {
+ obj = isArrayLike(obj) ? obj : _.values(obj);
+ for (var i = 0, length = obj.length; i < length; i++) {
+ value = obj[i];
+ if (value > result) {
+ result = value;
+ }
+ }
+ } else {
+ iteratee = cb(iteratee, context);
+ _.each(obj, function(value, index, list) {
+ computed = iteratee(value, index, list);
+ if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
+ result = value;
+ lastComputed = computed;
+ }
+ });
+ }
+ return result;
+ };
+
+ // Return the minimum element (or element-based computation).
+ _.min = function(obj, iteratee, context) {
+ var result = Infinity, lastComputed = Infinity,
+ value, computed;
+ if (iteratee == null && obj != null) {
+ obj = isArrayLike(obj) ? obj : _.values(obj);
+ for (var i = 0, length = obj.length; i < length; i++) {
+ value = obj[i];
+ if (value < result) {
+ result = value;
+ }
+ }
+ } else {
+ iteratee = cb(iteratee, context);
+ _.each(obj, function(value, index, list) {
+ computed = iteratee(value, index, list);
+ if (computed < lastComputed || computed === Infinity && result === Infinity) {
+ result = value;
+ lastComputed = computed;
+ }
+ });
+ }
+ return result;
+ };
+
+ // Shuffle a collection, using the modern version of the
+ // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
+ _.shuffle = function(obj) {
+ var set = isArrayLike(obj) ? obj : _.values(obj);
+ var length = set.length;
+ var shuffled = Array(length);
+ for (var index = 0, rand; index < length; index++) {
+ rand = _.random(0, index);
+ if (rand !== index) shuffled[index] = shuffled[rand];
+ shuffled[rand] = set[index];
+ }
+ return shuffled;
+ };
+
+ // Sample **n** random values from a collection.
+ // If **n** is not specified, returns a single random element.
+ // The internal `guard` argument allows it to work with `map`.
+ _.sample = function(obj, n, guard) {
+ if (n == null || guard) {
+ if (!isArrayLike(obj)) obj = _.values(obj);
+ return obj[_.random(obj.length - 1)];
+ }
+ return _.shuffle(obj).slice(0, Math.max(0, n));
+ };
+
+ // Sort the object's values by a criterion produced by an iteratee.
+ _.sortBy = function(obj, iteratee, context) {
+ iteratee = cb(iteratee, context);
+ return _.pluck(_.map(obj, function(value, index, list) {
+ return {
+ value: value,
+ index: index,
+ criteria: iteratee(value, index, list)
+ };
+ }).sort(function(left, right) {
+ var a = left.criteria;
+ var b = right.criteria;
+ if (a !== b) {
+ if (a > b || a === void 0) return 1;
+ if (a < b || b === void 0) return -1;
+ }
+ return left.index - right.index;
+ }), 'value');
+ };
+
+ // An internal function used for aggregate "group by" operations.
+ var group = function(behavior) {
+ return function(obj, iteratee, context) {
+ var result = {};
+ iteratee = cb(iteratee, context);
+ _.each(obj, function(value, index) {
+ var key = iteratee(value, index, obj);
+ behavior(result, value, key);
+ });
+ return result;
+ };
+ };
+
+ // Groups the object's values by a criterion. Pass either a string attribute
+ // to group by, or a function that returns the criterion.
+ _.groupBy = group(function(result, value, key) {
+ if (_.has(result, key)) result[key].push(value); else result[key] = [value];
+ });
+
+ // Indexes the object's values by a criterion, similar to `groupBy`, but for
+ // when you know that your index values will be unique.
+ _.indexBy = group(function(result, value, key) {
+ result[key] = value;
+ });
+
+ // Counts instances of an object that group by a certain criterion. Pass
+ // either a string attribute to count by, or a function that returns the
+ // criterion.
+ _.countBy = group(function(result, value, key) {
+ if (_.has(result, key)) result[key]++; else result[key] = 1;
+ });
+
+ // Safely create a real, live array from anything iterable.
+ _.toArray = function(obj) {
+ if (!obj) return [];
+ if (_.isArray(obj)) return slice.call(obj);
+ if (isArrayLike(obj)) return _.map(obj, _.identity);
+ return _.values(obj);
+ };
+
+ // Return the number of elements in an object.
+ _.size = function(obj) {
+ if (obj == null) return 0;
+ return isArrayLike(obj) ? obj.length : _.keys(obj).length;
+ };
+
+ // Split a collection into two arrays: one whose elements all satisfy the given
+ // predicate, and one whose elements all do not satisfy the predicate.
+ _.partition = function(obj, predicate, context) {
+ predicate = cb(predicate, context);
+ var pass = [], fail = [];
+ _.each(obj, function(value, key, obj) {
+ (predicate(value, key, obj) ? pass : fail).push(value);
+ });
+ return [pass, fail];
+ };
+
+ // Array Functions
+ // ---------------
+
+ // Get the first element of an array. Passing **n** will return the first N
+ // values in the array. Aliased as `head` and `take`. The **guard** check
+ // allows it to work with `_.map`.
+ _.first = _.head = _.take = function(array, n, guard) {
+ if (array == null) return void 0;
+ if (n == null || guard) return array[0];
+ return _.initial(array, array.length - n);
+ };
+
+ // Returns everything but the last entry of the array. Especially useful on
+ // the arguments object. Passing **n** will return all the values in
+ // the array, excluding the last N.
+ _.initial = function(array, n, guard) {
+ return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
+ };
+
+ // Get the last element of an array. Passing **n** will return the last N
+ // values in the array.
+ _.last = function(array, n, guard) {
+ if (array == null) return void 0;
+ if (n == null || guard) return array[array.length - 1];
+ return _.rest(array, Math.max(0, array.length - n));
+ };
+
+ // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
+ // Especially useful on the arguments object. Passing an **n** will return
+ // the rest N values in the array.
+ _.rest = _.tail = _.drop = function(array, n, guard) {
+ return slice.call(array, n == null || guard ? 1 : n);
+ };
+
+ // Trim out all falsy values from an array.
+ _.compact = function(array) {
+ return _.filter(array, _.identity);
+ };
+
+ // Internal implementation of a recursive `flatten` function.
+ var flatten = function(input, shallow, strict, startIndex) {
+ var output = [], idx = 0;
+ for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
+ var value = input[i];
+ if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
+ //flatten current level of array or arguments object
+ if (!shallow) value = flatten(value, shallow, strict);
+ var j = 0, len = value.length;
+ output.length += len;
+ while (j < len) {
+ output[idx++] = value[j++];
+ }
+ } else if (!strict) {
+ output[idx++] = value;
+ }
+ }
+ return output;
+ };
+
+ // Flatten out an array, either recursively (by default), or just one level.
+ _.flatten = function(array, shallow) {
+ return flatten(array, shallow, false);
+ };
+
+ // Return a version of the array that does not contain the specified value(s).
+ _.without = function(array) {
+ return _.difference(array, slice.call(arguments, 1));
+ };
+
+ // Produce a duplicate-free version of the array. If the array has already
+ // been sorted, you have the option of using a faster algorithm.
+ // Aliased as `unique`.
+ _.uniq = _.unique = function(array, isSorted, iteratee, context) {
+ if (!_.isBoolean(isSorted)) {
+ context = iteratee;
+ iteratee = isSorted;
+ isSorted = false;
+ }
+ if (iteratee != null) iteratee = cb(iteratee, context);
+ var result = [];
+ var seen = [];
+ for (var i = 0, length = getLength(array); i < length; i++) {
+ var value = array[i],
+ computed = iteratee ? iteratee(value, i, array) : value;
+ if (isSorted) {
+ if (!i || seen !== computed) result.push(value);
+ seen = computed;
+ } else if (iteratee) {
+ if (!_.contains(seen, computed)) {
+ seen.push(computed);
+ result.push(value);
+ }
+ } else if (!_.contains(result, value)) {
+ result.push(value);
+ }
+ }
+ return result;
+ };
+
+ // Produce an array that contains the union: each distinct element from all of
+ // the passed-in arrays.
+ _.union = function() {
+ return _.uniq(flatten(arguments, true, true));
+ };
+
+ // Produce an array that contains every item shared between all the
+ // passed-in arrays.
+ _.intersection = function(array) {
+ var result = [];
+ var argsLength = arguments.length;
+ for (var i = 0, length = getLength(array); i < length; i++) {
+ var item = array[i];
+ if (_.contains(result, item)) continue;
+ for (var j = 1; j < argsLength; j++) {
+ if (!_.contains(arguments[j], item)) break;
+ }
+ if (j === argsLength) result.push(item);
+ }
+ return result;
+ };
+
+ // Take the difference between one array and a number of other arrays.
+ // Only the elements present in just the first array will remain.
+ _.difference = function(array) {
+ var rest = flatten(arguments, true, true, 1);
+ return _.filter(array, function(value){
+ return !_.contains(rest, value);
+ });
+ };
+
+ // Zip together multiple lists into a single array -- elements that share
+ // an index go together.
+ _.zip = function() {
+ return _.unzip(arguments);
+ };
+
+ // Complement of _.zip. Unzip accepts an array of arrays and groups
+ // each array's elements on shared indices
+ _.unzip = function(array) {
+ var length = array && _.max(array, getLength).length || 0;
+ var result = Array(length);
+
+ for (var index = 0; index < length; index++) {
+ result[index] = _.pluck(array, index);
+ }
+ return result;
+ };
+
+ // Converts lists into objects. Pass either a single array of `[key, value]`
+ // pairs, or two parallel arrays of the same length -- one of keys, and one of
+ // the corresponding values.
+ _.object = function(list, values) {
+ var result = {};
+ for (var i = 0, length = getLength(list); i < length; i++) {
+ if (values) {
+ result[list[i]] = values[i];
+ } else {
+ result[list[i][0]] = list[i][1];
+ }
+ }
+ return result;
+ };
+
+ // Generator function to create the findIndex and findLastIndex functions
+ function createPredicateIndexFinder(dir) {
+ return function(array, predicate, context) {
+ predicate = cb(predicate, context);
+ var length = getLength(array);
+ var index = dir > 0 ? 0 : length - 1;
+ for (; index >= 0 && index < length; index += dir) {
+ if (predicate(array[index], index, array)) return index;
+ }
+ return -1;
+ };
+ }
+
+ // Returns the first index on an array-like that passes a predicate test
+ _.findIndex = createPredicateIndexFinder(1);
+ _.findLastIndex = createPredicateIndexFinder(-1);
+
+ // Use a comparator function to figure out the smallest index at which
+ // an object should be inserted so as to maintain order. Uses binary search.
+ _.sortedIndex = function(array, obj, iteratee, context) {
+ iteratee = cb(iteratee, context, 1);
+ var value = iteratee(obj);
+ var low = 0, high = getLength(array);
+ while (low < high) {
+ var mid = Math.floor((low + high) / 2);
+ if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
+ }
+ return low;
+ };
+
+ // Generator function to create the indexOf and lastIndexOf functions
+ function createIndexFinder(dir, predicateFind, sortedIndex) {
+ return function(array, item, idx) {
+ var i = 0, length = getLength(array);
+ if (typeof idx == 'number') {
+ if (dir > 0) {
+ i = idx >= 0 ? idx : Math.max(idx + length, i);
+ } else {
+ length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
+ }
+ } else if (sortedIndex && idx && length) {
+ idx = sortedIndex(array, item);
+ return array[idx] === item ? idx : -1;
+ }
+ if (item !== item) {
+ idx = predicateFind(slice.call(array, i, length), _.isNaN);
+ return idx >= 0 ? idx + i : -1;
+ }
+ for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
+ if (array[idx] === item) return idx;
+ }
+ return -1;
+ };
+ }
+
+ // Return the position of the first occurrence of an item in an array,
+ // or -1 if the item is not included in the array.
+ // If the array is large and already in sort order, pass `true`
+ // for **isSorted** to use binary search.
+ _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
+ _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
+
+ // Generate an integer Array containing an arithmetic progression. A port of
+ // the native Python `range()` function. See
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
+ _.range = function(start, stop, step) {
+ if (stop == null) {
+ stop = start || 0;
+ start = 0;
+ }
+ step = step || 1;
+
+ var length = Math.max(Math.ceil((stop - start) / step), 0);
+ var range = Array(length);
+
+ for (var idx = 0; idx < length; idx++, start += step) {
+ range[idx] = start;
+ }
+
+ return range;
+ };
+
+ // Function (ahem) Functions
+ // ------------------
+
+ // Determines whether to execute a function as a constructor
+ // or a normal function with the provided arguments
+ var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
+ if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
+ var self = baseCreate(sourceFunc.prototype);
+ var result = sourceFunc.apply(self, args);
+ if (_.isObject(result)) return result;
+ return self;
+ };
+
+ // Create a function bound to a given object (assigning `this`, and arguments,
+ // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
+ // available.
+ _.bind = function(func, context) {
+ if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+ if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
+ var args = slice.call(arguments, 2);
+ var bound = function() {
+ return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
+ };
+ return bound;
+ };
+
+ // Partially apply a function by creating a version that has had some of its
+ // arguments pre-filled, without changing its dynamic `this` context. _ acts
+ // as a placeholder, allowing any combination of arguments to be pre-filled.
+ _.partial = function(func) {
+ var boundArgs = slice.call(arguments, 1);
+ var bound = function() {
+ var position = 0, length = boundArgs.length;
+ var args = Array(length);
+ for (var i = 0; i < length; i++) {
+ args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
+ }
+ while (position < arguments.length) args.push(arguments[position++]);
+ return executeBound(func, bound, this, this, args);
+ };
+ return bound;
+ };
+
+ // Bind a number of an object's methods to that object. Remaining arguments
+ // are the method names to be bound. Useful for ensuring that all callbacks
+ // defined on an object belong to it.
+ _.bindAll = function(obj) {
+ var i, length = arguments.length, key;
+ if (length <= 1) throw new Error('bindAll must be passed function names');
+ for (i = 1; i < length; i++) {
+ key = arguments[i];
+ obj[key] = _.bind(obj[key], obj);
+ }
+ return obj;
+ };
+
+ // Memoize an expensive function by storing its results.
+ _.memoize = function(func, hasher) {
+ var memoize = function(key) {
+ var cache = memoize.cache;
+ var address = '' + (hasher ? hasher.apply(this, arguments) : key);
+ if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
+ return cache[address];
+ };
+ memoize.cache = {};
+ return memoize;
+ };
+
+ // Delays a function for the given number of milliseconds, and then calls
+ // it with the arguments supplied.
+ _.delay = function(func, wait) {
+ var args = slice.call(arguments, 2);
+ return setTimeout(function(){
+ return func.apply(null, args);
+ }, wait);
+ };
+
+ // Defers a function, scheduling it to run after the current call stack has
+ // cleared.
+ _.defer = _.partial(_.delay, _, 1);
+
+ // Returns a function, that, when invoked, will only be triggered at most once
+ // during a given window of time. Normally, the throttled function will run
+ // as much as it can, without ever going more than once per `wait` duration;
+ // but if you'd like to disable the execution on the leading edge, pass
+ // `{leading: false}`. To disable execution on the trailing edge, ditto.
+ _.throttle = function(func, wait, options) {
+ var context, args, result;
+ var timeout = null;
+ var previous = 0;
+ if (!options) options = {};
+ var later = function() {
+ previous = options.leading === false ? 0 : _.now();
+ timeout = null;
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ };
+ return function() {
+ var now = _.now();
+ if (!previous && options.leading === false) previous = now;
+ var remaining = wait - (now - previous);
+ context = this;
+ args = arguments;
+ if (remaining <= 0 || remaining > wait) {
+ if (timeout) {
+ clearTimeout(timeout);
+ timeout = null;
+ }
+ previous = now;
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ } else if (!timeout && options.trailing !== false) {
+ timeout = setTimeout(later, remaining);
+ }
+ return result;
+ };
+ };
+
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds. If `immediate` is passed, trigger the function on the
+ // leading edge, instead of the trailing.
+ _.debounce = function(func, wait, immediate) {
+ var timeout, args, context, timestamp, result;
+
+ var later = function() {
+ var last = _.now() - timestamp;
+
+ if (last < wait && last >= 0) {
+ timeout = setTimeout(later, wait - last);
+ } else {
+ timeout = null;
+ if (!immediate) {
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ }
+ }
+ };
+
+ return function() {
+ context = this;
+ args = arguments;
+ timestamp = _.now();
+ var callNow = immediate && !timeout;
+ if (!timeout) timeout = setTimeout(later, wait);
+ if (callNow) {
+ result = func.apply(context, args);
+ context = args = null;
+ }
+
+ return result;
+ };
+ };
+
+ // Returns the first function passed as an argument to the second,
+ // allowing you to adjust arguments, run code before and after, and
+ // conditionally execute the original function.
+ _.wrap = function(func, wrapper) {
+ return _.partial(wrapper, func);
+ };
+
+ // Returns a negated version of the passed-in predicate.
+ _.negate = function(predicate) {
+ return function() {
+ return !predicate.apply(this, arguments);
+ };
+ };
+
+ // Returns a function that is the composition of a list of functions, each
+ // consuming the return value of the function that follows.
+ _.compose = function() {
+ var args = arguments;
+ var start = args.length - 1;
+ return function() {
+ var i = start;
+ var result = args[start].apply(this, arguments);
+ while (i--) result = args[i].call(this, result);
+ return result;
+ };
+ };
+
+ // Returns a function that will only be executed on and after the Nth call.
+ _.after = function(times, func) {
+ return function() {
+ if (--times < 1) {
+ return func.apply(this, arguments);
+ }
+ };
+ };
+
+ // Returns a function that will only be executed up to (but not including) the Nth call.
+ _.before = function(times, func) {
+ var memo;
+ return function() {
+ if (--times > 0) {
+ memo = func.apply(this, arguments);
+ }
+ if (times <= 1) func = null;
+ return memo;
+ };
+ };
+
+ // Returns a function that will be executed at most one time, no matter how
+ // often you call it. Useful for lazy initialization.
+ _.once = _.partial(_.before, 2);
+
+ // Object Functions
+ // ----------------
+
+ // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
+ var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
+ var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
+ 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
+
+ function collectNonEnumProps(obj, keys) {
+ var nonEnumIdx = nonEnumerableProps.length;
+ var constructor = obj.constructor;
+ var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
+
+ // Constructor is a special case.
+ var prop = 'constructor';
+ if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
+
+ while (nonEnumIdx--) {
+ prop = nonEnumerableProps[nonEnumIdx];
+ if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
+ keys.push(prop);
+ }
+ }
+ }
+
+ // Retrieve the names of an object's own properties.
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
+ _.keys = function(obj) {
+ if (!_.isObject(obj)) return [];
+ if (nativeKeys) return nativeKeys(obj);
+ var keys = [];
+ for (var key in obj) if (_.has(obj, key)) keys.push(key);
+ // Ahem, IE < 9.
+ if (hasEnumBug) collectNonEnumProps(obj, keys);
+ return keys;
+ };
+
+ // Retrieve all the property names of an object.
+ _.allKeys = function(obj) {
+ if (!_.isObject(obj)) return [];
+ var keys = [];
+ for (var key in obj) keys.push(key);
+ // Ahem, IE < 9.
+ if (hasEnumBug) collectNonEnumProps(obj, keys);
+ return keys;
+ };
+
+ // Retrieve the values of an object's properties.
+ _.values = function(obj) {
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var values = Array(length);
+ for (var i = 0; i < length; i++) {
+ values[i] = obj[keys[i]];
+ }
+ return values;
+ };
+
+ // Returns the results of applying the iteratee to each element of the object
+ // In contrast to _.map it returns an object
+ _.mapObject = function(obj, iteratee, context) {
+ iteratee = cb(iteratee, context);
+ var keys = _.keys(obj),
+ length = keys.length,
+ results = {},
+ currentKey;
+ for (var index = 0; index < length; index++) {
+ currentKey = keys[index];
+ results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
+ }
+ return results;
+ };
+
+ // Convert an object into a list of `[key, value]` pairs.
+ _.pairs = function(obj) {
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var pairs = Array(length);
+ for (var i = 0; i < length; i++) {
+ pairs[i] = [keys[i], obj[keys[i]]];
+ }
+ return pairs;
+ };
+
+ // Invert the keys and values of an object. The values must be serializable.
+ _.invert = function(obj) {
+ var result = {};
+ var keys = _.keys(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ result[obj[keys[i]]] = keys[i];
+ }
+ return result;
+ };
+
+ // Return a sorted list of the function names available on the object.
+ // Aliased as `methods`
+ _.functions = _.methods = function(obj) {
+ var names = [];
+ for (var key in obj) {
+ if (_.isFunction(obj[key])) names.push(key);
+ }
+ return names.sort();
+ };
+
+ // Extend a given object with all the properties in passed-in object(s).
+ _.extend = createAssigner(_.allKeys);
+
+ // Assigns a given object with all the own properties in the passed-in object(s)
+ // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
+ _.extendOwn = _.assign = createAssigner(_.keys);
+
+ // Returns the first key on an object that passes a predicate test
+ _.findKey = function(obj, predicate, context) {
+ predicate = cb(predicate, context);
+ var keys = _.keys(obj), key;
+ for (var i = 0, length = keys.length; i < length; i++) {
+ key = keys[i];
+ if (predicate(obj[key], key, obj)) return key;
+ }
+ };
+
+ // Return a copy of the object only containing the whitelisted properties.
+ _.pick = function(object, oiteratee, context) {
+ var result = {}, obj = object, iteratee, keys;
+ if (obj == null) return result;
+ if (_.isFunction(oiteratee)) {
+ keys = _.allKeys(obj);
+ iteratee = optimizeCb(oiteratee, context);
+ } else {
+ keys = flatten(arguments, false, false, 1);
+ iteratee = function(value, key, obj) { return key in obj; };
+ obj = Object(obj);
+ }
+ for (var i = 0, length = keys.length; i < length; i++) {
+ var key = keys[i];
+ var value = obj[key];
+ if (iteratee(value, key, obj)) result[key] = value;
+ }
+ return result;
+ };
+
+ // Return a copy of the object without the blacklisted properties.
+ _.omit = function(obj, iteratee, context) {
+ if (_.isFunction(iteratee)) {
+ iteratee = _.negate(iteratee);
+ } else {
+ var keys = _.map(flatten(arguments, false, false, 1), String);
+ iteratee = function(value, key) {
+ return !_.contains(keys, key);
+ };
+ }
+ return _.pick(obj, iteratee, context);
+ };
+
+ // Fill in a given object with default properties.
+ _.defaults = createAssigner(_.allKeys, true);
+
+ // Creates an object that inherits from the given prototype object.
+ // If additional properties are provided then they will be added to the
+ // created object.
+ _.create = function(prototype, props) {
+ var result = baseCreate(prototype);
+ if (props) _.extendOwn(result, props);
+ return result;
+ };
+
+ // Create a (shallow-cloned) duplicate of an object.
+ _.clone = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+ };
+
+ // Invokes interceptor with the obj, and then returns obj.
+ // The primary purpose of this method is to "tap into" a method chain, in
+ // order to perform operations on intermediate results within the chain.
+ _.tap = function(obj, interceptor) {
+ interceptor(obj);
+ return obj;
+ };
+
+ // Returns whether an object has a given set of `key:value` pairs.
+ _.isMatch = function(object, attrs) {
+ var keys = _.keys(attrs), length = keys.length;
+ if (object == null) return !length;
+ var obj = Object(object);
+ for (var i = 0; i < length; i++) {
+ var key = keys[i];
+ if (attrs[key] !== obj[key] || !(key in obj)) return false;
+ }
+ return true;
+ };
+
+
+ // Internal recursive comparison function for `isEqual`.
+ var eq = function(a, b, aStack, bStack) {
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
+ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
+ if (a === b) return a !== 0 || 1 / a === 1 / b;
+ // A strict comparison is necessary because `null == undefined`.
+ if (a == null || b == null) return a === b;
+ // Unwrap any wrapped objects.
+ if (a instanceof _) a = a._wrapped;
+ if (b instanceof _) b = b._wrapped;
+ // Compare `[[Class]]` names.
+ var className = toString.call(a);
+ if (className !== toString.call(b)) return false;
+ switch (className) {
+ // Strings, numbers, regular expressions, dates, and booleans are compared by value.
+ case '[object RegExp]':
+ // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
+ case '[object String]':
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+ // equivalent to `new String("5")`.
+ return '' + a === '' + b;
+ case '[object Number]':
+ // `NaN`s are equivalent, but non-reflexive.
+ // Object(NaN) is equivalent to NaN
+ if (+a !== +a) return +b !== +b;
+ // An `egal` comparison is performed for other numeric values.
+ return +a === 0 ? 1 / +a === 1 / b : +a === +b;
+ case '[object Date]':
+ case '[object Boolean]':
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+ // millisecond representations. Note that invalid dates with millisecond representations
+ // of `NaN` are not equivalent.
+ return +a === +b;
+ }
+
+ var areArrays = className === '[object Array]';
+ if (!areArrays) {
+ if (typeof a != 'object' || typeof b != 'object') return false;
+
+ // Objects with different constructors are not equivalent, but `Object`s or `Array`s
+ // from different frames are.
+ var aCtor = a.constructor, bCtor = b.constructor;
+ if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
+ _.isFunction(bCtor) && bCtor instanceof bCtor)
+ && ('constructor' in a && 'constructor' in b)) {
+ return false;
+ }
+ }
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+
+ // Initializing stack of traversed objects.
+ // It's done here since we only need them for objects and arrays comparison.
+ aStack = aStack || [];
+ bStack = bStack || [];
+ var length = aStack.length;
+ while (length--) {
+ // Linear search. Performance is inversely proportional to the number of
+ // unique nested structures.
+ if (aStack[length] === a) return bStack[length] === b;
+ }
+
+ // Add the first object to the stack of traversed objects.
+ aStack.push(a);
+ bStack.push(b);
+
+ // Recursively compare objects and arrays.
+ if (areArrays) {
+ // Compare array lengths to determine if a deep comparison is necessary.
+ length = a.length;
+ if (length !== b.length) return false;
+ // Deep compare the contents, ignoring non-numeric properties.
+ while (length--) {
+ if (!eq(a[length], b[length], aStack, bStack)) return false;
+ }
+ } else {
+ // Deep compare objects.
+ var keys = _.keys(a), key;
+ length = keys.length;
+ // Ensure that both objects contain the same number of properties before comparing deep equality.
+ if (_.keys(b).length !== length) return false;
+ while (length--) {
+ // Deep compare each member
+ key = keys[length];
+ if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
+ }
+ }
+ // Remove the first object from the stack of traversed objects.
+ aStack.pop();
+ bStack.pop();
+ return true;
+ };
+
+ // Perform a deep comparison to check if two objects are equal.
+ _.isEqual = function(a, b) {
+ return eq(a, b);
+ };
+
+ // Is a given array, string, or object empty?
+ // An "empty" object has no enumerable own-properties.
+ _.isEmpty = function(obj) {
+ if (obj == null) return true;
+ if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
+ return _.keys(obj).length === 0;
+ };
+
+ // Is a given value a DOM element?
+ _.isElement = function(obj) {
+ return !!(obj && obj.nodeType === 1);
+ };
+
+ // Is a given value an array?
+ // Delegates to ECMA5's native Array.isArray
+ _.isArray = nativeIsArray || function(obj) {
+ return toString.call(obj) === '[object Array]';
+ };
+
+ // Is a given variable an object?
+ _.isObject = function(obj) {
+ var type = typeof obj;
+ return type === 'function' || type === 'object' && !!obj;
+ };
+
+ // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
+ _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
+ _['is' + name] = function(obj) {
+ return toString.call(obj) === '[object ' + name + ']';
+ };
+ });
+
+ // Define a fallback version of the method in browsers (ahem, IE < 9), where
+ // there isn't any inspectable "Arguments" type.
+ if (!_.isArguments(arguments)) {
+ _.isArguments = function(obj) {
+ return _.has(obj, 'callee');
+ };
+ }
+
+ // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
+ // IE 11 (#1621), and in Safari 8 (#1929).
+ if (typeof /./ != 'function' && typeof Int8Array != 'object') {
+ _.isFunction = function(obj) {
+ return typeof obj == 'function' || false;
+ };
+ }
+
+ // Is a given object a finite number?
+ _.isFinite = function(obj) {
+ return isFinite(obj) && !isNaN(parseFloat(obj));
+ };
+
+ // Is the given value `NaN`? (NaN is the only number which does not equal itself).
+ _.isNaN = function(obj) {
+ return _.isNumber(obj) && obj !== +obj;
+ };
+
+ // Is a given value a boolean?
+ _.isBoolean = function(obj) {
+ return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
+ };
+
+ // Is a given value equal to null?
+ _.isNull = function(obj) {
+ return obj === null;
+ };
+
+ // Is a given variable undefined?
+ _.isUndefined = function(obj) {
+ return obj === void 0;
+ };
+
+ // Shortcut function for checking if an object has a given property directly
+ // on itself (in other words, not on a prototype).
+ _.has = function(obj, key) {
+ return obj != null && hasOwnProperty.call(obj, key);
+ };
+
+ // Utility Functions
+ // -----------------
+
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+ // previous owner. Returns a reference to the Underscore object.
+ _.noConflict = function() {
+ root._ = previousUnderscore;
+ return this;
+ };
+
+ // Keep the identity function around for default iteratees.
+ _.identity = function(value) {
+ return value;
+ };
+
+ // Predicate-generating functions. Often useful outside of Underscore.
+ _.constant = function(value) {
+ return function() {
+ return value;
+ };
+ };
+
+ _.noop = function(){};
+
+ _.property = property;
+
+ // Generates a function for a given object that returns a given property.
+ _.propertyOf = function(obj) {
+ return obj == null ? function(){} : function(key) {
+ return obj[key];
+ };
+ };
+
+ // Returns a predicate for checking whether an object has a given set of
+ // `key:value` pairs.
+ _.matcher = _.matches = function(attrs) {
+ attrs = _.extendOwn({}, attrs);
+ return function(obj) {
+ return _.isMatch(obj, attrs);
+ };
+ };
+
+ // Run a function **n** times.
+ _.times = function(n, iteratee, context) {
+ var accum = Array(Math.max(0, n));
+ iteratee = optimizeCb(iteratee, context, 1);
+ for (var i = 0; i < n; i++) accum[i] = iteratee(i);
+ return accum;
+ };
+
+ // Return a random integer between min and max (inclusive).
+ _.random = function(min, max) {
+ if (max == null) {
+ max = min;
+ min = 0;
+ }
+ return min + Math.floor(Math.random() * (max - min + 1));
+ };
+
+ // A (possibly faster) way to get the current timestamp as an integer.
+ _.now = Date.now || function() {
+ return new Date().getTime();
+ };
+
+ // List of HTML entities for escaping.
+ var escapeMap = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&quot;',
+ "'": '&#x27;',
+ '`': '&#x60;'
+ };
+ var unescapeMap = _.invert(escapeMap);
+
+ // Functions for escaping and unescaping strings to/from HTML interpolation.
+ var createEscaper = function(map) {
+ var escaper = function(match) {
+ return map[match];
+ };
+ // Regexes for identifying a key that needs to be escaped
+ var source = '(?:' + _.keys(map).join('|') + ')';
+ var testRegexp = RegExp(source);
+ var replaceRegexp = RegExp(source, 'g');
+ return function(string) {
+ string = string == null ? '' : '' + string;
+ return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
+ };
+ };
+ _.escape = createEscaper(escapeMap);
+ _.unescape = createEscaper(unescapeMap);
+
+ // If the value of the named `property` is a function then invoke it with the
+ // `object` as context; otherwise, return it.
+ _.result = function(object, property, fallback) {
+ var value = object == null ? void 0 : object[property];
+ if (value === void 0) {
+ value = fallback;
+ }
+ return _.isFunction(value) ? value.call(object) : value;
+ };
+
+ // Generate a unique integer id (unique within the entire client session).
+ // Useful for temporary DOM ids.
+ var idCounter = 0;
+ _.uniqueId = function(prefix) {
+ var id = ++idCounter + '';
+ return prefix ? prefix + id : id;
+ };
+
+ // By default, Underscore uses ERB-style template delimiters, change the
+ // following template settings to use alternative delimiters.
+ _.templateSettings = {
+ evaluate : /<%([\s\S]+?)%>/g,
+ interpolate : /<%=([\s\S]+?)%>/g,
+ escape : /<%-([\s\S]+?)%>/g
+ };
+
+ // When customizing `templateSettings`, if you don't want to define an
+ // interpolation, evaluation or escaping regex, we need one that is
+ // guaranteed not to match.
+ var noMatch = /(.)^/;
+
+ // Certain characters need to be escaped so that they can be put into a
+ // string literal.
+ var escapes = {
+ "'": "'",
+ '\\': '\\',
+ '\r': 'r',
+ '\n': 'n',
+ '\u2028': 'u2028',
+ '\u2029': 'u2029'
+ };
+
+ var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
+
+ var escapeChar = function(match) {
+ return '\\' + escapes[match];
+ };
+
+ // JavaScript micro-templating, similar to John Resig's implementation.
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
+ // and correctly escapes quotes within interpolated code.
+ // NB: `oldSettings` only exists for backwards compatibility.
+ _.template = function(text, settings, oldSettings) {
+ if (!settings && oldSettings) settings = oldSettings;
+ settings = _.defaults({}, settings, _.templateSettings);
+
+ // Combine delimiters into one regular expression via alternation.
+ var matcher = RegExp([
+ (settings.escape || noMatch).source,
+ (settings.interpolate || noMatch).source,
+ (settings.evaluate || noMatch).source
+ ].join('|') + '|$', 'g');
+
+ // Compile the template source, escaping string literals appropriately.
+ var index = 0;
+ var source = "__p+='";
+ text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
+ source += text.slice(index, offset).replace(escaper, escapeChar);
+ index = offset + match.length;
+
+ if (escape) {
+ source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
+ } else if (interpolate) {
+ source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
+ } else if (evaluate) {
+ source += "';\n" + evaluate + "\n__p+='";
+ }
+
+ // Adobe VMs need the match returned to produce the correct offest.
+ return match;
+ });
+ source += "';\n";
+
+ // If a variable is not specified, place data values in local scope.
+ if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
+
+ source = "var __t,__p='',__j=Array.prototype.join," +
+ "print=function(){__p+=__j.call(arguments,'');};\n" +
+ source + 'return __p;\n';
+
+ try {
+ var render = new Function(settings.variable || 'obj', '_', source);
+ } catch (e) {
+ e.source = source;
+ throw e;
+ }
+
+ var template = function(data) {
+ return render.call(this, data, _);
+ };
+
+ // Provide the compiled source as a convenience for precompilation.
+ var argument = settings.variable || 'obj';
+ template.source = 'function(' + argument + '){\n' + source + '}';
+
+ return template;
+ };
+
+ // Add a "chain" function. Start chaining a wrapped Underscore object.
+ _.chain = function(obj) {
+ var instance = _(obj);
+ instance._chain = true;
+ return instance;
+ };
+
+ // OOP
+ // ---------------
+ // If Underscore is called as a function, it returns a wrapped object that
+ // can be used OO-style. This wrapper holds altered versions of all the
+ // underscore functions. Wrapped objects may be chained.
+
+ // Helper function to continue chaining intermediate results.
+ var result = function(instance, obj) {
+ return instance._chain ? _(obj).chain() : obj;
+ };
+
+ // Add your own custom functions to the Underscore object.
+ _.mixin = function(obj) {
+ _.each(_.functions(obj), function(name) {
+ var func = _[name] = obj[name];
+ _.prototype[name] = function() {
+ var args = [this._wrapped];
+ push.apply(args, arguments);
+ return result(this, func.apply(_, args));
+ };
+ });
+ };
+
+ // Add all of the Underscore functions to the wrapper object.
+ _.mixin(_);
+
+ // Add all mutator Array functions to the wrapper.
+ _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+ var method = ArrayProto[name];
+ _.prototype[name] = function() {
+ var obj = this._wrapped;
+ method.apply(obj, arguments);
+ if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
+ return result(this, obj);
+ };
+ });
+
+ // Add all accessor Array functions to the wrapper.
+ _.each(['concat', 'join', 'slice'], function(name) {
+ var method = ArrayProto[name];
+ _.prototype[name] = function() {
+ return result(this, method.apply(this._wrapped, arguments));
+ };
+ });
+
+ // Extracts the result from a wrapped and chained object.
+ _.prototype.value = function() {
+ return this._wrapped;
+ };
+
+ // Provide unwrapping proxy for some methods used in engine operations
+ // such as arithmetic and JSON stringification.
+ _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
+
+ _.prototype.toString = function() {
+ return '' + this._wrapped;
+ };
+
+ // AMD registration happens at the end for compatibility with AMD loaders
+ // that may not enforce next-turn semantics on modules. Even though general
+ // practice for AMD registration is to be anonymous, underscore registers
+ // as a named module because, like jQuery, it is a base library that is
+ // popular enough to be bundled in a third party lib, but not be part of
+ // an AMD load request. Those cases could generate an error when an
+ // anonymous define() is called outside of a loader request.
+ if (typeof define === 'function' && define.amd) {
+ define('underscore', [], function() {
+ return _;
+ });
+ }
+}.call(this));