From a751a561ff86ef25b7ce1bc4bf8a81f12c9a2dd7 Mon Sep 17 00:00:00 2001 From: Andrew Humphreys Date: Fri, 26 Feb 2016 12:03:03 +0000 Subject: [PATCH] Build 1.4.0 --- dist/orchestra.js | 12 ++++++++---- dist/orchestra.js.map | 2 +- dist/orchestra.min.js | 2 +- dist/orchestra.min.js.map | 2 +- lib/helpers/translate.js | 12 ++++++++---- lib/helpers/translate.js.map | 2 +- 6 files changed, 20 insertions(+), 12 deletions(-) diff --git a/dist/orchestra.js b/dist/orchestra.js index 4c8030c..66677f6 100644 --- a/dist/orchestra.js +++ b/dist/orchestra.js @@ -41149,15 +41149,19 @@ var TranslateHelpers = (function () { value: function translate(i18nKey, params) { var locale = this.getLocale(); var result = null; + var options = { + postProcess: 'sprintf', + sprintf: params + }; _i18next2.default.use(_i18nextSprintfPostprocessor2.default).init({ lng: locale, resources: resources[locale] }, function (err, translate) { - result = translate(i18nKey, { - postProcess: 'sprintf', - sprintf: params - }); + if (params && params.count) { + options.count = params.count; + } + result = translate(i18nKey, options); }); return result; diff --git a/dist/orchestra.js.map b/dist/orchestra.js.map index f6d7521..d08a0dd 100644 --- a/dist/orchestra.js.map +++ b/dist/orchestra.js.map @@ -1 +1 @@ -{"version":3,"names":[],"mappings":"","sources":["orchestra.js"],"sourcesContent":["(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.orchestra = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o> Created!\n * ```\n *\n * @public\n * @class Class\n * @memberOf Metal\n * @memberOf Backbone\n */\n var Class = Metal.Class = function () {\n var _ref;\n (_ref = this).initialize.apply(_ref, arguments);\n };\n\n /**\n * An overridable method called when objects are instantiated. Does not do\n * anything by default.\n *\n * @public\n * @abstract\n * @method initialize\n */\n Class.prototype.initialize = _.noop;\n\n _.extend(Class, {\n\n /**\n * Creates a new subclass.\n *\n * ```js\n * var MyClass = Class.extend({\n * // ...\n * });\n *\n * var myClass = new MyClass();\n * myClass instanceof MyClass\n * // true\n * myClass instanceof Class\n * // true\n * ```\n *\n * @public\n * @static\n * @method extend\n * @param {Object} [protoProps] - The properties to be added to the prototype.\n * @param {Object} [staticProps] - The properties to be added to the constructor.\n */\n extend: function extend(protoProps, staticProps) {\n var Parent = this;\n var Child;\n\n // The constructor function for the new subclass is either defined by you\n // (the \"constructor\" property in your `extend` definition), or defaulted\n // by us to simply call the parent's constructor.\n if (!protoProps || !_.has(protoProps, \"constructor\")) {\n Child = function () {\n Parent.apply(this, arguments);\n };\n } else if (CONTAINS_SUPER.test(protoProps.constructor)) {\n Child = _wrap(protoProps.constructor, Parent.prototype.constructor);\n } else {\n Child = protoProps.constructor;\n }\n\n // Add static properties to the constructor function, if supplied.\n _.extend(Child, Parent);\n if (staticProps) {\n _wrapAll(Child, staticProps);\n }\n\n // Set the prototype chain to inherit from `parent`, without calling\n // `parent`'s constructor function.\n var Surrogate = function () {\n this.constructor = Child;\n };\n Surrogate.prototype = Parent.prototype;\n Child.prototype = new Surrogate();\n\n // Add prototype properties (instance properties) to the subclass,\n // if supplied.\n if (protoProps) {\n _wrapAll(Child.prototype, protoProps);\n }\n\n // Set a convenience property in case the parent class is needed later.\n Child.superclass = Parent;\n\n // Set a convenience property in case the parent's prototype is needed\n // later.\n Child.__super__ = Parent.prototype;\n\n return Child;\n },\n\n /**\n * Mixes properties onto the class's prototype.\n *\n * ```js\n * var MyMixin = new Mixin({\n * alert() {\n * console.log('Alert!');\n * }\n * });\n *\n * var MyClass = Class.extend({\n * initialize() {\n * this.alert();\n * }\n * });\n *\n * MyClass.mixin(MyMixin);\n *\n * new MyClass();\n * // >> Alert!\n * ```\n *\n * @public\n * @static\n * @method mixin\n * @param {Object} protoProps - The properties to be added to the prototype.\n * @return {Class} - The class.\n */\n mixin: function mixin(protoProps) {\n // Add prototype properties (instance properties) to the class, if supplied.\n _wrapAll(this.prototype, protoProps);\n return this;\n },\n\n /**\n * Mixes properties onto the class's constructor.\n *\n * ```js\n * var MyMixin = new Mixin({\n * alert() {\n * console.log('Alert!');\n * }\n * });\n *\n * var MyClass = Class.extend(...);\n *\n * MyClass.include(MyMixin);\n *\n * MyClass.alert();\n * // >> Alert!\n * ```\n *\n * You can also simply pass a plain javascript object.\n *\n * ```js\n * var MyClass = Class.extend(...);\n *\n * MyClass.include({\n * alert() {\n * console.log('Alert!');\n * }\n * });\n *\n * MyClass.alert();\n * // >> Alert!\n * ```\n *\n * @public\n * @static\n * @method mixin\n * @param {Object} staticProps - The properties to be added to the constructor.\n * @return {Class} - The class.\n */\n include: function include(staticProps) {\n // Add static properties to the constructor function, if supplied.\n _wrapAll(this, staticProps);\n return this;\n },\n\n /**\n * Checks if `value` is a Metal Class.\n *\n * ```js\n * _.isClass(Class.extend(...));\n * // >> true\n * _.isClass(new Class());\n * // >> true\n * _.isClass(function() {...});\n * // >> false\n * _.isClass({...});\n * // >> false\n * ```\n * @public\n * @method isClass\n * @memberOf _\n * @param {*} value - The value to check.\n */\n isClass: function isClass(value) {\n return !!value && (value instanceof Class || value.prototype instanceof Class || value === Class);\n }\n });\n\n /**\n * Allows you to create mixins, whose properties can be added to other classes.\n *\n * @public\n * @class Mixin\n * @memberOf Metal\n * @memberOf Backbone\n * @param {Object} protoProps - The properties to be added to the prototype.\n */\n var Mixin = Metal.Mixin = function (protoProps) {\n // Add prototype properties (instance properties) to the class, if supplied.\n _.extend(this, protoProps);\n };\n\n /**\n * Checks if `value` is a Metal Mixin.\n *\n * ```js\n * _.isMixin(new Mixin());\n * // >> true\n * _.isMixin({});\n * // >> false\n * _.isMixin(function() {...});\n * // >> false\n * _.isMixin(new Class());\n * // >> false\n * ```\n *\n * @public\n * @method isMixin\n * @memberOf _\n * @param {*} value - The value to check.\n */\n Mixin.isMixin = function (value) {\n return !!value && value instanceof Mixin;\n };\n\n /**\n * @private\n * @const {String[]}\n */\n var ERROR_PROPS = [\"description\", \"fileName\", \"lineNumber\", \"name\", \"message\", \"number\"];\n\n /**\n * A subclass of the JavaScript Error.\n *\n * ```js\n * throw new Metal.Error('Oh you\\'ve really done it now...');\n * // Uncaught Metal.Error: Oh you've really done it now...\n * // [stack trace]\n * ```\n *\n * @class Error\n * @memberOf Metal\n * @extends Error\n * @uses Metal.Class\n */\n var Err = Metal.Error = Class.extend.call(Error, {\n\n /**\n * @public\n * @constructs Error\n * @param {String} [message] - A description of the error.\n * @param {Object} [options] - Settings for the error.\n * @param {String} [options.message] - A description of the error.\n */\n constructor: function constructor(message) {\n var options = arguments[1] === undefined ? {} : arguments[1];\n // If options are provided in place of a message, assume message exists on\n // options.\n if (_.isObject(message)) {\n options = message;\n message = options.message;\n }\n\n // Create a fake error with message in order to capture a stack trace.\n var error = Error.call(this, message);\n\n // Copy over all the error-related properties.\n _.extend(this, _.pick(error, ERROR_PROPS), _.pick(options, ERROR_PROPS));\n\n // Adds a `stack` property to the given error object that will yield the\n // stack trace at the time captureStackTrace was called.\n // When collecting the stack trace all frames above the topmost call\n // to this function, including that call, will be left out of the\n // stack trace.\n // This is useful because we can hide Metal implementation details\n // that are not very helpful for the user.\n Err.captureStackTrace(this, Err);\n },\n\n /**\n * Formats the error message to display in the console.\n *\n * @public\n * @method toString\n * @returns {String} - Formatted error message.\n */\n toString: function toString() {\n return \"\" + this.name + \": \" + this.message;\n }\n }, {\n\n /**\n * A safe reference to V8's `Error.captureStackTrace`.\n *\n * @public\n * @method captureStackTrace\n */\n captureStackTrace: function captureStackTrace(target, method) {\n if (Error.captureStackTrace) {\n Error.captureStackTrace(target, method);\n }\n }\n });\n\n /**\n * @class Error\n * @mixes Class\n */\n _.extend(Err, Class);\n\n /**\n * Display a deprecation warning with the provided message.\n *\n * @public\n * @method deprecate\n * @param {String|Object} message - A description of the deprecation.\n * @param {String} message.prev - The deprecated item.\n * @param {String} message.next - The replacement for the deprecated item.\n * @param {Boolean} [test] - An optional boolean. If falsy, the deprecation will be displayed.\n */\n var deprecate = Metal.deprecate = function (message, test) {\n // Returns if test is provided and is falsy.\n if (test !== undefined && test) {\n return;\n }\n\n // If message is provided as an object, format the object into a string.\n if (_.isObject(message)) {\n message = deprecate._format(message.prev, message.next);\n }\n\n // Ensure that message is a string\n message = message && message.toString();\n\n // If deprecation message has not already been warned, send the warning.\n if (!deprecate._cache[message]) {\n deprecate._warn(\"Deprecation warning: \" + message);\n deprecate._cache[message] = true;\n }\n };\n\n /**\n * Format a message for deprecate.\n *\n * @private\n * @method _format\n * @memberOf deprecate\n * @param {String} prev - The deprecated item.\n * @param {String} next - The replacement for the deprecated item.\n * @return {String} - The formatted message.\n */\n deprecate._format = function (prev, next) {\n return \"\" + prev + \" is going to be removed in the future. Please use \" + next + \" instead.\";\n };\n\n /**\n * A safe reference to `console.warn` that will fallback to `console.log` or\n * `_noop` if the `console` object does not exist.\n *\n * @private\n * @method _warn\n * @memberOf deprecate\n * @param {*...} - The values to warn in the console.\n */\n deprecate._warn = typeof console !== \"undefined\" && (console.warn || console.log) || _.noop;\n\n /**\n * An internal cache to avoid sending the same deprecation warning multiple\n * times.\n *\n * @private\n * @property _cache\n * @memberOf deprecate\n */\n deprecate._cache = {};\n\n /**\n * A `Metal.Mixin` version of `Backbone.Events`.\n *\n * @mixin Events\n * @memberOf Metal\n * @memberOf Backbone\n * @extends Metal.Mixin\n * @mixes Backbone.Events\n */\n var Events = Metal.Events = new Mixin(Backbone.Events);\n\n /**\n * @class Class\n * @mixes Events\n */\n Class.mixin(Events);\n\n\n return Metal;\n\n}));\n\n},{\"backbone\":18,\"underscore\":34}],3:[function(require,module,exports){\nvar _ = require('underscore');\n\nmodule.exports = function normalizeHash(source, hash) {\n var obj = _.result(source, hash);\n var clone = {};\n\n _.each(obj, function(val, key) {\n clone[key] = _.isFunction(val) ? val : source[key];\n });\n\n return clone;\n};\n\n},{\"underscore\":34}],4:[function(require,module,exports){\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('backbone'), require('backbone-metal')) : typeof define === 'function' && define.amd ? define(['backbone', 'backbone-metal'], factory) : global.Backbone.Routing = factory(global.Backbone, global.Metal);\n})(this, function (Backbone, Metal) {\n 'use strict';\n\n var CancellationError = Metal.Error.extend({\n name: 'CancellationError'\n });\n\n /**\n * @public\n * @class Route\n */\n var Route = Metal.Class.extend({\n\n /**\n * @public\n * @method enter\n * @returns {Promise}\n * @param {...*} [args=[]]\n */\n enter: function enter() {\n var _this = this;\n\n var args = arguments[0] === undefined ? [] : arguments[0];\n\n this._isEntering = true;\n this.trigger.apply(this, ['before:enter before:fetch', this].concat(args));\n\n return Promise.resolve().then(function () {\n if (_this._isCancelled) {\n return Promise.reject(new CancellationError());\n }\n return _this.fetch.apply(_this, args);\n }).then(function () {\n return _this.trigger.apply(_this, ['fetch before:render', _this].concat(args));\n }).then(function () {\n if (_this._isCancelled) {\n return Promise.reject(new CancellationError());\n }\n return _this.render.apply(_this, args);\n }).then(function () {\n _this._isEntering = false;\n _this.trigger.apply(_this, ['render enter', _this].concat(args));\n })['catch'](function (err) {\n _this._isEntering = false;\n if (err instanceof CancellationError) {\n _this.trigger('cancel', _this);\n } else {\n _this.trigger('error error:enter', _this, err);\n throw err;\n }\n });\n },\n\n /**\n * @public\n * @method exit\n * @returns {Promise}\n */\n exit: function exit() {\n var _this2 = this;\n\n if (this._isEntering) {\n this.cancel();\n }\n this._isExiting = true;\n this.trigger('before:exit before:destroy', this);\n\n return Promise.resolve().then(function () {\n return _this2.destroy();\n }).then(function () {\n _this2._isExiting = false;\n _this2.trigger('destroy exit', _this2);\n _this2.stopListening();\n })['catch'](function (err) {\n _this2._isExiting = false;\n _this2.trigger('error error:exit', _this2, err);\n _this2.stopListening();\n throw err;\n });\n },\n\n /**\n * @public\n * @method cancel\n * @returns {Promise}\n */\n cancel: function cancel() {\n var _this3 = this;\n\n if (!this._isEntering) {\n return;\n }\n this.trigger('before:cancel', this);\n this._isCancelled = true;\n return new Promise(function (resolve, reject) {\n _this3.once('cancel', resolve);\n _this3.once('enter error', reject);\n });\n },\n\n /**\n * @public\n * @method isEntering\n * @returns {Boolean}\n */\n isEntering: function isEntering() {\n return !!this._isEntering;\n },\n\n /**\n * @public\n * @method isExiting\n * @returns {Boolean}\n */\n isExiting: function isExiting() {\n return !!this._isExiting;\n },\n\n /**\n * @public\n * @method isCancelled\n * @returns {Boolean}\n */\n isCancelled: function isCancelled() {\n return !!this._isCancelled;\n },\n\n /**\n * @public\n * @abstract\n * @method fetch\n * @param {...*} [args=[]]\n */\n fetch: function fetch() {},\n\n /**\n * @public\n * @abstract\n * @method render\n * @param {...*} [args=[]]\n */\n render: function render() {},\n\n /**\n * @public\n * @abstract\n * @method destroy\n */\n destroy: function destroy() {}\n });\n\n /**\n * @public\n * @class Router\n */\n var Router = Metal.Class.extend(Backbone.Router.prototype, Backbone.Router).extend({\n constructor: function constructor() {\n this.listenTo(Backbone.history, 'route', this._onHistoryRoute);\n this._super.apply(this, arguments);\n },\n\n /**\n * @public\n * @method isActive\n * @returns {Boolean}\n */\n isActive: function isActive() {\n return !!this._isActive;\n },\n\n /**\n * @public\n * @method execute\n * @param {Function} callback\n * @param {Array} [args]\n */\n execute: function execute(callback, args) {\n var _this4 = this;\n\n var wasInactive = !this._isActive;\n if (wasInactive) {\n this.trigger('before:enter', this);\n }\n\n this.trigger('before:route', this);\n\n return Promise.resolve().then(function () {\n return _this4._execute(callback, args);\n }).then(function () {\n _this4.trigger('route', _this4);\n\n if (wasInactive) {\n _this4.trigger('enter', _this4);\n }\n })['catch'](function (err) {\n _this4.trigger('error', _this4, err);\n Backbone.history.trigger('error', _this4, err);\n throw err;\n });\n },\n\n /**\n * @public\n * @method execute\n * @param {Function} callback\n * @param {Array} [args]\n * @returns {Promise}\n */\n _execute: function _execute(callback, args) {\n var _this5 = this;\n\n return Promise.resolve().then(function () {\n if (Router._prevRoute instanceof Route) {\n return Router._prevRoute.exit();\n }\n }).then(function () {\n var route = Router._prevRoute = callback.apply(_this5, args);\n if (route instanceof Route) {\n route.router = _this5;\n return route.enter(args);\n }\n });\n },\n\n /**\n * @private\n * @method _onHistoryRoute\n * @param {Router} router\n */\n _onHistoryRoute: function _onHistoryRoute(router) {\n this._isActive = router === this;\n }\n }, {\n\n /**\n * @private\n * @member _prevRoute\n */\n _prevRoute: null\n });\n\n var backbone_routing = { Route: Route, Router: Router, CancellationError: CancellationError };\n\n return backbone_routing;\n});\n\n},{\"backbone\":18,\"backbone-metal\":2}],5:[function(require,module,exports){\n// Backbone.Validation v0.11.5\n//\n// Copyright (c) 2011-2015 Thomas Pedersen\n// Distributed under MIT License\n//\n// Documentation and full license available at:\n// http://thedersen.com/projects/backbone-validation\n(function (factory) {\n if (typeof exports === 'object') {\n module.exports = factory(require('backbone'), require('underscore'));\n } else if (typeof define === 'function' && define.amd) {\n define(['backbone', 'underscore'], factory);\n }\n}(function (Backbone, _) {\n Backbone.Validation = (function(_){\n 'use strict';\n \n // Default options\n // ---------------\n \n var defaultOptions = {\n forceUpdate: false,\n selector: 'name',\n labelFormatter: 'sentenceCase',\n valid: Function.prototype,\n invalid: Function.prototype\n };\n \n \n // Helper functions\n // ----------------\n \n // Formatting functions used for formatting error messages\n var formatFunctions = {\n // Uses the configured label formatter to format the attribute name\n // to make it more readable for the user\n formatLabel: function(attrName, model) {\n return defaultLabelFormatters[defaultOptions.labelFormatter](attrName, model);\n },\n \n // Replaces nummeric placeholders like {0} in a string with arguments\n // passed to the function\n format: function() {\n var args = Array.prototype.slice.call(arguments),\n text = args.shift();\n return text.replace(/\\{(\\d+)\\}/g, function(match, number) {\n return typeof args[number] !== 'undefined' ? args[number] : match;\n });\n }\n };\n \n // Flattens an object\n // eg:\n //\n // var o = {\n // owner: {\n // name: 'Backbone',\n // address: {\n // street: 'Street',\n // zip: 1234\n // }\n // }\n // };\n //\n // becomes:\n //\n // var o = {\n // 'owner': {\n // name: 'Backbone',\n // address: {\n // street: 'Street',\n // zip: 1234\n // }\n // },\n // 'owner.name': 'Backbone',\n // 'owner.address': {\n // street: 'Street',\n // zip: 1234\n // },\n // 'owner.address.street': 'Street',\n // 'owner.address.zip': 1234\n // };\n // This may seem redundant, but it allows for maximum flexibility\n // in validation rules.\n var flatten = function (obj, into, prefix) {\n into = into || {};\n prefix = prefix || '';\n \n _.each(obj, function(val, key) {\n if(obj.hasOwnProperty(key)) {\n if (!!val && _.isArray(val)) {\n _.forEach(val, function(v, k) {\n flatten(v, into, prefix + key + '.' + k + '.');\n into[prefix + key + '.' + k] = v;\n });\n } else if (!!val && typeof val === 'object' && val.constructor === Object) {\n flatten(val, into, prefix + key + '.');\n }\n \n // Register the current level object as well\n into[prefix + key] = val;\n }\n });\n \n return into;\n };\n \n // Validation\n // ----------\n \n var Validation = (function(){\n \n // Returns an object with undefined properties for all\n // attributes on the model that has defined one or more\n // validation rules.\n var getValidatedAttrs = function(model, attrs) {\n attrs = attrs || _.keys(_.result(model, 'validation') || {});\n return _.reduce(attrs, function(memo, key) {\n memo[key] = void 0;\n return memo;\n }, {});\n };\n \n // Returns an array with attributes passed through options\n var getOptionsAttrs = function(options, view) {\n var attrs = options.attributes;\n if (_.isFunction(attrs)) {\n attrs = attrs(view);\n } else if (_.isString(attrs) && (_.isFunction(defaultAttributeLoaders[attrs]))) {\n attrs = defaultAttributeLoaders[attrs](view);\n }\n if (_.isArray(attrs)) {\n return attrs;\n }\n };\n \n \n // Looks on the model for validations for a specified\n // attribute. Returns an array of any validators defined,\n // or an empty array if none is defined.\n var getValidators = function(model, attr) {\n var attrValidationSet = model.validation ? _.result(model, 'validation')[attr] || {} : {};\n \n // If the validator is a function or a string, wrap it in a function validator\n if (_.isFunction(attrValidationSet) || _.isString(attrValidationSet)) {\n attrValidationSet = {\n fn: attrValidationSet\n };\n }\n \n // Stick the validator object into an array\n if(!_.isArray(attrValidationSet)) {\n attrValidationSet = [attrValidationSet];\n }\n \n // Reduces the array of validators into a new array with objects\n // with a validation method to call, the value to validate against\n // and the specified error message, if any\n return _.reduce(attrValidationSet, function(memo, attrValidation) {\n _.each(_.without(_.keys(attrValidation), 'msg'), function(validator) {\n memo.push({\n fn: defaultValidators[validator],\n val: attrValidation[validator],\n msg: attrValidation.msg\n });\n });\n return memo;\n }, []);\n };\n \n // Validates an attribute against all validators defined\n // for that attribute. If one or more errors are found,\n // the first error message is returned.\n // If the attribute is valid, an empty string is returned.\n var validateAttr = function(model, attr, value, computed) {\n // Reduces the array of validators to an error message by\n // applying all the validators and returning the first error\n // message, if any.\n return _.reduce(getValidators(model, attr), function(memo, validator){\n // Pass the format functions plus the default\n // validators as the context to the validator\n var ctx = _.extend({}, formatFunctions, defaultValidators),\n result = validator.fn.call(ctx, value, attr, validator.val, model, computed);\n \n if(result === false || memo === false) {\n return false;\n }\n if (result && !memo) {\n return _.result(validator, 'msg') || result;\n }\n return memo;\n }, '');\n };\n \n // Loops through the model's attributes and validates the specified attrs.\n // Returns and object containing names of invalid attributes\n // as well as error messages.\n var validateModel = function(model, attrs, validatedAttrs) {\n var error,\n invalidAttrs = {},\n isValid = true,\n computed = _.clone(attrs);\n \n _.each(validatedAttrs, function(val, attr) {\n error = validateAttr(model, attr, val, computed);\n if (error) {\n invalidAttrs[attr] = error;\n isValid = false;\n }\n });\n \n return {\n invalidAttrs: invalidAttrs,\n isValid: isValid\n };\n };\n \n // Contains the methods that are mixed in on the model when binding\n var mixin = function(view, options) {\n return {\n \n // Check whether or not a value, or a hash of values\n // passes validation without updating the model\n preValidate: function(attr, value) {\n var self = this,\n result = {},\n error;\n \n if(_.isObject(attr)){\n _.each(attr, function(value, key) {\n error = self.preValidate(key, value);\n if(error){\n result[key] = error;\n }\n });\n \n return _.isEmpty(result) ? undefined : result;\n }\n else {\n return validateAttr(this, attr, value, _.extend({}, this.attributes));\n }\n },\n \n // Check to see if an attribute, an array of attributes or the\n // entire model is valid. Passing true will force a validation\n // of the model.\n isValid: function(option) {\n var flattened, attrs, error, invalidAttrs;\n \n option = option || getOptionsAttrs(options, view);\n \n if(_.isString(option)){\n attrs = [option];\n } else if(_.isArray(option)) {\n attrs = option;\n }\n if (attrs) {\n flattened = flatten(this.attributes);\n //Loop through all associated views\n _.each(this.associatedViews, function(view) {\n _.each(attrs, function (attr) {\n error = validateAttr(this, attr, flattened[attr], _.extend({}, this.attributes));\n if (error) {\n options.invalid(view, attr, error, options.selector);\n invalidAttrs = invalidAttrs || {};\n invalidAttrs[attr] = error;\n } else {\n options.valid(view, attr, options.selector);\n }\n }, this);\n }, this);\n }\n \n if(option === true) {\n invalidAttrs = this.validate();\n }\n if (invalidAttrs) {\n this.trigger('invalid', this, invalidAttrs, {validationError: invalidAttrs});\n }\n return attrs ? !invalidAttrs : this.validation ? this._isValid : true;\n },\n \n // This is called by Backbone when it needs to perform validation.\n // You can call it manually without any parameters to validate the\n // entire model.\n validate: function(attrs, setOptions){\n var model = this,\n validateAll = !attrs,\n opt = _.extend({}, options, setOptions),\n validatedAttrs = getValidatedAttrs(model, getOptionsAttrs(options, view)),\n allAttrs = _.extend({}, validatedAttrs, model.attributes, attrs),\n flattened = flatten(allAttrs),\n changedAttrs = attrs ? flatten(attrs) : flattened,\n result = validateModel(model, allAttrs, _.pick(flattened, _.keys(validatedAttrs)));\n \n model._isValid = result.isValid;\n \n //After validation is performed, loop through all associated views\n _.each(model.associatedViews, function(view){\n \n // After validation is performed, loop through all validated and changed attributes\n // and call the valid and invalid callbacks so the view is updated.\n _.each(validatedAttrs, function(val, attr){\n var invalid = result.invalidAttrs.hasOwnProperty(attr),\n changed = changedAttrs.hasOwnProperty(attr);\n \n if(!invalid){\n opt.valid(view, attr, opt.selector);\n }\n if(invalid && (changed || validateAll)){\n opt.invalid(view, attr, result.invalidAttrs[attr], opt.selector);\n }\n });\n });\n \n // Trigger validated events.\n // Need to defer this so the model is actually updated before\n // the event is triggered.\n _.defer(function() {\n model.trigger('validated', model._isValid, model, result.invalidAttrs);\n model.trigger('validated:' + (model._isValid ? 'valid' : 'invalid'), model, result.invalidAttrs);\n });\n \n // Return any error messages to Backbone, unless the forceUpdate flag is set.\n // Then we do not return anything and fools Backbone to believe the validation was\n // a success. That way Backbone will update the model regardless.\n if (!opt.forceUpdate && _.intersection(_.keys(result.invalidAttrs), _.keys(changedAttrs)).length > 0) {\n return result.invalidAttrs;\n }\n }\n };\n };\n \n // Helper to mix in validation on a model. Stores the view in the associated views array.\n var bindModel = function(view, model, options) {\n if (model.associatedViews) {\n model.associatedViews.push(view);\n } else {\n model.associatedViews = [view];\n }\n _.extend(model, mixin(view, options));\n };\n \n // Removes view from associated views of the model or the methods\n // added to a model if no view or single view provided\n var unbindModel = function(model, view) {\n if (view && model.associatedViews && model.associatedViews.length > 1){\n model.associatedViews = _.without(model.associatedViews, view);\n } else {\n delete model.validate;\n delete model.preValidate;\n delete model.isValid;\n delete model.associatedViews;\n }\n };\n \n // Mix in validation on a model whenever a model is\n // added to a collection\n var collectionAdd = function(model) {\n bindModel(this.view, model, this.options);\n };\n \n // Remove validation from a model whenever a model is\n // removed from a collection\n var collectionRemove = function(model) {\n unbindModel(model);\n };\n \n // Returns the public methods on Backbone.Validation\n return {\n \n // Current version of the library\n version: '0.11.3',\n \n // Called to configure the default options\n configure: function(options) {\n _.extend(defaultOptions, options);\n },\n \n // Hooks up validation on a view with a model\n // or collection\n bind: function(view, options) {\n options = _.extend({}, defaultOptions, defaultCallbacks, options);\n \n var model = options.model || view.model,\n collection = options.collection || view.collection;\n \n if(typeof model === 'undefined' && typeof collection === 'undefined'){\n throw 'Before you execute the binding your view must have a model or a collection.\\n' +\n 'See http://thedersen.com/projects/backbone-validation/#using-form-model-validation for more information.';\n }\n \n if(model) {\n bindModel(view, model, options);\n }\n else if(collection) {\n collection.each(function(model){\n bindModel(view, model, options);\n });\n collection.bind('add', collectionAdd, {view: view, options: options});\n collection.bind('remove', collectionRemove);\n }\n },\n \n // Removes validation from a view with a model\n // or collection\n unbind: function(view, options) {\n options = _.extend({}, options);\n var model = options.model || view.model,\n collection = options.collection || view.collection;\n \n if(model) {\n unbindModel(model, view);\n }\n else if(collection) {\n collection.each(function(model){\n unbindModel(model, view);\n });\n collection.unbind('add', collectionAdd);\n collection.unbind('remove', collectionRemove);\n }\n },\n \n // Used to extend the Backbone.Model.prototype\n // with validation\n mixin: mixin(null, defaultOptions)\n };\n }());\n \n \n // Callbacks\n // ---------\n \n var defaultCallbacks = Validation.callbacks = {\n \n // Gets called when a previously invalid field in the\n // view becomes valid. Removes any error message.\n // Should be overridden with custom functionality.\n valid: function(view, attr, selector) {\n view.$('[' + selector + '~=\"' + attr + '\"]')\n .removeClass('invalid')\n .removeAttr('data-error');\n },\n \n // Gets called when a field in the view becomes invalid.\n // Adds a error message.\n // Should be overridden with custom functionality.\n invalid: function(view, attr, error, selector) {\n view.$('[' + selector + '~=\"' + attr + '\"]')\n .addClass('invalid')\n .attr('data-error', error);\n }\n };\n \n \n // Patterns\n // --------\n \n var defaultPatterns = Validation.patterns = {\n // Matches any digit(s) (i.e. 0-9)\n digits: /^\\d+$/,\n \n // Matches any number (e.g. 100.000)\n number: /^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)(?:\\.\\d+)?$/,\n \n // Matches a valid email address (e.g. mail@example.com)\n email: /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i,\n \n // Mathes any valid url (e.g. http://www.xample.com)\n url: /^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i\n };\n \n \n // Error messages\n // --------------\n \n // Error message for the build in validators.\n // {x} gets swapped out with arguments form the validator.\n var defaultMessages = Validation.messages = {\n required: '{0} is required',\n acceptance: '{0} must be accepted',\n min: '{0} must be greater than or equal to {1}',\n max: '{0} must be less than or equal to {1}',\n range: '{0} must be between {1} and {2}',\n length: '{0} must be {1} characters',\n minLength: '{0} must be at least {1} characters',\n maxLength: '{0} must be at most {1} characters',\n rangeLength: '{0} must be between {1} and {2} characters',\n oneOf: '{0} must be one of: {1}',\n equalTo: '{0} must be the same as {1}',\n digits: '{0} must only contain digits',\n number: '{0} must be a number',\n email: '{0} must be a valid email',\n url: '{0} must be a valid url',\n inlinePattern: '{0} is invalid'\n };\n \n // Label formatters\n // ----------------\n \n // Label formatters are used to convert the attribute name\n // to a more human friendly label when using the built in\n // error messages.\n // Configure which one to use with a call to\n //\n // Backbone.Validation.configure({\n // labelFormatter: 'label'\n // });\n var defaultLabelFormatters = Validation.labelFormatters = {\n \n // Returns the attribute name with applying any formatting\n none: function(attrName) {\n return attrName;\n },\n \n // Converts attributeName or attribute_name to Attribute name\n sentenceCase: function(attrName) {\n return attrName.replace(/(?:^\\w|[A-Z]|\\b\\w)/g, function(match, index) {\n return index === 0 ? match.toUpperCase() : ' ' + match.toLowerCase();\n }).replace(/_/g, ' ');\n },\n \n // Looks for a label configured on the model and returns it\n //\n // var Model = Backbone.Model.extend({\n // validation: {\n // someAttribute: {\n // required: true\n // }\n // },\n //\n // labels: {\n // someAttribute: 'Custom label'\n // }\n // });\n label: function(attrName, model) {\n return (model.labels && model.labels[attrName]) || defaultLabelFormatters.sentenceCase(attrName, model);\n }\n };\n \n // AttributeLoaders\n \n var defaultAttributeLoaders = Validation.attributeLoaders = {\n inputNames: function (view) {\n var attrs = [];\n if (view) {\n view.$('form [name]').each(function () {\n if (/^(?:input|select|textarea)$/i.test(this.nodeName) && this.name &&\n this.type !== 'submit' && attrs.indexOf(this.name) === -1) {\n attrs.push(this.name);\n }\n });\n }\n return attrs;\n }\n };\n \n \n // Built in validators\n // -------------------\n \n var defaultValidators = Validation.validators = (function(){\n // Use native trim when defined\n var trim = String.prototype.trim ?\n function(text) {\n return text === null ? '' : String.prototype.trim.call(text);\n } :\n function(text) {\n var trimLeft = /^\\s+/,\n trimRight = /\\s+$/;\n \n return text === null ? '' : text.toString().replace(trimLeft, '').replace(trimRight, '');\n };\n \n // Determines whether or not a value is a number\n var isNumber = function(value){\n return _.isNumber(value) || (_.isString(value) && value.match(defaultPatterns.number));\n };\n \n // Determines whether or not a value is empty\n var hasValue = function(value) {\n return !(_.isNull(value) || _.isUndefined(value) || (_.isString(value) && trim(value) === '') || (_.isArray(value) && _.isEmpty(value)));\n };\n \n return {\n // Function validator\n // Lets you implement a custom function used for validation\n fn: function(value, attr, fn, model, computed) {\n if(_.isString(fn)){\n fn = model[fn];\n }\n return fn.call(model, value, attr, computed);\n },\n \n // Required validator\n // Validates if the attribute is required or not\n // This can be specified as either a boolean value or a function that returns a boolean value\n required: function(value, attr, required, model, computed) {\n var isRequired = _.isFunction(required) ? required.call(model, value, attr, computed) : required;\n if(!isRequired && !hasValue(value)) {\n return false; // overrides all other validators\n }\n if (isRequired && !hasValue(value)) {\n return this.format(defaultMessages.required, this.formatLabel(attr, model));\n }\n },\n \n // Acceptance validator\n // Validates that something has to be accepted, e.g. terms of use\n // `true` or 'true' are valid\n acceptance: function(value, attr, accept, model) {\n if(value !== 'true' && (!_.isBoolean(value) || value === false)) {\n return this.format(defaultMessages.acceptance, this.formatLabel(attr, model));\n }\n },\n \n // Min validator\n // Validates that the value has to be a number and equal to or greater than\n // the min value specified\n min: function(value, attr, minValue, model) {\n if (!isNumber(value) || value < minValue) {\n return this.format(defaultMessages.min, this.formatLabel(attr, model), minValue);\n }\n },\n \n // Max validator\n // Validates that the value has to be a number and equal to or less than\n // the max value specified\n max: function(value, attr, maxValue, model) {\n if (!isNumber(value) || value > maxValue) {\n return this.format(defaultMessages.max, this.formatLabel(attr, model), maxValue);\n }\n },\n \n // Range validator\n // Validates that the value has to be a number and equal to or between\n // the two numbers specified\n range: function(value, attr, range, model) {\n if(!isNumber(value) || value < range[0] || value > range[1]) {\n return this.format(defaultMessages.range, this.formatLabel(attr, model), range[0], range[1]);\n }\n },\n \n // Length validator\n // Validates that the value has to be a string with length equal to\n // the length value specified\n length: function(value, attr, length, model) {\n if (!_.isString(value) || value.length !== length) {\n return this.format(defaultMessages.length, this.formatLabel(attr, model), length);\n }\n },\n \n // Min length validator\n // Validates that the value has to be a string with length equal to or greater than\n // the min length value specified\n minLength: function(value, attr, minLength, model) {\n if (!_.isString(value) || value.length < minLength) {\n return this.format(defaultMessages.minLength, this.formatLabel(attr, model), minLength);\n }\n },\n \n // Max length validator\n // Validates that the value has to be a string with length equal to or less than\n // the max length value specified\n maxLength: function(value, attr, maxLength, model) {\n if (!_.isString(value) || value.length > maxLength) {\n return this.format(defaultMessages.maxLength, this.formatLabel(attr, model), maxLength);\n }\n },\n \n // Range length validator\n // Validates that the value has to be a string and equal to or between\n // the two numbers specified\n rangeLength: function(value, attr, range, model) {\n if (!_.isString(value) || value.length < range[0] || value.length > range[1]) {\n return this.format(defaultMessages.rangeLength, this.formatLabel(attr, model), range[0], range[1]);\n }\n },\n \n // One of validator\n // Validates that the value has to be equal to one of the elements in\n // the specified array. Case sensitive matching\n oneOf: function(value, attr, values, model) {\n if(!_.include(values, value)){\n return this.format(defaultMessages.oneOf, this.formatLabel(attr, model), values.join(', '));\n }\n },\n \n // Equal to validator\n // Validates that the value has to be equal to the value of the attribute\n // with the name specified\n equalTo: function(value, attr, equalTo, model, computed) {\n if(value !== computed[equalTo]) {\n return this.format(defaultMessages.equalTo, this.formatLabel(attr, model), this.formatLabel(equalTo, model));\n }\n },\n \n // Pattern validator\n // Validates that the value has to match the pattern specified.\n // Can be a regular expression or the name of one of the built in patterns\n pattern: function(value, attr, pattern, model) {\n if (!hasValue(value) || !value.toString().match(defaultPatterns[pattern] || pattern)) {\n return this.format(defaultMessages[pattern] || defaultMessages.inlinePattern, this.formatLabel(attr, model), pattern);\n }\n }\n };\n }());\n \n // Set the correct context for all validators\n // when used from within a method validator\n _.each(defaultValidators, function(validator, key){\n defaultValidators[key] = _.bind(defaultValidators[key], _.extend({}, formatFunctions, defaultValidators));\n });\n \n return Validation;\n }(_));\n return Backbone.Validation;\n}));\n},{\"backbone\":18,\"underscore\":34}],6:[function(require,module,exports){\n// Backbone.BabySitter\n// -------------------\n// v0.1.10\n//\n// Copyright (c)2015 Derick Bailey, Muted Solutions, LLC.\n// Distributed under MIT license\n//\n// http://github.com/marionettejs/backbone.babysitter\n\n(function(root, factory) {\n\n if (typeof define === 'function' && define.amd) {\n define(['backbone', 'underscore'], function(Backbone, _) {\n return factory(Backbone, _);\n });\n } else if (typeof exports !== 'undefined') {\n var Backbone = require('backbone');\n var _ = require('underscore');\n module.exports = factory(Backbone, _);\n } else {\n factory(root.Backbone, root._);\n }\n\n}(this, function(Backbone, _) {\n 'use strict';\n\n var previousChildViewContainer = Backbone.ChildViewContainer;\n\n // BabySitter.ChildViewContainer\n // -----------------------------\n //\n // Provide a container to store, retrieve and\n // shut down child views.\n \n Backbone.ChildViewContainer = (function (Backbone, _) {\n \n // Container Constructor\n // ---------------------\n \n var Container = function(views){\n this._views = {};\n this._indexByModel = {};\n this._indexByCustom = {};\n this._updateLength();\n \n _.each(views, this.add, this);\n };\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: function(view, customIndex){\n var 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 this._updateLength();\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: function(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: function(modelCid){\n var viewCid = this._indexByModel[modelCid];\n return this.findByCid(viewCid);\n },\n \n // Find a view by a custom indexer.\n findByCustom: function(index){\n var 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: function(index){\n return _.values(this._views)[index];\n },\n \n // retrieve a view by its `cid` directly\n findByCid: function(cid){\n return this._views[cid];\n },\n \n // Remove a view\n remove: function(view){\n var 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 _.any(this._indexByCustom, 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 // update the length\n this._updateLength();\n return this;\n },\n \n // Call a method on every view in the container,\n // passing parameters to the call method one at a\n // time, like `function.call`.\n call: function(method){\n this.apply(method, _.tail(arguments));\n },\n \n // Apply a method on every view in the container,\n // passing parameters to the call method one at a\n // time, like `function.apply`.\n apply: function(method, args){\n _.each(this._views, function(view){\n if (_.isFunction(view[method])){\n view[method].apply(view, args || []);\n }\n });\n },\n \n // Update the `.length` attribute on this container\n _updateLength: function(){\n this.length = _.size(this._views);\n }\n });\n \n // Borrowing this code from Backbone.Collection:\n // http://backbonejs.org/docs/backbone.html#section-106\n //\n // Mix in methods from Underscore, for iteration, and other\n // collection related features.\n var 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 \n _.each(methods, function(method) {\n Container.prototype[method] = function() {\n var views = _.values(this._views);\n var args = [views].concat(_.toArray(arguments));\n return _[method].apply(_, args);\n };\n });\n \n // return the public API\n return Container;\n })(Backbone, _);\n \n\n Backbone.ChildViewContainer.VERSION = '0.1.10';\n\n Backbone.ChildViewContainer.noConflict = function () {\n Backbone.ChildViewContainer = previousChildViewContainer;\n return this;\n };\n\n return Backbone.ChildViewContainer;\n\n}));\n\n},{\"backbone\":18,\"underscore\":34}],7:[function(require,module,exports){\n// (c) 2012 Onsi Fakhouri\n// Cocktail.js may be freely distributed under the MIT license.\n// http://github.com/onsi/cocktail\n(function(factory) {\n if (typeof require === 'function' && typeof module !== 'undefined' && module.exports) {\n module.exports = factory(require('underscore'));\n } else if (typeof define === 'function') {\n define(['underscore'], factory);\n } else {\n this.Cocktail = factory(_);\n }\n}(function (_) {\n\n var Cocktail = {};\n\n Cocktail.mixins = {};\n\n Cocktail.mixin = function mixin(klass) {\n var mixins = _.chain(arguments).toArray().rest().flatten().value();\n // Allows mixing into the constructor's prototype or the dynamic instance\n var obj = klass.prototype || klass;\n\n var collisions = {};\n\n _.each(mixins, function(mixin) {\n if (_.isString(mixin)) {\n mixin = Cocktail.mixins[mixin];\n }\n _.each(mixin, function(value, key) {\n if (_.isFunction(value)) {\n // If the mixer already has that exact function reference\n // Note: this would occur on an accidental mixin of the same base\n if (obj[key] === value) return;\n\n if (obj[key]) {\n // Avoid accessing built-in properties like constructor (#39)\n collisions[key] = collisions.hasOwnProperty(key) ? collisions[key] : [obj[key]];\n collisions[key].push(value);\n }\n obj[key] = value;\n } else if (_.isArray(value)) {\n obj[key] = _.union(value, obj[key] || []);\n } else if (_.isObject(value)) {\n obj[key] = _.extend({}, value, obj[key] || {});\n } else if (!(key in obj)) {\n obj[key] = value;\n }\n });\n });\n\n _.each(collisions, function(propertyValues, propertyName) {\n obj[propertyName] = function() {\n var that = this,\n args = arguments,\n returnValue;\n\n _.each(propertyValues, function(value) {\n var returnedValue = _.isFunction(value) ? value.apply(that, args) : value;\n returnValue = (typeof returnedValue === 'undefined' ? returnValue : returnedValue);\n });\n\n return returnValue;\n };\n });\n\n return klass;\n };\n\n var originalExtend;\n\n Cocktail.patch = function patch(Backbone) {\n originalExtend = Backbone.Model.extend;\n\n var extend = function(protoProps, classProps) {\n var klass = originalExtend.call(this, protoProps, classProps);\n\n var mixins = klass.prototype.mixins;\n if (mixins && klass.prototype.hasOwnProperty('mixins')) {\n Cocktail.mixin(klass, mixins);\n }\n\n return klass;\n };\n\n _.each([Backbone.Model, Backbone.Collection, Backbone.Router, Backbone.View], function(klass) {\n klass.mixin = function mixin() {\n Cocktail.mixin(this, _.toArray(arguments));\n };\n\n klass.extend = extend;\n });\n };\n\n Cocktail.unpatch = function unpatch(Backbone) {\n _.each([Backbone.Model, Backbone.Collection, Backbone.Router, Backbone.View], function(klass) {\n klass.mixin = undefined;\n klass.extend = originalExtend;\n });\n };\n\n return Cocktail;\n}));\n\n},{\"underscore\":8}],8:[function(require,module,exports){\n// Underscore.js 1.5.2\n// http://underscorejs.org\n// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n// Underscore may be freely distributed under the MIT license.\n\n(function() {\n\n // Baseline setup\n // --------------\n\n // Establish the root object, `window` in the browser, or `exports` on the server.\n var root = this;\n\n // Save the previous value of the `_` variable.\n var previousUnderscore = root._;\n\n // Establish the object that gets returned to break out of a loop iteration.\n var breaker = {};\n\n // Save bytes in the minified (but not gzipped) version:\n var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;\n\n // Create quick reference variables for speed access to core prototypes.\n var\n push = ArrayProto.push,\n slice = ArrayProto.slice,\n concat = ArrayProto.concat,\n toString = ObjProto.toString,\n hasOwnProperty = ObjProto.hasOwnProperty;\n\n // All **ECMAScript 5** native function implementations that we hope to use\n // are declared here.\n var\n nativeForEach = ArrayProto.forEach,\n nativeMap = ArrayProto.map,\n nativeReduce = ArrayProto.reduce,\n nativeReduceRight = ArrayProto.reduceRight,\n nativeFilter = ArrayProto.filter,\n nativeEvery = ArrayProto.every,\n nativeSome = ArrayProto.some,\n nativeIndexOf = ArrayProto.indexOf,\n nativeLastIndexOf = ArrayProto.lastIndexOf,\n nativeIsArray = Array.isArray,\n nativeKeys = Object.keys,\n nativeBind = FuncProto.bind;\n\n // Create a safe reference to the Underscore object for use below.\n var _ = function(obj) {\n if (obj instanceof _) return obj;\n if (!(this instanceof _)) return new _(obj);\n this._wrapped = obj;\n };\n\n // Export the Underscore object for **Node.js**, with\n // backwards-compatibility for the old `require()` API. If we're in\n // the browser, add `_` as a global object via a string identifier,\n // for Closure Compiler \"advanced\" mode.\n if (typeof exports !== 'undefined') {\n if (typeof module !== 'undefined' && module.exports) {\n exports = module.exports = _;\n }\n exports._ = _;\n } else {\n root._ = _;\n }\n\n // Current version.\n _.VERSION = '1.5.2';\n\n // Collection Functions\n // --------------------\n\n // The cornerstone, an `each` implementation, aka `forEach`.\n // Handles objects with the built-in `forEach`, arrays, and raw objects.\n // Delegates to **ECMAScript 5**'s native `forEach` if available.\n var each = _.each = _.forEach = function(obj, iterator, context) {\n if (obj == null) return;\n if (nativeForEach && obj.forEach === nativeForEach) {\n obj.forEach(iterator, context);\n } else if (obj.length === +obj.length) {\n for (var i = 0, length = obj.length; i < length; i++) {\n if (iterator.call(context, obj[i], i, obj) === breaker) return;\n }\n } else {\n var keys = _.keys(obj);\n for (var i = 0, length = keys.length; i < length; i++) {\n if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;\n }\n }\n };\n\n // Return the results of applying the iterator to each element.\n // Delegates to **ECMAScript 5**'s native `map` if available.\n _.map = _.collect = function(obj, iterator, context) {\n var results = [];\n if (obj == null) return results;\n if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);\n each(obj, function(value, index, list) {\n results.push(iterator.call(context, value, index, list));\n });\n return results;\n };\n\n var reduceError = 'Reduce of empty array with no initial value';\n\n // **Reduce** builds up a single result from a list of values, aka `inject`,\n // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.\n _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {\n var initial = arguments.length > 2;\n if (obj == null) obj = [];\n if (nativeReduce && obj.reduce === nativeReduce) {\n if (context) iterator = _.bind(iterator, context);\n return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);\n }\n each(obj, function(value, index, list) {\n if (!initial) {\n memo = value;\n initial = true;\n } else {\n memo = iterator.call(context, memo, value, index, list);\n }\n });\n if (!initial) throw new TypeError(reduceError);\n return memo;\n };\n\n // The right-associative version of reduce, also known as `foldr`.\n // Delegates to **ECMAScript 5**'s native `reduceRight` if available.\n _.reduceRight = _.foldr = function(obj, iterator, memo, context) {\n var initial = arguments.length > 2;\n if (obj == null) obj = [];\n if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {\n if (context) iterator = _.bind(iterator, context);\n return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);\n }\n var length = obj.length;\n if (length !== +length) {\n var keys = _.keys(obj);\n length = keys.length;\n }\n each(obj, function(value, index, list) {\n index = keys ? keys[--length] : --length;\n if (!initial) {\n memo = obj[index];\n initial = true;\n } else {\n memo = iterator.call(context, memo, obj[index], index, list);\n }\n });\n if (!initial) throw new TypeError(reduceError);\n return memo;\n };\n\n // Return the first value which passes a truth test. Aliased as `detect`.\n _.find = _.detect = function(obj, iterator, context) {\n var result;\n any(obj, function(value, index, list) {\n if (iterator.call(context, value, index, list)) {\n result = value;\n return true;\n }\n });\n return result;\n };\n\n // Return all the elements that pass a truth test.\n // Delegates to **ECMAScript 5**'s native `filter` if available.\n // Aliased as `select`.\n _.filter = _.select = function(obj, iterator, context) {\n var results = [];\n if (obj == null) return results;\n if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);\n each(obj, function(value, index, list) {\n if (iterator.call(context, value, index, list)) results.push(value);\n });\n return results;\n };\n\n // Return all the elements for which a truth test fails.\n _.reject = function(obj, iterator, context) {\n return _.filter(obj, function(value, index, list) {\n return !iterator.call(context, value, index, list);\n }, context);\n };\n\n // Determine whether all of the elements match a truth test.\n // Delegates to **ECMAScript 5**'s native `every` if available.\n // Aliased as `all`.\n _.every = _.all = function(obj, iterator, context) {\n iterator || (iterator = _.identity);\n var result = true;\n if (obj == null) return result;\n if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);\n each(obj, function(value, index, list) {\n if (!(result = result && iterator.call(context, value, index, list))) return breaker;\n });\n return !!result;\n };\n\n // Determine if at least one element in the object matches a truth test.\n // Delegates to **ECMAScript 5**'s native `some` if available.\n // Aliased as `any`.\n var any = _.some = _.any = function(obj, iterator, context) {\n iterator || (iterator = _.identity);\n var result = false;\n if (obj == null) return result;\n if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);\n each(obj, function(value, index, list) {\n if (result || (result = iterator.call(context, value, index, list))) return breaker;\n });\n return !!result;\n };\n\n // Determine if the array or object contains a given value (using `===`).\n // Aliased as `include`.\n _.contains = _.include = function(obj, target) {\n if (obj == null) return false;\n if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;\n return any(obj, function(value) {\n return value === target;\n });\n };\n\n // Invoke a method (with arguments) on every item in a collection.\n _.invoke = function(obj, method) {\n var args = slice.call(arguments, 2);\n var isFunc = _.isFunction(method);\n return _.map(obj, function(value) {\n return (isFunc ? method : value[method]).apply(value, args);\n });\n };\n\n // Convenience version of a common use case of `map`: fetching a property.\n _.pluck = function(obj, key) {\n return _.map(obj, function(value){ return value[key]; });\n };\n\n // Convenience version of a common use case of `filter`: selecting only objects\n // containing specific `key:value` pairs.\n _.where = function(obj, attrs, first) {\n if (_.isEmpty(attrs)) return first ? void 0 : [];\n return _[first ? 'find' : 'filter'](obj, function(value) {\n for (var key in attrs) {\n if (attrs[key] !== value[key]) return false;\n }\n return true;\n });\n };\n\n // Convenience version of a common use case of `find`: getting the first object\n // containing specific `key:value` pairs.\n _.findWhere = function(obj, attrs) {\n return _.where(obj, attrs, true);\n };\n\n // Return the maximum element or (element-based computation).\n // Can't optimize arrays of integers longer than 65,535 elements.\n // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)\n _.max = function(obj, iterator, context) {\n if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {\n return Math.max.apply(Math, obj);\n }\n if (!iterator && _.isEmpty(obj)) return -Infinity;\n var result = {computed : -Infinity, value: -Infinity};\n each(obj, function(value, index, list) {\n var computed = iterator ? iterator.call(context, value, index, list) : value;\n computed > result.computed && (result = {value : value, computed : computed});\n });\n return result.value;\n };\n\n // Return the minimum element (or element-based computation).\n _.min = function(obj, iterator, context) {\n if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {\n return Math.min.apply(Math, obj);\n }\n if (!iterator && _.isEmpty(obj)) return Infinity;\n var result = {computed : Infinity, value: Infinity};\n each(obj, function(value, index, list) {\n var computed = iterator ? iterator.call(context, value, index, list) : value;\n computed < result.computed && (result = {value : value, computed : computed});\n });\n return result.value;\n };\n\n // Shuffle an array, using the modern version of the \n // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).\n _.shuffle = function(obj) {\n var rand;\n var index = 0;\n var shuffled = [];\n each(obj, function(value) {\n rand = _.random(index++);\n shuffled[index - 1] = shuffled[rand];\n shuffled[rand] = value;\n });\n return shuffled;\n };\n\n // Sample **n** random values from an array.\n // If **n** is not specified, returns a single random element from the array.\n // The internal `guard` argument allows it to work with `map`.\n _.sample = function(obj, n, guard) {\n if (arguments.length < 2 || guard) {\n return obj[_.random(obj.length - 1)];\n }\n return _.shuffle(obj).slice(0, Math.max(0, n));\n };\n\n // An internal function to generate lookup iterators.\n var lookupIterator = function(value) {\n return _.isFunction(value) ? value : function(obj){ return obj[value]; };\n };\n\n // Sort the object's values by a criterion produced by an iterator.\n _.sortBy = function(obj, value, context) {\n var iterator = lookupIterator(value);\n return _.pluck(_.map(obj, function(value, index, list) {\n return {\n value: value,\n index: index,\n criteria: iterator.call(context, value, index, list)\n };\n }).sort(function(left, right) {\n var a = left.criteria;\n var b = right.criteria;\n if (a !== b) {\n if (a > b || a === void 0) return 1;\n if (a < b || b === void 0) return -1;\n }\n return left.index - right.index;\n }), 'value');\n };\n\n // An internal function used for aggregate \"group by\" operations.\n var group = function(behavior) {\n return function(obj, value, context) {\n var result = {};\n var iterator = value == null ? _.identity : lookupIterator(value);\n each(obj, function(value, index) {\n var key = iterator.call(context, value, index, obj);\n behavior(result, key, value);\n });\n return result;\n };\n };\n\n // Groups the object's values by a criterion. Pass either a string attribute\n // to group by, or a function that returns the criterion.\n _.groupBy = group(function(result, key, value) {\n (_.has(result, key) ? result[key] : (result[key] = [])).push(value);\n });\n\n // Indexes the object's values by a criterion, similar to `groupBy`, but for\n // when you know that your index values will be unique.\n _.indexBy = group(function(result, key, value) {\n result[key] = value;\n });\n\n // Counts instances of an object that group by a certain criterion. Pass\n // either a string attribute to count by, or a function that returns the\n // criterion.\n _.countBy = group(function(result, key) {\n _.has(result, key) ? result[key]++ : result[key] = 1;\n });\n\n // Use a comparator function to figure out the smallest index at which\n // an object should be inserted so as to maintain order. Uses binary search.\n _.sortedIndex = function(array, obj, iterator, context) {\n iterator = iterator == null ? _.identity : lookupIterator(iterator);\n var value = iterator.call(context, obj);\n var low = 0, high = array.length;\n while (low < high) {\n var mid = (low + high) >>> 1;\n iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;\n }\n return low;\n };\n\n // Safely create a real, live array from anything iterable.\n _.toArray = function(obj) {\n if (!obj) return [];\n if (_.isArray(obj)) return slice.call(obj);\n if (obj.length === +obj.length) return _.map(obj, _.identity);\n return _.values(obj);\n };\n\n // Return the number of elements in an object.\n _.size = function(obj) {\n if (obj == null) return 0;\n return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;\n };\n\n // Array Functions\n // ---------------\n\n // Get the first element of an array. Passing **n** will return the first N\n // values in the array. Aliased as `head` and `take`. The **guard** check\n // allows it to work with `_.map`.\n _.first = _.head = _.take = function(array, n, guard) {\n if (array == null) return void 0;\n return (n == null) || guard ? array[0] : slice.call(array, 0, n);\n };\n\n // Returns everything but the last entry of the array. Especially useful on\n // the arguments object. Passing **n** will return all the values in\n // the array, excluding the last N. The **guard** check allows it to work with\n // `_.map`.\n _.initial = function(array, n, guard) {\n return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));\n };\n\n // Get the last element of an array. Passing **n** will return the last N\n // values in the array. The **guard** check allows it to work with `_.map`.\n _.last = function(array, n, guard) {\n if (array == null) return void 0;\n if ((n == null) || guard) {\n return array[array.length - 1];\n } else {\n return slice.call(array, Math.max(array.length - n, 0));\n }\n };\n\n // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.\n // Especially useful on the arguments object. Passing an **n** will return\n // the rest N values in the array. The **guard**\n // check allows it to work with `_.map`.\n _.rest = _.tail = _.drop = function(array, n, guard) {\n return slice.call(array, (n == null) || guard ? 1 : n);\n };\n\n // Trim out all falsy values from an array.\n _.compact = function(array) {\n return _.filter(array, _.identity);\n };\n\n // Internal implementation of a recursive `flatten` function.\n var flatten = function(input, shallow, output) {\n if (shallow && _.every(input, _.isArray)) {\n return concat.apply(output, input);\n }\n each(input, function(value) {\n if (_.isArray(value) || _.isArguments(value)) {\n shallow ? push.apply(output, value) : flatten(value, shallow, output);\n } else {\n output.push(value);\n }\n });\n return output;\n };\n\n // Flatten out an array, either recursively (by default), or just one level.\n _.flatten = function(array, shallow) {\n return flatten(array, shallow, []);\n };\n\n // Return a version of the array that does not contain the specified value(s).\n _.without = function(array) {\n return _.difference(array, slice.call(arguments, 1));\n };\n\n // Produce a duplicate-free version of the array. If the array has already\n // been sorted, you have the option of using a faster algorithm.\n // Aliased as `unique`.\n _.uniq = _.unique = function(array, isSorted, iterator, context) {\n if (_.isFunction(isSorted)) {\n context = iterator;\n iterator = isSorted;\n isSorted = false;\n }\n var initial = iterator ? _.map(array, iterator, context) : array;\n var results = [];\n var seen = [];\n each(initial, function(value, index) {\n if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {\n seen.push(value);\n results.push(array[index]);\n }\n });\n return results;\n };\n\n // Produce an array that contains the union: each distinct element from all of\n // the passed-in arrays.\n _.union = function() {\n return _.uniq(_.flatten(arguments, true));\n };\n\n // Produce an array that contains every item shared between all the\n // passed-in arrays.\n _.intersection = function(array) {\n var rest = slice.call(arguments, 1);\n return _.filter(_.uniq(array), function(item) {\n return _.every(rest, function(other) {\n return _.indexOf(other, item) >= 0;\n });\n });\n };\n\n // Take the difference between one array and a number of other arrays.\n // Only the elements present in just the first array will remain.\n _.difference = function(array) {\n var rest = concat.apply(ArrayProto, slice.call(arguments, 1));\n return _.filter(array, function(value){ return !_.contains(rest, value); });\n };\n\n // Zip together multiple lists into a single array -- elements that share\n // an index go together.\n _.zip = function() {\n var length = _.max(_.pluck(arguments, \"length\").concat(0));\n var results = new Array(length);\n for (var i = 0; i < length; i++) {\n results[i] = _.pluck(arguments, '' + i);\n }\n return results;\n };\n\n // Converts lists into objects. Pass either a single array of `[key, value]`\n // pairs, or two parallel arrays of the same length -- one of keys, and one of\n // the corresponding values.\n _.object = function(list, values) {\n if (list == null) return {};\n var result = {};\n for (var i = 0, length = list.length; i < length; i++) {\n if (values) {\n result[list[i]] = values[i];\n } else {\n result[list[i][0]] = list[i][1];\n }\n }\n return result;\n };\n\n // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),\n // we need this function. Return the position of the first occurrence of an\n // item in an array, or -1 if the item is not included in the array.\n // Delegates to **ECMAScript 5**'s native `indexOf` if available.\n // If the array is large and already in sort order, pass `true`\n // for **isSorted** to use binary search.\n _.indexOf = function(array, item, isSorted) {\n if (array == null) return -1;\n var i = 0, length = array.length;\n if (isSorted) {\n if (typeof isSorted == 'number') {\n i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);\n } else {\n i = _.sortedIndex(array, item);\n return array[i] === item ? i : -1;\n }\n }\n if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);\n for (; i < length; i++) if (array[i] === item) return i;\n return -1;\n };\n\n // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.\n _.lastIndexOf = function(array, item, from) {\n if (array == null) return -1;\n var hasIndex = from != null;\n if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {\n return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);\n }\n var i = (hasIndex ? from : array.length);\n while (i--) if (array[i] === item) return i;\n return -1;\n };\n\n // Generate an integer Array containing an arithmetic progression. A port of\n // the native Python `range()` function. See\n // [the Python documentation](http://docs.python.org/library/functions.html#range).\n _.range = function(start, stop, step) {\n if (arguments.length <= 1) {\n stop = start || 0;\n start = 0;\n }\n step = arguments[2] || 1;\n\n var length = Math.max(Math.ceil((stop - start) / step), 0);\n var idx = 0;\n var range = new Array(length);\n\n while(idx < length) {\n range[idx++] = start;\n start += step;\n }\n\n return range;\n };\n\n // Function (ahem) Functions\n // ------------------\n\n // Reusable constructor function for prototype setting.\n var ctor = function(){};\n\n // Create a function bound to a given object (assigning `this`, and arguments,\n // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if\n // available.\n _.bind = function(func, context) {\n var args, bound;\n if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));\n if (!_.isFunction(func)) throw new TypeError;\n args = slice.call(arguments, 2);\n return bound = function() {\n if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));\n ctor.prototype = func.prototype;\n var self = new ctor;\n ctor.prototype = null;\n var result = func.apply(self, args.concat(slice.call(arguments)));\n if (Object(result) === result) return result;\n return self;\n };\n };\n\n // Partially apply a function by creating a version that has had some of its\n // arguments pre-filled, without changing its dynamic `this` context.\n _.partial = function(func) {\n var args = slice.call(arguments, 1);\n return function() {\n return func.apply(this, args.concat(slice.call(arguments)));\n };\n };\n\n // Bind all of an object's methods to that object. Useful for ensuring that\n // all callbacks defined on an object belong to it.\n _.bindAll = function(obj) {\n var funcs = slice.call(arguments, 1);\n if (funcs.length === 0) throw new Error(\"bindAll must be passed function names\");\n each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });\n return obj;\n };\n\n // Memoize an expensive function by storing its results.\n _.memoize = function(func, hasher) {\n var memo = {};\n hasher || (hasher = _.identity);\n return function() {\n var key = hasher.apply(this, arguments);\n return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));\n };\n };\n\n // Delays a function for the given number of milliseconds, and then calls\n // it with the arguments supplied.\n _.delay = function(func, wait) {\n var args = slice.call(arguments, 2);\n return setTimeout(function(){ return func.apply(null, args); }, wait);\n };\n\n // Defers a function, scheduling it to run after the current call stack has\n // cleared.\n _.defer = function(func) {\n return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));\n };\n\n // Returns a function, that, when invoked, will only be triggered at most once\n // during a given window of time. Normally, the throttled function will run\n // as much as it can, without ever going more than once per `wait` duration;\n // but if you'd like to disable the execution on the leading edge, pass\n // `{leading: false}`. To disable execution on the trailing edge, ditto.\n _.throttle = function(func, wait, options) {\n var context, args, result;\n var timeout = null;\n var previous = 0;\n options || (options = {});\n var later = function() {\n previous = options.leading === false ? 0 : new Date;\n timeout = null;\n result = func.apply(context, args);\n };\n return function() {\n var now = new Date;\n if (!previous && options.leading === false) previous = now;\n var remaining = wait - (now - previous);\n context = this;\n args = arguments;\n if (remaining <= 0) {\n clearTimeout(timeout);\n timeout = null;\n previous = now;\n result = func.apply(context, args);\n } else if (!timeout && options.trailing !== false) {\n timeout = setTimeout(later, remaining);\n }\n return result;\n };\n };\n\n // Returns a function, that, as long as it continues to be invoked, will not\n // be triggered. The function will be called after it stops being called for\n // N milliseconds. If `immediate` is passed, trigger the function on the\n // leading edge, instead of the trailing.\n _.debounce = function(func, wait, immediate) {\n var timeout, args, context, timestamp, result;\n return function() {\n context = this;\n args = arguments;\n timestamp = new Date();\n var later = function() {\n var last = (new Date()) - timestamp;\n if (last < wait) {\n timeout = setTimeout(later, wait - last);\n } else {\n timeout = null;\n if (!immediate) result = func.apply(context, args);\n }\n };\n var callNow = immediate && !timeout;\n if (!timeout) {\n timeout = setTimeout(later, wait);\n }\n if (callNow) result = func.apply(context, args);\n return result;\n };\n };\n\n // Returns a function that will be executed at most one time, no matter how\n // often you call it. Useful for lazy initialization.\n _.once = function(func) {\n var ran = false, memo;\n return function() {\n if (ran) return memo;\n ran = true;\n memo = func.apply(this, arguments);\n func = null;\n return memo;\n };\n };\n\n // Returns the first function passed as an argument to the second,\n // allowing you to adjust arguments, run code before and after, and\n // conditionally execute the original function.\n _.wrap = function(func, wrapper) {\n return function() {\n var args = [func];\n push.apply(args, arguments);\n return wrapper.apply(this, args);\n };\n };\n\n // Returns a function that is the composition of a list of functions, each\n // consuming the return value of the function that follows.\n _.compose = function() {\n var funcs = arguments;\n return function() {\n var args = arguments;\n for (var i = funcs.length - 1; i >= 0; i--) {\n args = [funcs[i].apply(this, args)];\n }\n return args[0];\n };\n };\n\n // Returns a function that will only be executed after being called N times.\n _.after = function(times, func) {\n return function() {\n if (--times < 1) {\n return func.apply(this, arguments);\n }\n };\n };\n\n // Object Functions\n // ----------------\n\n // Retrieve the names of an object's properties.\n // Delegates to **ECMAScript 5**'s native `Object.keys`\n _.keys = nativeKeys || function(obj) {\n if (obj !== Object(obj)) throw new TypeError('Invalid object');\n var keys = [];\n for (var key in obj) if (_.has(obj, key)) keys.push(key);\n return keys;\n };\n\n // Retrieve the values of an object's properties.\n _.values = function(obj) {\n var keys = _.keys(obj);\n var length = keys.length;\n var values = new Array(length);\n for (var i = 0; i < length; i++) {\n values[i] = obj[keys[i]];\n }\n return values;\n };\n\n // Convert an object into a list of `[key, value]` pairs.\n _.pairs = function(obj) {\n var keys = _.keys(obj);\n var length = keys.length;\n var pairs = new Array(length);\n for (var i = 0; i < length; i++) {\n pairs[i] = [keys[i], obj[keys[i]]];\n }\n return pairs;\n };\n\n // Invert the keys and values of an object. The values must be serializable.\n _.invert = function(obj) {\n var result = {};\n var keys = _.keys(obj);\n for (var i = 0, length = keys.length; i < length; i++) {\n result[obj[keys[i]]] = keys[i];\n }\n return result;\n };\n\n // Return a sorted list of the function names available on the object.\n // Aliased as `methods`\n _.functions = _.methods = function(obj) {\n var names = [];\n for (var key in obj) {\n if (_.isFunction(obj[key])) names.push(key);\n }\n return names.sort();\n };\n\n // Extend a given object with all the properties in passed-in object(s).\n _.extend = function(obj) {\n each(slice.call(arguments, 1), function(source) {\n if (source) {\n for (var prop in source) {\n obj[prop] = source[prop];\n }\n }\n });\n return obj;\n };\n\n // Return a copy of the object only containing the whitelisted properties.\n _.pick = function(obj) {\n var copy = {};\n var keys = concat.apply(ArrayProto, slice.call(arguments, 1));\n each(keys, function(key) {\n if (key in obj) copy[key] = obj[key];\n });\n return copy;\n };\n\n // Return a copy of the object without the blacklisted properties.\n _.omit = function(obj) {\n var copy = {};\n var keys = concat.apply(ArrayProto, slice.call(arguments, 1));\n for (var key in obj) {\n if (!_.contains(keys, key)) copy[key] = obj[key];\n }\n return copy;\n };\n\n // Fill in a given object with default properties.\n _.defaults = function(obj) {\n each(slice.call(arguments, 1), function(source) {\n if (source) {\n for (var prop in source) {\n if (obj[prop] === void 0) obj[prop] = source[prop];\n }\n }\n });\n return obj;\n };\n\n // Create a (shallow-cloned) duplicate of an object.\n _.clone = function(obj) {\n if (!_.isObject(obj)) return obj;\n return _.isArray(obj) ? obj.slice() : _.extend({}, obj);\n };\n\n // Invokes interceptor with the obj, and then returns obj.\n // The primary purpose of this method is to \"tap into\" a method chain, in\n // order to perform operations on intermediate results within the chain.\n _.tap = function(obj, interceptor) {\n interceptor(obj);\n return obj;\n };\n\n // Internal recursive comparison function for `isEqual`.\n var eq = function(a, b, aStack, bStack) {\n // Identical objects are equal. `0 === -0`, but they aren't identical.\n // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).\n if (a === b) return a !== 0 || 1 / a == 1 / b;\n // A strict comparison is necessary because `null == undefined`.\n if (a == null || b == null) return a === b;\n // Unwrap any wrapped objects.\n if (a instanceof _) a = a._wrapped;\n if (b instanceof _) b = b._wrapped;\n // Compare `[[Class]]` names.\n var className = toString.call(a);\n if (className != toString.call(b)) return false;\n switch (className) {\n // Strings, numbers, dates, and booleans are compared by value.\n case '[object String]':\n // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n // equivalent to `new String(\"5\")`.\n return a == String(b);\n case '[object Number]':\n // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for\n // other numeric values.\n return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);\n case '[object Date]':\n case '[object Boolean]':\n // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n // millisecond representations. Note that invalid dates with millisecond representations\n // of `NaN` are not equivalent.\n return +a == +b;\n // RegExps are compared by their source patterns and flags.\n case '[object RegExp]':\n return a.source == b.source &&\n a.global == b.global &&\n a.multiline == b.multiline &&\n a.ignoreCase == b.ignoreCase;\n }\n if (typeof a != 'object' || typeof b != 'object') return false;\n // Assume equality for cyclic structures. The algorithm for detecting cyclic\n // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n var length = aStack.length;\n while (length--) {\n // Linear search. Performance is inversely proportional to the number of\n // unique nested structures.\n if (aStack[length] == a) return bStack[length] == b;\n }\n // Objects with different constructors are not equivalent, but `Object`s\n // from different frames are.\n var aCtor = a.constructor, bCtor = b.constructor;\n if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&\n _.isFunction(bCtor) && (bCtor instanceof bCtor))) {\n return false;\n }\n // Add the first object to the stack of traversed objects.\n aStack.push(a);\n bStack.push(b);\n var size = 0, result = true;\n // Recursively compare objects and arrays.\n if (className == '[object Array]') {\n // Compare array lengths to determine if a deep comparison is necessary.\n size = a.length;\n result = size == b.length;\n if (result) {\n // Deep compare the contents, ignoring non-numeric properties.\n while (size--) {\n if (!(result = eq(a[size], b[size], aStack, bStack))) break;\n }\n }\n } else {\n // Deep compare objects.\n for (var key in a) {\n if (_.has(a, key)) {\n // Count the expected number of properties.\n size++;\n // Deep compare each member.\n if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;\n }\n }\n // Ensure that both objects contain the same number of properties.\n if (result) {\n for (key in b) {\n if (_.has(b, key) && !(size--)) break;\n }\n result = !size;\n }\n }\n // Remove the first object from the stack of traversed objects.\n aStack.pop();\n bStack.pop();\n return result;\n };\n\n // Perform a deep comparison to check if two objects are equal.\n _.isEqual = function(a, b) {\n return eq(a, b, [], []);\n };\n\n // Is a given array, string, or object empty?\n // An \"empty\" object has no enumerable own-properties.\n _.isEmpty = function(obj) {\n if (obj == null) return true;\n if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;\n for (var key in obj) if (_.has(obj, key)) return false;\n return true;\n };\n\n // Is a given value a DOM element?\n _.isElement = function(obj) {\n return !!(obj && obj.nodeType === 1);\n };\n\n // Is a given value an array?\n // Delegates to ECMA5's native Array.isArray\n _.isArray = nativeIsArray || function(obj) {\n return toString.call(obj) == '[object Array]';\n };\n\n // Is a given variable an object?\n _.isObject = function(obj) {\n return obj === Object(obj);\n };\n\n // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.\n each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {\n _['is' + name] = function(obj) {\n return toString.call(obj) == '[object ' + name + ']';\n };\n });\n\n // Define a fallback version of the method in browsers (ahem, IE), where\n // there isn't any inspectable \"Arguments\" type.\n if (!_.isArguments(arguments)) {\n _.isArguments = function(obj) {\n return !!(obj && _.has(obj, 'callee'));\n };\n }\n\n // Optimize `isFunction` if appropriate.\n if (typeof (/./) !== 'function') {\n _.isFunction = function(obj) {\n return typeof obj === 'function';\n };\n }\n\n // Is a given object a finite number?\n _.isFinite = function(obj) {\n return isFinite(obj) && !isNaN(parseFloat(obj));\n };\n\n // Is the given value `NaN`? (NaN is the only number which does not equal itself).\n _.isNaN = function(obj) {\n return _.isNumber(obj) && obj != +obj;\n };\n\n // Is a given value a boolean?\n _.isBoolean = function(obj) {\n return obj === true || obj === false || toString.call(obj) == '[object Boolean]';\n };\n\n // Is a given value equal to null?\n _.isNull = function(obj) {\n return obj === null;\n };\n\n // Is a given variable undefined?\n _.isUndefined = function(obj) {\n return obj === void 0;\n };\n\n // Shortcut function for checking if an object has a given property directly\n // on itself (in other words, not on a prototype).\n _.has = function(obj, key) {\n return hasOwnProperty.call(obj, key);\n };\n\n // Utility Functions\n // -----------------\n\n // Run Underscore.js in *noConflict* mode, returning the `_` variable to its\n // previous owner. Returns a reference to the Underscore object.\n _.noConflict = function() {\n root._ = previousUnderscore;\n return this;\n };\n\n // Keep the identity function around for default iterators.\n _.identity = function(value) {\n return value;\n };\n\n // Run a function **n** times.\n _.times = function(n, iterator, context) {\n var accum = Array(Math.max(0, n));\n for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);\n return accum;\n };\n\n // Return a random integer between min and max (inclusive).\n _.random = function(min, max) {\n if (max == null) {\n max = min;\n min = 0;\n }\n return min + Math.floor(Math.random() * (max - min + 1));\n };\n\n // List of HTML entities for escaping.\n var entityMap = {\n escape: {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n }\n };\n entityMap.unescape = _.invert(entityMap.escape);\n\n // Regexes containing the keys and values listed immediately above.\n var entityRegexes = {\n escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),\n unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')\n };\n\n // Functions for escaping and unescaping strings to/from HTML interpolation.\n _.each(['escape', 'unescape'], function(method) {\n _[method] = function(string) {\n if (string == null) return '';\n return ('' + string).replace(entityRegexes[method], function(match) {\n return entityMap[method][match];\n });\n };\n });\n\n // If the value of the named `property` is a function then invoke it with the\n // `object` as context; otherwise, return it.\n _.result = function(object, property) {\n if (object == null) return void 0;\n var value = object[property];\n return _.isFunction(value) ? value.call(object) : value;\n };\n\n // Add your own custom functions to the Underscore object.\n _.mixin = function(obj) {\n each(_.functions(obj), function(name) {\n var func = _[name] = obj[name];\n _.prototype[name] = function() {\n var args = [this._wrapped];\n push.apply(args, arguments);\n return result.call(this, func.apply(_, args));\n };\n });\n };\n\n // Generate a unique integer id (unique within the entire client session).\n // Useful for temporary DOM ids.\n var idCounter = 0;\n _.uniqueId = function(prefix) {\n var id = ++idCounter + '';\n return prefix ? prefix + id : id;\n };\n\n // By default, Underscore uses ERB-style template delimiters, change the\n // following template settings to use alternative delimiters.\n _.templateSettings = {\n evaluate : /<%([\\s\\S]+?)%>/g,\n interpolate : /<%=([\\s\\S]+?)%>/g,\n escape : /<%-([\\s\\S]+?)%>/g\n };\n\n // When customizing `templateSettings`, if you don't want to define an\n // interpolation, evaluation or escaping regex, we need one that is\n // guaranteed not to match.\n var noMatch = /(.)^/;\n\n // Certain characters need to be escaped so that they can be put into a\n // string literal.\n var escapes = {\n \"'\": \"'\",\n '\\\\': '\\\\',\n '\\r': 'r',\n '\\n': 'n',\n '\\t': 't',\n '\\u2028': 'u2028',\n '\\u2029': 'u2029'\n };\n\n var escaper = /\\\\|'|\\r|\\n|\\t|\\u2028|\\u2029/g;\n\n // JavaScript micro-templating, similar to John Resig's implementation.\n // Underscore templating handles arbitrary delimiters, preserves whitespace,\n // and correctly escapes quotes within interpolated code.\n _.template = function(text, data, settings) {\n var render;\n settings = _.defaults({}, settings, _.templateSettings);\n\n // Combine delimiters into one regular expression via alternation.\n var matcher = new RegExp([\n (settings.escape || noMatch).source,\n (settings.interpolate || noMatch).source,\n (settings.evaluate || noMatch).source\n ].join('|') + '|$', 'g');\n\n // Compile the template source, escaping string literals appropriately.\n var index = 0;\n var source = \"__p+='\";\n text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {\n source += text.slice(index, offset)\n .replace(escaper, function(match) { return '\\\\' + escapes[match]; });\n\n if (escape) {\n source += \"'+\\n((__t=(\" + escape + \"))==null?'':_.escape(__t))+\\n'\";\n }\n if (interpolate) {\n source += \"'+\\n((__t=(\" + interpolate + \"))==null?'':__t)+\\n'\";\n }\n if (evaluate) {\n source += \"';\\n\" + evaluate + \"\\n__p+='\";\n }\n index = offset + match.length;\n return match;\n });\n source += \"';\\n\";\n\n // If a variable is not specified, place data values in local scope.\n if (!settings.variable) source = 'with(obj||{}){\\n' + source + '}\\n';\n\n source = \"var __t,__p='',__j=Array.prototype.join,\" +\n \"print=function(){__p+=__j.call(arguments,'');};\\n\" +\n source + \"return __p;\\n\";\n\n try {\n render = new Function(settings.variable || 'obj', '_', source);\n } catch (e) {\n e.source = source;\n throw e;\n }\n\n if (data) return render(data, _);\n var template = function(data) {\n return render.call(this, data, _);\n };\n\n // Provide the compiled function source as a convenience for precompilation.\n template.source = 'function(' + (settings.variable || 'obj') + '){\\n' + source + '}';\n\n return template;\n };\n\n // Add a \"chain\" function, which will delegate to the wrapper.\n _.chain = function(obj) {\n return _(obj).chain();\n };\n\n // OOP\n // ---------------\n // If Underscore is called as a function, it returns a wrapped object that\n // can be used OO-style. This wrapper holds altered versions of all the\n // underscore functions. Wrapped objects may be chained.\n\n // Helper function to continue chaining intermediate results.\n var result = function(obj) {\n return this._chain ? _(obj).chain() : obj;\n };\n\n // Add all of the Underscore functions to the wrapper object.\n _.mixin(_);\n\n // Add all mutator Array functions to the wrapper.\n each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n var method = ArrayProto[name];\n _.prototype[name] = function() {\n var obj = this._wrapped;\n method.apply(obj, arguments);\n if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];\n return result.call(this, obj);\n };\n });\n\n // Add all accessor Array functions to the wrapper.\n each(['concat', 'join', 'slice'], function(name) {\n var method = ArrayProto[name];\n _.prototype[name] = function() {\n return result.call(this, method.apply(this._wrapped, arguments));\n };\n });\n\n _.extend(_.prototype, {\n\n // Start chaining a wrapped Underscore object.\n chain: function() {\n this._chain = true;\n return this;\n },\n\n // Extracts the result from a wrapped and chained object.\n value: function() {\n return this._wrapped;\n }\n\n });\n\n}).call(this);\n\n},{}],9:[function(require,module,exports){\n// MarionetteJS (Backbone.Marionette)\n// ----------------------------------\n// v2.4.4\n//\n// Copyright (c)2015 Derick Bailey, Muted Solutions, LLC.\n// Distributed under MIT license\n//\n// http://marionettejs.com\n\n(function(root, factory) {\n\n if (typeof define === 'function' && define.amd) {\n define(['backbone', 'underscore', 'backbone.wreqr', 'backbone.babysitter'], function(Backbone, _) {\n return (root.Marionette = root.Mn = factory(root, Backbone, _));\n });\n } else if (typeof exports !== 'undefined') {\n var Backbone = require('backbone');\n var _ = require('underscore');\n var Wreqr = require('backbone.wreqr');\n var BabySitter = require('backbone.babysitter');\n module.exports = factory(root, Backbone, _);\n } else {\n root.Marionette = root.Mn = factory(root, root.Backbone, root._);\n }\n\n}(this, function(root, Backbone, _) {\n 'use strict';\n\n var previousMarionette = root.Marionette;\n var previousMn = root.Mn;\n\n var Marionette = Backbone.Marionette = {};\n\n Marionette.VERSION = '2.4.4';\n\n Marionette.noConflict = function() {\n root.Marionette = previousMarionette;\n root.Mn = previousMn;\n return this;\n };\n\n // Get the Deferred creator for later use\n Marionette.Deferred = Backbone.$.Deferred;\n\n Marionette.FEATURES = {\n };\n \n Marionette.isEnabled = function(name) {\n return !!Marionette.FEATURES[name];\n };\n \n /* jshint unused: false *//* global console */\n \n // Helpers\n // -------\n \n // Marionette.extend\n // -----------------\n \n // Borrow the Backbone `extend` method so we can use it as needed\n Marionette.extend = Backbone.Model.extend;\n \n // Marionette.isNodeAttached\n // -------------------------\n \n // Determine if `el` is a child of the document\n Marionette.isNodeAttached = function(el) {\n return Backbone.$.contains(document.documentElement, el);\n };\n \n // Merge `keys` from `options` onto `this`\n Marionette.mergeOptions = function(options, keys) {\n if (!options) { return; }\n _.extend(this, _.pick(options, keys));\n };\n \n // Marionette.getOption\n // --------------------\n \n // Retrieve an object, function or other value from a target\n // object or its `options`, with `options` taking precedence.\n Marionette.getOption = function(target, optionName) {\n if (!target || !optionName) { return; }\n if (target.options && (target.options[optionName] !== undefined)) {\n return target.options[optionName];\n } else {\n return target[optionName];\n }\n };\n \n // Proxy `Marionette.getOption`\n Marionette.proxyGetOption = function(optionName) {\n return Marionette.getOption(this, optionName);\n };\n \n // Similar to `_.result`, this is a simple helper\n // If a function is provided we call it with context\n // otherwise just return the value. If the value is\n // undefined return a default value\n Marionette._getValue = function(value, context, params) {\n if (_.isFunction(value)) {\n value = params ? value.apply(context, params) : value.call(context);\n }\n return value;\n };\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\n Marionette.normalizeMethods = function(hash) {\n return _.reduce(hash, function(normalizedHash, method, name) {\n if (!_.isFunction(method)) {\n method = this[method];\n }\n if (method) {\n normalizedHash[name] = method;\n }\n return normalizedHash;\n }, {}, this);\n };\n \n // utility method for parsing @ui. syntax strings\n // into associated selector\n Marionette.normalizeUIString = function(uiString, ui) {\n return uiString.replace(/@ui\\.[a-zA-Z_$0-9]*/g, function(r) {\n return ui[r.slice(4)];\n });\n };\n \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.\n Marionette.normalizeUIKeys = function(hash, ui) {\n return _.reduce(hash, function(memo, val, key) {\n var normalizedKey = Marionette.normalizeUIString(key, ui);\n memo[normalizedKey] = val;\n return memo;\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\n Marionette.normalizeUIValues = function(hash, ui, properties) {\n _.each(hash, function(val, key) {\n if (_.isString(val)) {\n hash[key] = Marionette.normalizeUIString(val, ui);\n } else if (_.isObject(val) && _.isArray(properties)) {\n _.extend(val, Marionette.normalizeUIValues(_.pick(val, properties), ui));\n /* Value is an object, and we got an array of embedded property names to normalize. */\n _.each(properties, function(property) {\n var propertyVal = val[property];\n if (_.isString(propertyVal)) {\n val[property] = Marionette.normalizeUIString(propertyVal, ui);\n }\n });\n }\n });\n return hash;\n };\n \n // Mix in methods from Underscore, for iteration, and other\n // collection related features.\n // Borrowing this code from Backbone.Collection:\n // http://backbonejs.org/docs/backbone.html#section-121\n Marionette.actAsCollection = function(object, listProperty) {\n var 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'];\n \n _.each(methods, function(method) {\n object[method] = function() {\n var list = _.values(_.result(this, listProperty));\n var args = [list].concat(_.toArray(arguments));\n return _[method].apply(_, args);\n };\n });\n };\n \n var deprecate = Marionette.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 ((test === undefined || !test) && !deprecate._cache[message]) {\n deprecate._warn('Deprecation warning: ' + message);\n deprecate._cache[message] = true;\n }\n };\n \n deprecate._warn = typeof console !== 'undefined' && (console.warn || console.log) || function() {};\n deprecate._cache = {};\n \n /* jshint maxstatements: 14, maxcomplexity: 7 */\n \n // Trigger Method\n // --------------\n \n Marionette._triggerMethod = (function() {\n // split the event name on the \":\"\n var splitter = /(^|:)(\\w)/gi;\n \n // take the event section (\"section1:section2:section3\")\n // and turn it in to uppercase name\n function getEventName(match, prefix, eventName) {\n return eventName.toUpperCase();\n }\n \n return function(context, event, args) {\n var noEventArg = arguments.length < 3;\n if (noEventArg) {\n args = event;\n event = args[0];\n }\n \n // get the method name from the event name\n var methodName = 'on' + event.replace(splitter, getEventName);\n var method = context[methodName];\n var 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(context, noEventArg ? _.rest(args) : args);\n }\n \n // trigger the event, if a trigger method exists\n if (_.isFunction(context.trigger)) {\n if (noEventArg + args.length > 1) {\n context.trigger.apply(context, noEventArg ? args : [event].concat(_.drop(args, 0)));\n } else {\n context.trigger(event);\n }\n }\n \n return result;\n };\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.\n Marionette.triggerMethod = function(event) {\n return Marionette._triggerMethod(this, arguments);\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.\n Marionette.triggerMethodOn = function(context) {\n var fnc = _.isFunction(context.triggerMethod) ?\n context.triggerMethod :\n Marionette.triggerMethod;\n \n return fnc.apply(context, _.rest(arguments));\n };\n \n // DOM Refresh\n // -----------\n \n // Monitor a view's state, and after it has been rendered and shown\n // in the DOM, trigger a \"dom:refresh\" event every time it is\n // re-rendered.\n \n Marionette.MonitorDOMRefresh = function(view) {\n if (view._isDomRefreshMonitored) { return; }\n view._isDomRefreshMonitored = true;\n \n // track when the view has been shown in the DOM,\n // using a Marionette.Region (or by other means of triggering \"show\")\n function handleShow() {\n view._isShown = true;\n triggerDOMRefresh();\n }\n \n // track when the view has been rendered\n function handleRender() {\n view._isRendered = true;\n triggerDOMRefresh();\n }\n \n // Trigger the \"dom:refresh\" event and corresponding \"onDomRefresh\" method\n function triggerDOMRefresh() {\n if (view._isShown && view._isRendered && Marionette.isNodeAttached(view.el)) {\n Marionette.triggerMethodOn(view, 'dom:refresh', view);\n }\n }\n \n view.on({\n show: handleShow,\n render: handleRender\n });\n };\n \n /* jshint maxparams: 5 */\n \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 \n (function(Marionette) {\n 'use strict';\n \n // Bind the event to handlers specified as a string of\n // handler names on the target object\n function bindFromStrings(target, entity, evt, methods) {\n var methodNames = methods.split(/\\s+/);\n \n _.each(methodNames, function(methodName) {\n \n var method = target[methodName];\n if (!method) {\n throw new Marionette.Error('Method \"' + methodName +\n '\" was configured as an event handler, but does not exist.');\n }\n \n target.listenTo(entity, evt, method);\n });\n }\n \n // Bind the event to a supplied callback function\n function bindToFunction(target, entity, evt, method) {\n target.listenTo(entity, evt, method);\n }\n \n // Bind the event to handlers specified as a string of\n // handler names on the target object\n function unbindFromStrings(target, entity, evt, methods) {\n var methodNames = methods.split(/\\s+/);\n \n _.each(methodNames, function(methodName) {\n var method = target[methodName];\n target.stopListening(entity, evt, method);\n });\n }\n \n // Bind the event to a supplied callback function\n function unbindToFunction(target, entity, evt, method) {\n target.stopListening(entity, evt, method);\n }\n \n // generic looping function\n function iterateEvents(target, entity, bindings, functionCallback, stringCallback) {\n if (!entity || !bindings) { return; }\n \n // type-check bindings\n if (!_.isObject(bindings)) {\n throw new Marionette.Error({\n message: 'Bindings must be an object or function.',\n url: 'marionette.functions.html#marionettebindentityevents'\n });\n }\n \n // allow the bindings to be a function\n bindings = Marionette._getValue(bindings, target);\n \n // iterate the bindings and bind them\n _.each(bindings, function(methods, evt) {\n \n // allow for a function as the handler,\n // or a list of event names as a string\n if (_.isFunction(methods)) {\n functionCallback(target, entity, evt, methods);\n } else {\n stringCallback(target, entity, evt, methods);\n }\n \n });\n }\n \n // Export Public API\n Marionette.bindEntityEvents = function(target, entity, bindings) {\n iterateEvents(target, entity, bindings, bindToFunction, bindFromStrings);\n };\n \n Marionette.unbindEntityEvents = function(target, entity, bindings) {\n iterateEvents(target, entity, bindings, unbindToFunction, unbindFromStrings);\n };\n \n // Proxy `bindEntityEvents`\n Marionette.proxyBindEntityEvents = function(entity, bindings) {\n return Marionette.bindEntityEvents(this, entity, bindings);\n };\n \n // Proxy `unbindEntityEvents`\n Marionette.proxyUnbindEntityEvents = function(entity, bindings) {\n return Marionette.unbindEntityEvents(this, entity, bindings);\n };\n })(Marionette);\n \n\n // Error\n // -----\n \n var errorProps = ['description', 'fileName', 'lineNumber', 'name', 'message', 'number'];\n \n Marionette.Error = Marionette.extend.call(Error, {\n urlRoot: 'http://marionettejs.com/docs/v' + Marionette.VERSION + '/',\n \n constructor: function(message, options) {\n if (_.isObject(message)) {\n options = message;\n message = options.message;\n } else if (!options) {\n options = {};\n }\n \n var 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: function() {\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, Marionette.Error);\n }\n },\n \n toString: function() {\n return this.name + ': ' + this.message + (this.url ? ' See: ' + this.url : '');\n }\n });\n \n Marionette.Error.extend = Marionette.extend;\n \n // Callbacks\n // ---------\n \n // A simple way of managing a collection of callbacks\n // and executing them at a later point in time, using jQuery's\n // `Deferred` object.\n Marionette.Callbacks = function() {\n this._deferred = Marionette.Deferred();\n this._callbacks = [];\n };\n \n _.extend(Marionette.Callbacks.prototype, {\n \n // Add a callback to be executed. Callbacks added here are\n // guaranteed to execute, even if they are added after the\n // `run` method is called.\n add: function(callback, contextOverride) {\n var promise = _.result(this._deferred, 'promise');\n \n this._callbacks.push({cb: callback, ctx: contextOverride});\n \n promise.then(function(args) {\n if (contextOverride) { args.context = contextOverride; }\n callback.call(args.context, args.options);\n });\n },\n \n // Run all registered callbacks with the context specified.\n // Additional callbacks can be added after this has been run\n // and they will still be executed.\n run: function(options, context) {\n this._deferred.resolve({\n options: options,\n context: context\n });\n },\n \n // Resets the list of callbacks to be run, allowing the same list\n // to be run multiple times - whenever the `run` method is called.\n reset: function() {\n var callbacks = this._callbacks;\n this._deferred = Marionette.Deferred();\n this._callbacks = [];\n \n _.each(callbacks, function(cb) {\n this.add(cb.cb, cb.ctx);\n }, this);\n }\n });\n \n // Controller\n // ----------\n \n // A multi-purpose object to use as a controller for\n // modules and routers, and as a mediator for workflow\n // and coordination of other objects, views, and more.\n Marionette.Controller = function(options) {\n this.options = options || {};\n \n if (_.isFunction(this.initialize)) {\n this.initialize(this.options);\n }\n };\n \n Marionette.Controller.extend = Marionette.extend;\n \n // Controller Methods\n // --------------\n \n // Ensure it can trigger events with Backbone.Events\n _.extend(Marionette.Controller.prototype, Backbone.Events, {\n destroy: function() {\n Marionette._triggerMethod(this, 'before:destroy', arguments);\n Marionette._triggerMethod(this, 'destroy', arguments);\n \n this.stopListening();\n this.off();\n return this;\n },\n \n // import the `triggerMethod` to trigger events with corresponding\n // methods if the method exists\n triggerMethod: Marionette.triggerMethod,\n \n // A handy way to merge options onto the instance\n mergeOptions: Marionette.mergeOptions,\n \n // Proxy `getOption` to enable getting options from this or this.options by name.\n getOption: Marionette.proxyGetOption\n \n });\n \n // Object\n // ------\n \n // A Base Class that other Classes should descend from.\n // Object borrows many conventions and utilities from Backbone.\n Marionette.Object = function(options) {\n this.options = _.extend({}, _.result(this, 'options'), options);\n \n this.initialize.apply(this, arguments);\n };\n \n Marionette.Object.extend = Marionette.extend;\n \n // Object Methods\n // --------------\n \n // Ensure it can trigger events with Backbone.Events\n _.extend(Marionette.Object.prototype, Backbone.Events, {\n \n //this is a noop method intended to be overridden by classes that extend from this base\n initialize: function() {},\n \n destroy: function(options) {\n options = options || {};\n \n this.triggerMethod('before:destroy', options);\n this.triggerMethod('destroy', options);\n this.stopListening();\n \n return this;\n },\n \n // Import the `triggerMethod` to trigger events with corresponding\n // methods if the method exists\n triggerMethod: Marionette.triggerMethod,\n \n // A handy way to merge options onto the instance\n mergeOptions: Marionette.mergeOptions,\n \n // Proxy `getOption` to enable getting options from this or this.options by name.\n getOption: Marionette.proxyGetOption,\n \n // Proxy `bindEntityEvents` to enable binding view's events from another entity.\n bindEntityEvents: Marionette.proxyBindEntityEvents,\n \n // Proxy `unbindEntityEvents` to enable unbinding view's events from another entity.\n unbindEntityEvents: Marionette.proxyUnbindEntityEvents\n });\n \n /* jshint maxcomplexity: 16, maxstatements: 45, maxlen: 120 */\n \n // Region\n // ------\n \n // Manage the visual regions of your composite application. See\n // http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/\n \n Marionette.Region = Marionette.Object.extend({\n constructor: function(options) {\n \n // set options temporarily so that we can get `el`.\n // options will be overriden by Object.constructor\n this.options = options || {};\n 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 Marionette.Error({\n name: 'NoElError',\n message: 'An \"el\" must be specified for a region.'\n });\n }\n \n this.$el = this.getEl(this.el);\n Marionette.Object.call(this, options);\n },\n \n // Displays a backbone view instance inside of the region.\n // Handles calling the `render` method for you. Reads content\n // directly from the `el` attribute. Also calls an optional\n // `onShow` and `onDestroy` method on your view, just after showing\n // or just before destroying the view, respectively.\n // The `preventDestroy` option can be used to prevent a view from\n // the old view being destroyed on show.\n // The `forceShow` option can be used to force a view to be\n // re-rendered if it's already shown in the region.\n show: function(view, options) {\n if (!this._ensureElement()) {\n return;\n }\n \n this._ensureViewIsIntact(view);\n Marionette.MonitorDOMRefresh(view);\n \n var showOptions = options || {};\n var isDifferentView = view !== this.currentView;\n var preventDestroy = !!showOptions.preventDestroy;\n var forceShow = !!showOptions.forceShow;\n \n // We are only changing the view if there is a current view to change to begin with\n var isChangingView = !!this.currentView;\n \n // Only destroy the current view if we don't want to `preventDestroy` and if\n // the view given in the first argument is different than `currentView`\n var _shouldDestroyView = isDifferentView && !preventDestroy;\n \n // Only show the view given in the first argument if it is different than\n // the current view or if we want to re-show the view. Note that if\n // `_shouldDestroyView` is true, then `_shouldShowView` is also necessarily true.\n var _shouldShowView = isDifferentView || forceShow;\n \n if (isChangingView) {\n this.triggerMethod('before:swapOut', this.currentView, this, options);\n }\n \n if (this.currentView) {\n delete this.currentView._parent;\n }\n \n if (_shouldDestroyView) {\n this.empty();\n \n // A `destroy` event is attached to the clean up manually removed views.\n // We need to detach this event when a new view is going to be shown as it\n // is no longer relevant.\n } else if (isChangingView && _shouldShowView) {\n this.currentView.off('destroy', this.empty, this);\n }\n \n if (_shouldShowView) {\n \n // We need to listen for if a view is destroyed\n // in a way other than through the region.\n // If this happens we need to remove the reference\n // to the currentView since once a view has been destroyed\n // we can not reuse it.\n view.once('destroy', this.empty, this);\n \n // make this region the view's parent,\n // It's important that this parent binding happens before rendering\n // so that any events the child may trigger during render can also be\n // triggered on the child's ancestor views\n view._parent = this;\n this._renderView(view);\n \n if (isChangingView) {\n this.triggerMethod('before:swap', view, this, options);\n }\n \n this.triggerMethod('before:show', view, this, options);\n Marionette.triggerMethodOn(view, 'before:show', view, this, options);\n \n if (isChangingView) {\n this.triggerMethod('swapOut', this.currentView, this, options);\n }\n \n // An array of views that we're about to display\n var attachedRegion = Marionette.isNodeAttached(this.el);\n \n // The views that we're about to attach to the document\n // It's important that we prevent _getNestedViews from being executed unnecessarily\n // as it's a potentially-slow method\n var displayedViews = [];\n \n var attachOptions = _.extend({\n triggerBeforeAttach: this.triggerBeforeAttach,\n triggerAttach: this.triggerAttach\n }, showOptions);\n \n if (attachedRegion && attachOptions.triggerBeforeAttach) {\n displayedViews = this._displayedViews(view);\n this._triggerAttach(displayedViews, 'before:');\n }\n \n this.attachHtml(view);\n this.currentView = view;\n \n if (attachedRegion && attachOptions.triggerAttach) {\n displayedViews = this._displayedViews(view);\n this._triggerAttach(displayedViews);\n }\n \n if (isChangingView) {\n this.triggerMethod('swap', view, this, options);\n }\n \n this.triggerMethod('show', view, this, options);\n Marionette.triggerMethodOn(view, 'show', view, this, options);\n \n return this;\n }\n \n return this;\n },\n \n triggerBeforeAttach: true,\n triggerAttach: true,\n \n _triggerAttach: function(views, prefix) {\n var eventName = (prefix || '') + 'attach';\n _.each(views, function(view) {\n Marionette.triggerMethodOn(view, eventName, view, this);\n }, this);\n },\n \n _displayedViews: function(view) {\n return _.union([view], _.result(view, '_getNestedViews') || []);\n },\n \n _renderView: function(view) {\n if (!view.supportsRenderLifecycle) {\n Marionette.triggerMethodOn(view, 'before:render', view);\n }\n view.render();\n if (!view.supportsRenderLifecycle) {\n Marionette.triggerMethodOn(view, 'render', view);\n }\n },\n \n _ensureElement: function() {\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 if (this.getOption('allowMissingEl')) {\n return false;\n } else {\n throw new Marionette.Error('An \"el\" ' + this.$el.selector + ' must exist in DOM');\n }\n }\n return true;\n },\n \n _ensureViewIsIntact: function(view) {\n if (!view) {\n throw new Marionette.Error({\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 Marionette.Error({\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\n // element that it manages. Return a jQuery selector object scoped\n // to a provided parent el or the document if none exists.\n getEl: function(el) {\n return Backbone.$(el, Marionette._getValue(this.options.parentEl, this));\n },\n \n // Override this method to change how the new view is\n // appended to the `$el` that the region is managing\n attachHtml: function(view) {\n this.$el.contents().detach();\n \n this.el.appendChild(view.el);\n },\n \n // Destroy the current view, if there is one. If there is no\n // current view, it does nothing and returns immediately.\n empty: function(options) {\n var view = this.currentView;\n \n var emptyOptions = options || {};\n var preventDestroy = !!emptyOptions.preventDestroy;\n // If there is no view in the region\n // we should not remove anything\n if (!view) { return this; }\n \n view.off('destroy', this.empty, this);\n this.triggerMethod('before:empty', view);\n if (!preventDestroy) {\n this._destroyView();\n }\n this.triggerMethod('empty', view);\n \n // Remove region pointer to the currentView\n delete this.currentView;\n \n if (preventDestroy) {\n this.$el.contents().detach();\n }\n \n return this;\n },\n \n // call 'destroy' or 'remove', depending on which is found\n // on the view (if showing a raw Backbone view or a Marionette View)\n _destroyView: function() {\n var view = this.currentView;\n if (view.isDestroyed) { return; }\n \n if (!view.supportsDestroyLifecycle) {\n Marionette.triggerMethodOn(view, 'before:destroy', view);\n }\n if (view.destroy) {\n view.destroy();\n } else {\n view.remove();\n \n // appending isDestroyed to raw Backbone View allows regions\n // to throw a ViewDestroyedError for this view\n view.isDestroyed = true;\n }\n if (!view.supportsDestroyLifecycle) {\n Marionette.triggerMethodOn(view, 'destroy', view);\n }\n },\n \n // Attach an existing view to the region. This\n // will not call `render` or `onShow` for the new view,\n // and will not replace the current HTML for the `el`\n // of the region.\n attachView: function(view) {\n if (this.currentView) {\n delete this.currentView._parent;\n }\n view._parent = this;\n this.currentView = view;\n return this;\n },\n \n // Checks whether a view is currently present within\n // the region. Returns `true` if there is and `false` if\n // no view is present.\n hasView: function() {\n return !!this.currentView;\n },\n \n // Reset the region by destroying any existing view and\n // clearing out the cached `$el`. The next time a view\n // is shown via this region, the region will re-query the\n // DOM for the region's `el`.\n reset: function() {\n this.empty();\n \n if (this.$el) {\n this.el = this.$el.selector;\n }\n \n delete this.$el;\n return this;\n }\n \n },\n \n // Static Methods\n {\n \n // Build an instance of a region by passing in a configuration object\n // and a default region class to use if none is specified in the config.\n //\n // The config object should either be a string as a jQuery DOM selector,\n // a Region class directly, or an object literal that specifies a selector,\n // a custom regionClass, and any options to be supplied to the region:\n //\n // ```js\n // {\n // selector: \"#foo\",\n // regionClass: MyCustomRegion,\n // allowMissingEl: false\n // }\n // ```\n //\n buildRegion: function(regionConfig, DefaultRegionClass) {\n if (_.isString(regionConfig)) {\n return this._buildRegionFromSelector(regionConfig, DefaultRegionClass);\n }\n \n if (regionConfig.selector || regionConfig.el || regionConfig.regionClass) {\n return this._buildRegionFromObject(regionConfig, DefaultRegionClass);\n }\n \n if (_.isFunction(regionConfig)) {\n return this._buildRegionFromRegionClass(regionConfig);\n }\n \n throw new Marionette.Error({\n message: 'Improper region configuration type.',\n url: 'marionette.region.html#region-configuration-types'\n });\n },\n \n // Build the region from a string selector like '#foo-region'\n _buildRegionFromSelector: function(selector, DefaultRegionClass) {\n return new DefaultRegionClass({el: selector});\n },\n \n // Build the region from a configuration object\n // ```js\n // { selector: '#foo', regionClass: FooRegion, allowMissingEl: false }\n // ```\n _buildRegionFromObject: function(regionConfig, DefaultRegionClass) {\n var RegionClass = regionConfig.regionClass || DefaultRegionClass;\n var options = _.omit(regionConfig, 'selector', 'regionClass');\n \n if (regionConfig.selector && !options.el) {\n options.el = regionConfig.selector;\n }\n \n return new RegionClass(options);\n },\n \n // Build the region directly from a given `RegionClass`\n _buildRegionFromRegionClass: function(RegionClass) {\n return new RegionClass();\n }\n });\n \n // Region Manager\n // --------------\n \n // Manage one or more related `Marionette.Region` objects.\n Marionette.RegionManager = Marionette.Controller.extend({\n constructor: function(options) {\n this._regions = {};\n this.length = 0;\n \n Marionette.Controller.call(this, options);\n \n this.addRegions(this.getOption('regions'));\n },\n \n // Add multiple regions using an object literal or a\n // function that returns an object literal, where\n // each key becomes the region name, and each value is\n // the region definition.\n addRegions: function(regionDefinitions, defaults) {\n regionDefinitions = Marionette._getValue(regionDefinitions, this, arguments);\n \n return _.reduce(regionDefinitions, function(regions, definition, name) {\n if (_.isString(definition)) {\n definition = {selector: definition};\n }\n if (definition.selector) {\n definition = _.defaults({}, definition, defaults);\n }\n \n regions[name] = this.addRegion(name, definition);\n return regions;\n }, {}, this);\n },\n \n // Add an individual region to the region manager,\n // and return the region instance\n addRegion: function(name, definition) {\n var region;\n \n if (definition instanceof Marionette.Region) {\n region = definition;\n } else {\n region = Marionette.Region.buildRegion(definition, Marionette.Region);\n }\n \n this.triggerMethod('before:add:region', name, region);\n \n region._parent = this;\n this._store(name, region);\n \n this.triggerMethod('add:region', name, region);\n return region;\n },\n \n // Get a region by name\n get: function(name) {\n return this._regions[name];\n },\n \n // Gets all the regions contained within\n // the `regionManager` instance.\n getRegions: function() {\n return _.clone(this._regions);\n },\n \n // Remove a region by name\n removeRegion: function(name) {\n var region = this._regions[name];\n this._remove(name, region);\n \n return region;\n },\n \n // Empty all regions in the region manager, and\n // remove them\n removeRegions: function() {\n var regions = this.getRegions();\n _.each(this._regions, function(region, name) {\n this._remove(name, region);\n }, this);\n \n return regions;\n },\n \n // Empty all regions in the region manager, but\n // leave them attached\n emptyRegions: function() {\n var regions = this.getRegions();\n _.invoke(regions, 'empty');\n return regions;\n },\n \n // Destroy all regions and shut down the region\n // manager entirely\n destroy: function() {\n this.removeRegions();\n return Marionette.Controller.prototype.destroy.apply(this, arguments);\n },\n \n // internal method to store regions\n _store: function(name, region) {\n if (!this._regions[name]) {\n this.length++;\n }\n \n this._regions[name] = region;\n },\n \n // internal method to remove a region\n _remove: function(name, region) {\n this.triggerMethod('before:remove:region', name, region);\n region.empty();\n region.stopListening();\n \n delete region._parent;\n delete this._regions[name];\n this.length--;\n this.triggerMethod('remove:region', name, region);\n }\n });\n \n Marionette.actAsCollection(Marionette.RegionManager.prototype, '_regions');\n \n\n // Template Cache\n // --------------\n \n // Manage templates stored in `