Commit 73c9726a authored by Kevin Malakoff's avatar Kevin Malakoff

Resubmission of Knockback including an upgrade of Knockout to 2.0.0

parent 7a773a09
......@@ -59,6 +59,7 @@
<li><a href="http://documentcloud.github.com/backbone/">Backbone.js</a></li>
<li><a href="http://spinejs.com/">Spine.js</a></li>
<li><a href="http://sammyjs.org/">Sammy.js</a></li>
<li><a href="http://kmalakoff.github.com/knockback/">Knockback.js</a></li>
<li><a href="http://knockoutjs.com/">KnockoutJS</a></li>
<li><a href="http://developer.yahoo.com/yui/">YUILibrary</a></li>
<li><a href="http://angularjs.org/">AngularJS</a></li>
......@@ -84,6 +85,8 @@
<li><a href="todo-example/spine/index.html">Spine.js</a></li>
<li><a href="todo-example/backbone/index.html">Backbone.js</a></li>
<li><a href="todo-example/sammyjs/index.html">Sammy.js</a></li>
<li><a href="todo-example/knockback/todos-classic/index.html">Knockback.js (Classic)</a></li>
<li><a href="todo-example/knockback/todos-extended/index.html">Knockback.js (Extended)</a></li>
<li><a href="todo-example/knockoutjs/index.html">KnockoutJS (MVVM)</a></li>
<li><a href="todo-example/yuilibrary/index.html">YUILibrary</a></li>
<li><a href="todo-example/angularjs/main/index.html">AngularJS</a></li>
......@@ -104,6 +107,7 @@
<li><a href="http://developer.yahoo.com">The YUI team</a></li>
<li><a href="https://github.com/jacobmumm">Jacob Mumm</a></li>
<li><a href="https://github.com/brokenseal">Davide Callegari</a></li>
<li><a href="https://github.com/kmalakoff">Kevin Malakoff</a></li>
</ul>
<h5>Coming Soon</h5>
......
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-weight: inherit;
font-style: inherit;
font-size: 100%;
font-family: inherit;
vertical-align: baseline;
}
body {
line-height: 1;
color: black;
background: white;
}
ol, ul {
list-style: none;
}
a img {
border: none;
}
html {
background: #eeeeee;
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.4em;
background: #eeeeee;
color: #333333;
}
#todoapp {
position: relative;
width: 480px;
margin: 0 auto 40px;
background: white;
padding: 20px;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
}
#todoapp h1 {
font-size: 36px;
font-weight: bold;
text-align: center;
padding: 20px 0 30px 0;
line-height: 1;
}
#todoapp #color-settings {
position: absolute;
top: 30px;
right: 0;
}
#todoapp .priority-color-entry {
position: relative;
display: block;
width: 75px;
}
#todoapp .priority-text {
float: left;
width: 50px;
text-align: right;
padding-right: 8px;
line-height: 1.6em;
}
#todoapp .priority-color-swatch {
float: right;
height: 15px;
width: 15px;
border-style: solid;
border-width: 1px;
}
#todoapp .priority-color-swatch.colorpicker {
display: none;
}
#todoapp .priority-picker-tooltip {
width: 80px;
padding: 10px 5px;
margin-left: -40px;
left: 3px;
z-index: 10;
}
#create-todo {
position: relative;
}
#create-todo input {
width: 466px;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
padding: 6px;
border: 1px solid #999999;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
}
#create-todo input::-webkit-input-placeholder {
font-style: italic;
}
#create-todo span {
position: absolute;
z-index: 999;
width: 170px;
left: 50%;
margin-left: -85px;
}
#create-todo .priority-color-swatch.create {
position: absolute;
top: 2px;
right: 0;
}
#create-todo .priority-picker-tooltip {
top: 50px;
}
#todo-list {
margin-top: 10px;
}
#todo-list li {
padding: 12px 20px 11px 0;
position: relative;
font-size: 24px;
line-height: 1.1em;
border-bottom: 1px solid #cccccc;
}
#todo-list li:after {
content: "\0020";
display: block;
height: 0;
clear: both;
overflow: hidden;
visibility: hidden;
}
#todo-list li.editing {
padding: 0;
border-bottom: 0;
}
#todo-list .todo.done_enhanced .display {
height: 40px;
}
#todo-list .editing .display,
#todo-list .edit {
display: none;
}
#todo-list .editing .edit {
display: block;
}
#todo-list .editing input {
width: 444px;
font-size: 24px;
font-family: inherit;
margin: 0;
line-height: 1.6em;
border: 0;
outline: none;
padding: 10px 7px 0px 27px;
border: 1px solid #999999;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
}
#todo-list .check {
position: relative;
top: 9px;
margin: 0 10px 0 7px;
float: left;
}
#todo-list .priority-color-swatch.todo {
position: relative;
top: 6px;
margin: 0 10px 0 7px;
float: left;
}
#todo-list .priority-picker-tooltip {
top: 20px;
}
#todo-list .done .todo-text {
text-decoration: line-through;
color: #777777;
}
#todo-list .todo-done-text {
position: absolute;
bottom: 0;
left: 0;
font-size: 12px;
}
#todo-list .todo-destroy {
position: absolute;
right: 5px;
top: 14px;
display: none;
cursor: pointer;
width: 20px;
height: 20px;
background: url(images/destroy.png) no-repeat 0 0;
}
#todo-list .done .todo-destroy {
top: 20px;
}
#todo-list li:hover .todo-destroy {
display: block;
}
#todo-list .todo-destroy:hover {
background-position: 0 -20px;
}
.todo-list-sorting-wrapper-outer {
width: 100%;
height: 24px;
}
.todo-list-sorting-wrapper-inner {
clear: left;
float: left;
margin: 0;
padding: 0;
position: relative;
left: 50%;
}
#todo-list-sorting {
float:left;
position:relative;
right:50%;
}
#todo-stats {
*zoom: 1;
margin-top: 10px;
color: #777777;
}
#todo-stats:after {
content: "\0020";
display: block;
height: 0;
clear: both;
overflow: hidden;
visibility: hidden;
}
#todo-stats .todo-count {
float: left;
}
#todo-stats .todo-count .number {
font-weight: bold;
color: #333333;
}
#todo-stats .todo-clear {
float: right;
}
#todo-stats .todo-clear a {
color: #777777;
font-size: 12px;
}
#todo-stats .todo-clear a:visited {
color: #777777;
}
#todo-stats .todo-clear a:hover {
color: #336699;
}
#instructions {
width: 520px;
margin: 10px auto;
color: #777777;
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
text-align: center;
}
#instructions a {
color: #336699;
}
#credits {
width: 520px;
margin: 30px auto;
color: #999;
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
text-align: center;
}
#credits a {
color: #888;
}
/*
* François 'cahnory' Germain
*/
.ui-tooltip, .ui-tooltip-top, .ui-tooltip-right, .ui-tooltip-bottom, .ui-tooltip-left {
color:#ffffff;
cursor:normal;
display:-moz-inline-stack;
display:inline-block;
font-size:12px;
font-family:arial;
padding:.5em 1em;
position:relative;
text-align:center;
text-shadow:0 -1px 1px #111111;
-webkit-border-top-left-radius:4px ;
-webkit-border-top-right-radius:4px ;
-webkit-border-bottom-right-radius:4px ;
-webkit-border-bottom-left-radius:4px ;
-khtml-border-top-left-radius:4px ;
-khtml-border-top-right-radius:4px ;
-khtml-border-bottom-right-radius:4px ;
-khtml-border-bottom-left-radius:4px ;
-moz-border-radius-topleft:4px ;
-moz-border-radius-topright:4px ;
-moz-border-radius-bottomright:4px ;
-moz-border-radius-bottomleft:4px ;
border-top-left-radius:4px ;
border-top-right-radius:4px ;
border-bottom-right-radius:4px ;
border-bottom-left-radius:4px ;
-o-box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
-moz-box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
-khtml-box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
-webkit-box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
background-color:#3b3b3b;
background-image:-moz-linear-gradient(top,#555555,#222222);
background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#555555),color-stop(1,#222222));
filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#555555,EndColorStr=#222222);
-ms-filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#555555,EndColorStr=#222222);
}
.ui-tooltip:after, .ui-tooltip-top:after, .ui-tooltip-right:after, .ui-tooltip-bottom:after, .ui-tooltip-left:after {
content:"\25B8";
display:block;
font-size:2em;
height:0;
line-height:0;
position:absolute;
}
.ui-tooltip:after, .ui-tooltip-bottom:after {
color:#2a2a2a;
bottom:0;
left:1px;
text-align:center;
text-shadow:1px 0 2px #000000;
-o-transform:rotate(90deg);
-moz-transform:rotate(90deg);
-khtml-transform:rotate(90deg);
-webkit-transform:rotate(90deg);
width:100%;
}
.ui-tooltip-top:after {
bottom:auto;
color:#4f4f4f;
left:-2px;
top:0;
text-align:center;
text-shadow:none;
-o-transform:rotate(-90deg);
-moz-transform:rotate(-90deg);
-khtml-transform:rotate(-90deg);
-webkit-transform:rotate(-90deg);
width:100%;
}
.ui-tooltip-right:after {
color:#222222;
right:-0.375em;
top:50%;
margin-top:-.05em;
text-shadow:0 1px 2px #000000;
-o-transform:rotate(0);
-moz-transform:rotate(0);
-khtml-transform:rotate(0);
-webkit-transform:rotate(0);
}
.ui-tooltip-left:after {
color:#222222;
left:-0.375em;
top:50%;
margin-top:.1em;
text-shadow:0 -1px 2px #000000;
-o-transform:rotate(180deg);
-moz-transform:rotate(180deg);
-khtml-transform:rotate(180deg);
-webkit-transform:rotate(180deg);
}
#todo-languages {
position: absolute;
right: 10px;
bottom: 5px;
}
.selection {
border: 1px solid #ccc;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
display: inline-block;
vertical-align: middle;
border-width: 1px;
border-style: solid;
border-color: #333 #666 #fff;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #777), color-stop(1, #999));
background: -webkit-linear-gradient(top, #777 0%, #999 100%);
background: -moz-linear-gradient(top, #777 0%, #999 100%);
background: linear-gradient(top, #777 0%, #999 100%);
}
.selection .option {
display: inline-block;
vertical-align: middle;
}
.selection .option input[type="radio"] {
display: none;
}
.selection .option input[type="radio"] + label {
display: inline-block;
background: none transparent;
margin: -1px -1px 0;
padding: 0.5ex 1ex;
vertical-align: middle;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
cursor: pointer;
}
.selection .option input[type="radio"]:checked + label {
background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #666), color-stop(1, #333));
background: -webkit-linear-gradient(top, #666 0%, #333 100%);
background: -moz-linear-gradient(top, #666 0%, #333 100%);
background: linear-gradient(top, #666 0%, #333 100%);
color: #fff;
text-shadow: 0px 1px 0px rgba(255,255,255,0.00), 0px -1px 0px #000;
-webkit-box-shadow: inset 0px 0px 0px 1px rgba(0,0,0,0.40);
-moz-box-shadow: inset 0px 0px 0px 1px rgba(0,0,0,0.40);
box-shadow: inset 0px 0px 0px 1px rgba(0,0,0,0.40);
cursor: default;
}
// Backbone.js 0.5.3
// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
// Backbone may be freely distributed under the MIT license.
// For all details and documentation:
// http://documentcloud.github.com/backbone
(function(){
// Initial Setup
// -------------
// Save a reference to the global object.
var root = this;
// Save the previous value of the `Backbone` variable.
var previousBackbone = root.Backbone;
// The top-level namespace. All public Backbone classes and modules will
// be attached to this. Exported for both CommonJS and the browser.
var Backbone;
if (typeof exports !== 'undefined') {
Backbone = exports;
} else {
Backbone = root.Backbone = {};
}
// Current version of the library. Keep in sync with `package.json`.
Backbone.VERSION = '0.5.3';
// Require Underscore, if we're on the server, and it's not already present.
var _ = root._;
if (!_ && (typeof require !== 'undefined')) _ = require('underscore')._;
// For Backbone's purposes, jQuery or Zepto owns the `$` variable.
var $ = root.jQuery || root.Zepto;
// Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
// to its previous owner. Returns a reference to this Backbone object.
Backbone.noConflict = function() {
root.Backbone = previousBackbone;
return this;
};
// Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option will
// fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and set a
// `X-Http-Method-Override` header.
Backbone.emulateHTTP = false;
// Turn on `emulateJSON` to support legacy servers that can't deal with direct
// `application/json` requests ... will encode the body as
// `application/x-www-form-urlencoded` instead and will send the model in a
// form param named `model`.
Backbone.emulateJSON = false;
// Backbone.Events
// -----------------
// A module that can be mixed in to *any object* in order to provide it with
// custom events. You may `bind` or `unbind` a callback function to an event;
// `trigger`-ing an event fires all callbacks in succession.
//
// var object = {};
// _.extend(object, Backbone.Events);
// object.bind('expand', function(){ alert('expanded'); });
// object.trigger('expand');
//
Backbone.Events = {
// Bind an event, specified by a string name, `ev`, to a `callback` function.
// Passing `"all"` will bind the callback to all events fired.
bind : function(ev, callback, context) {
var calls = this._callbacks || (this._callbacks = {});
var list = calls[ev] || (calls[ev] = []);
list.push([callback, context]);
return this;
},
// Remove one or many callbacks. If `callback` is null, removes all
// callbacks for the event. If `ev` is null, removes all bound callbacks
// for all events.
unbind : function(ev, callback) {
var calls;
if (!ev) {
this._callbacks = {};
} else if (calls = this._callbacks) {
if (!callback) {
calls[ev] = [];
} else {
var list = calls[ev];
if (!list) return this;
for (var i = 0, l = list.length; i < l; i++) {
if (list[i] && callback === list[i][0]) {
list[i] = null;
break;
}
}
}
}
return this;
},
// Trigger an event, firing all bound callbacks. Callbacks are passed the
// same arguments as `trigger` is, apart from the event name.
// Listening for `"all"` passes the true event name as the first argument.
trigger : function(eventName) {
var list, calls, ev, callback, args;
var both = 2;
if (!(calls = this._callbacks)) return this;
while (both--) {
ev = both ? eventName : 'all';
if (list = calls[ev]) {
for (var i = 0, l = list.length; i < l; i++) {
if (!(callback = list[i])) {
list.splice(i, 1); i--; l--;
} else {
args = both ? Array.prototype.slice.call(arguments, 1) : arguments;
callback[0].apply(callback[1] || this, args);
}
}
}
}
return this;
}
};
// Backbone.Model
// --------------
// Create a new model, with defined attributes. A client id (`cid`)
// is automatically generated and assigned for you.
Backbone.Model = function(attributes, options) {
var defaults;
attributes || (attributes = {});
if (defaults = this.defaults) {
if (_.isFunction(defaults)) defaults = defaults.call(this);
attributes = _.extend({}, defaults, attributes);
}
this.attributes = {};
this._escapedAttributes = {};
this.cid = _.uniqueId('c');
this.set(attributes, {silent : true});
this._changed = false;
this._previousAttributes = _.clone(this.attributes);
if (options && options.collection) this.collection = options.collection;
this.initialize(attributes, options);
};
// Attach all inheritable methods to the Model prototype.
_.extend(Backbone.Model.prototype, Backbone.Events, {
// A snapshot of the model's previous attributes, taken immediately
// after the last `"change"` event was fired.
_previousAttributes : null,
// Has the item been changed since the last `"change"` event?
_changed : false,
// The default name for the JSON `id` attribute is `"id"`. MongoDB and
// CouchDB users may want to set this to `"_id"`.
idAttribute : 'id',
// Initialize is an empty function by default. Override it with your own
// initialization logic.
initialize : function(){},
// Return a copy of the model's `attributes` object.
toJSON : function() {
return _.clone(this.attributes);
},
// Get the value of an attribute.
get : function(attr) {
return this.attributes[attr];
},
// Get the HTML-escaped value of an attribute.
escape : function(attr) {
var html;
if (html = this._escapedAttributes[attr]) return html;
var val = this.attributes[attr];
return this._escapedAttributes[attr] = escapeHTML(val == null ? '' : '' + val);
},
// Returns `true` if the attribute contains a value that is not null
// or undefined.
has : function(attr) {
return this.attributes[attr] != null;
},
// Set a hash of model attributes on the object, firing `"change"` unless you
// choose to silence it.
set : function(attrs, options) {
// Extract attributes and options.
options || (options = {});
if (!attrs) return this;
if (attrs.attributes) attrs = attrs.attributes;
var now = this.attributes, escaped = this._escapedAttributes;
// Run validation.
if (!options.silent && this.validate && !this._performValidation(attrs, options)) return false;
// Check for changes of `id`.
if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
// We're about to start triggering change events.
var alreadyChanging = this._changing;
this._changing = true;
// Update attributes.
for (var attr in attrs) {
var val = attrs[attr];
if (!_.isEqual(now[attr], val)) {
now[attr] = val;
delete escaped[attr];
this._changed = true;
if (!options.silent) this.trigger('change:' + attr, this, val, options);
}
}
// Fire the `"change"` event, if the model has been changed.
if (!alreadyChanging && !options.silent && this._changed) this.change(options);
this._changing = false;
return this;
},
// Remove an attribute from the model, firing `"change"` unless you choose
// to silence it. `unset` is a noop if the attribute doesn't exist.
unset : function(attr, options) {
if (!(attr in this.attributes)) return this;
options || (options = {});
var value = this.attributes[attr];
// Run validation.
var validObj = {};
validObj[attr] = void 0;
if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;
// Remove the attribute.
delete this.attributes[attr];
delete this._escapedAttributes[attr];
if (attr == this.idAttribute) delete this.id;
this._changed = true;
if (!options.silent) {
this.trigger('change:' + attr, this, void 0, options);
this.change(options);
}
return this;
},
// Clear all attributes on the model, firing `"change"` unless you choose
// to silence it.
clear : function(options) {
options || (options = {});
var attr;
var old = this.attributes;
// Run validation.
var validObj = {};
for (attr in old) validObj[attr] = void 0;
if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;
this.attributes = {};
this._escapedAttributes = {};
this._changed = true;
if (!options.silent) {
for (attr in old) {
this.trigger('change:' + attr, this, void 0, options);
}
this.change(options);
}
return this;
},
// Fetch the model from the server. If the server's representation of the
// model differs from its current attributes, they will be overriden,
// triggering a `"change"` event.
fetch : function(options) {
options || (options = {});
var model = this;
var success = options.success;
options.success = function(resp, status, xhr) {
if (!model.set(model.parse(resp, xhr), options)) return false;
if (success) success(model, resp);
};
options.error = wrapError(options.error, model, options);
return (this.sync || Backbone.sync).call(this, 'read', this, options);
},
// Set a hash of model attributes, and sync the model to the server.
// If the server returns an attributes hash that differs, the model's
// state will be `set` again.
save : function(attrs, options) {
options || (options = {});
if (attrs && !this.set(attrs, options)) return false;
var model = this;
var success = options.success;
options.success = function(resp, status, xhr) {
if (!model.set(model.parse(resp, xhr), options)) return false;
if (success) success(model, resp, xhr);
};
options.error = wrapError(options.error, model, options);
var method = this.isNew() ? 'create' : 'update';
return (this.sync || Backbone.sync).call(this, method, this, options);
},
// Destroy this model on the server if it was already persisted. Upon success, the model is removed
// from its collection, if it has one.
destroy : function(options) {
options || (options = {});
if (this.isNew()) return this.trigger('destroy', this, this.collection, options);
var model = this;
var success = options.success;
options.success = function(resp) {
model.trigger('destroy', model, model.collection, options);
if (success) success(model, resp);
};
options.error = wrapError(options.error, model, options);
return (this.sync || Backbone.sync).call(this, 'delete', this, options);
},
// Default URL for the model's representation on the server -- if you're
// using Backbone's restful methods, override this to change the endpoint
// that will be called.
url : function() {
var base = getUrl(this.collection) || this.urlRoot || urlError();
if (this.isNew()) return base;
return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
},
// **parse** converts a response into the hash of attributes to be `set` on
// the model. The default implementation is just to pass the response along.
parse : function(resp, xhr) {
return resp;
},
// Create a new model with identical attributes to this one.
clone : function() {
return new this.constructor(this);
},
// A model is new if it has never been saved to the server, and lacks an id.
isNew : function() {
return this.id == null;
},
// Call this method to manually fire a `change` event for this model.
// Calling this will cause all objects observing the model to update.
change : function(options) {
this.trigger('change', this, options);
this._previousAttributes = _.clone(this.attributes);
this._changed = false;
},
// Determine if the model has changed since the last `"change"` event.
// If you specify an attribute name, determine if that attribute has changed.
hasChanged : function(attr) {
if (attr) return this._previousAttributes[attr] != this.attributes[attr];
return this._changed;
},
// Return an object containing all the attributes that have changed, or false
// if there are no changed attributes. Useful for determining what parts of a
// view need to be updated and/or what attributes need to be persisted to
// the server.
changedAttributes : function(now) {
now || (now = this.attributes);
var old = this._previousAttributes;
var changed = false;
for (var attr in now) {
if (!_.isEqual(old[attr], now[attr])) {
changed = changed || {};
changed[attr] = now[attr];
}
}
return changed;
},
// Get the previous value of an attribute, recorded at the time the last
// `"change"` event was fired.
previous : function(attr) {
if (!attr || !this._previousAttributes) return null;
return this._previousAttributes[attr];
},
// Get all of the attributes of the model at the time of the previous
// `"change"` event.
previousAttributes : function() {
return _.clone(this._previousAttributes);
},
// Run validation against a set of incoming attributes, returning `true`
// if all is well. If a specific `error` callback has been passed,
// call that instead of firing the general `"error"` event.
_performValidation : function(attrs, options) {
var error = this.validate(attrs);
if (error) {
if (options.error) {
options.error(this, error, options);
} else {
this.trigger('error', this, error, options);
}
return false;
}
return true;
}
});
// Backbone.Collection
// -------------------
// Provides a standard collection class for our sets of models, ordered
// or unordered. If a `comparator` is specified, the Collection will maintain
// its models in sort order, as they're added and removed.
Backbone.Collection = function(models, options) {
options || (options = {});
if (options.comparator) this.comparator = options.comparator;
_.bindAll(this, '_onModelEvent', '_removeReference');
this._reset();
if (models) this.reset(models, {silent: true});
this.initialize.apply(this, arguments);
};
// Define the Collection's inheritable methods.
_.extend(Backbone.Collection.prototype, Backbone.Events, {
// The default model for a collection is just a **Backbone.Model**.
// This should be overridden in most cases.
model : Backbone.Model,
// Initialize is an empty function by default. Override it with your own
// initialization logic.
initialize : function(){},
// The JSON representation of a Collection is an array of the
// models' attributes.
toJSON : function() {
return this.map(function(model){ return model.toJSON(); });
},
// Add a model, or list of models to the set. Pass **silent** to avoid
// firing the `added` event for every new model.
add : function(models, options) {
if (_.isArray(models)) {
for (var i = 0, l = models.length; i < l; i++) {
this._add(models[i], options);
}
} else {
this._add(models, options);
}
return this;
},
// Remove a model, or a list of models from the set. Pass silent to avoid
// firing the `removed` event for every model removed.
remove : function(models, options) {
if (_.isArray(models)) {
for (var i = 0, l = models.length; i < l; i++) {
this._remove(models[i], options);
}
} else {
this._remove(models, options);
}
return this;
},
// Get a model from the set by id.
get : function(id) {
if (id == null) return null;
return this._byId[id.id != null ? id.id : id];
},
// Get a model from the set by client id.
getByCid : function(cid) {
return cid && this._byCid[cid.cid || cid];
},
// Get the model at the given index.
at: function(index) {
return this.models[index];
},
// Force the collection to re-sort itself. You don't need to call this under normal
// circumstances, as the set will maintain sort order as each item is added.
sort : function(options) {
options || (options = {});
if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
this.models = this.sortBy(this.comparator);
if (!options.silent) this.trigger('reset', this, options);
return this;
},
// Pluck an attribute from each model in the collection.
pluck : function(attr) {
return _.map(this.models, function(model){ return model.get(attr); });
},
// When you have more items than you want to add or remove individually,
// you can reset the entire set with a new list of models, without firing
// any `added` or `removed` events. Fires `reset` when finished.
reset : function(models, options) {
models || (models = []);
options || (options = {});
this.each(this._removeReference);
this._reset();
this.add(models, {silent: true});
if (!options.silent) this.trigger('reset', this, options);
return this;
},
// Fetch the default set of models for this collection, resetting the
// collection when they arrive. If `add: true` is passed, appends the
// models to the collection instead of resetting.
fetch : function(options) {
options || (options = {});
var collection = this;
var success = options.success;
options.success = function(resp, status, xhr) {
collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
if (success) success(collection, resp);
};
options.error = wrapError(options.error, collection, options);
return (this.sync || Backbone.sync).call(this, 'read', this, options);
},
// Create a new instance of a model in this collection. After the model
// has been created on the server, it will be added to the collection.
// Returns the model, or 'false' if validation on a new model fails.
create : function(model, options) {
var coll = this;
options || (options = {});
model = this._prepareModel(model, options);
if (!model) return false;
var success = options.success;
options.success = function(nextModel, resp, xhr) {
coll.add(nextModel, options);
if (success) success(nextModel, resp, xhr);
};
model.save(null, options);
return model;
},
// **parse** converts a response into a list of models to be added to the
// collection. The default implementation is just to pass it through.
parse : function(resp, xhr) {
return resp;
},
// Proxy to _'s chain. Can't be proxied the same way the rest of the
// underscore methods are proxied because it relies on the underscore
// constructor.
chain: function () {
return _(this.models).chain();
},
// Reset all internal state. Called when the collection is reset.
_reset : function(options) {
this.length = 0;
this.models = [];
this._byId = {};
this._byCid = {};
},
// Prepare a model to be added to this collection
_prepareModel: function(model, options) {
if (!(model instanceof Backbone.Model)) {
var attrs = model;
model = new this.model(attrs, {collection: this});
if (model.validate && !model._performValidation(attrs, options)) model = false;
} else if (!model.collection) {
model.collection = this;
}
return model;
},
// Internal implementation of adding a single model to the set, updating
// hash indexes for `id` and `cid` lookups.
// Returns the model, or 'false' if validation on a new model fails.
_add : function(model, options) {
options || (options = {});
model = this._prepareModel(model, options);
if (!model) return false;
var already = this.getByCid(model);
if (already) throw new Error(["Can't add the same model to a set twice", already.id]);
this._byId[model.id] = model;
this._byCid[model.cid] = model;
var index = options.at != null ? options.at :
this.comparator ? this.sortedIndex(model, this.comparator) :
this.length;
this.models.splice(index, 0, model);
model.bind('all', this._onModelEvent);
this.length++;
if (!options.silent) model.trigger('add', model, this, options);
return model;
},
// Internal implementation of removing a single model from the set, updating
// hash indexes for `id` and `cid` lookups.
_remove : function(model, options) {
options || (options = {});
model = this.getByCid(model) || this.get(model);
if (!model) return null;
delete this._byId[model.id];
delete this._byCid[model.cid];
this.models.splice(this.indexOf(model), 1);
this.length--;
if (!options.silent) model.trigger('remove', model, this, options);
this._removeReference(model);
return model;
},
// Internal method to remove a model's ties to a collection.
_removeReference : function(model) {
if (this == model.collection) {
delete model.collection;
}
model.unbind('all', this._onModelEvent);
},
// Internal method called every time a model in the set fires an event.
// Sets need to update their indexes when models change ids. All other
// events simply proxy through. "add" and "remove" events that originate
// in other collections are ignored.
_onModelEvent : function(ev, model, collection, options) {
if ((ev == 'add' || ev == 'remove') && collection != this) return;
if (ev == 'destroy') {
this._remove(model, options);
}
if (model && ev === 'change:' + model.idAttribute) {
delete this._byId[model.previous(model.idAttribute)];
this._byId[model.id] = model;
}
this.trigger.apply(this, arguments);
}
});
// Underscore methods that we want to implement on the Collection.
var methods = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find', 'detect',
'filter', 'select', 'reject', 'every', 'all', 'some', 'any', 'include',
'contains', 'invoke', 'max', 'min', 'sortBy', 'sortedIndex', 'toArray', 'size',
'first', 'rest', 'last', 'without', 'indexOf', 'lastIndexOf', 'isEmpty', 'groupBy'];
// Mix in each Underscore method as a proxy to `Collection#models`.
_.each(methods, function(method) {
Backbone.Collection.prototype[method] = function() {
return _[method].apply(_, [this.models].concat(_.toArray(arguments)));
};
});
// Backbone.Router
// -------------------
// Routers map faux-URLs to actions, and fire events when routes are
// matched. Creating a new one sets its `routes` hash, if not set statically.
Backbone.Router = function(options) {
options || (options = {});
if (options.routes) this.routes = options.routes;
this._bindRoutes();
this.initialize.apply(this, arguments);
};
// Cached regular expressions for matching named param parts and splatted
// parts of route strings.
var namedParam = /:([\w\d]+)/g;
var splatParam = /\*([\w\d]+)/g;
var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g;
// Set up all inheritable **Backbone.Router** properties and methods.
_.extend(Backbone.Router.prototype, Backbone.Events, {
// Initialize is an empty function by default. Override it with your own
// initialization logic.
initialize : function(){},
// Manually bind a single named route to a callback. For example:
//
// this.route('search/:query/p:num', 'search', function(query, num) {
// ...
// });
//
route : function(route, name, callback) {
Backbone.history || (Backbone.history = new Backbone.History);
if (!_.isRegExp(route)) route = this._routeToRegExp(route);
Backbone.history.route(route, _.bind(function(fragment) {
var args = this._extractParameters(route, fragment);
callback.apply(this, args);
this.trigger.apply(this, ['route:' + name].concat(args));
}, this));
},
// Simple proxy to `Backbone.history` to save a fragment into the history.
navigate : function(fragment, triggerRoute) {
Backbone.history.navigate(fragment, triggerRoute);
},
// Bind all defined routes to `Backbone.history`. We have to reverse the
// order of the routes here to support behavior where the most general
// routes can be defined at the bottom of the route map.
_bindRoutes : function() {
if (!this.routes) return;
var routes = [];
for (var route in this.routes) {
routes.unshift([route, this.routes[route]]);
}
for (var i = 0, l = routes.length; i < l; i++) {
this.route(routes[i][0], routes[i][1], this[routes[i][1]]);
}
},
// Convert a route string into a regular expression, suitable for matching
// against the current location hash.
_routeToRegExp : function(route) {
route = route.replace(escapeRegExp, "\\$&")
.replace(namedParam, "([^\/]*)")
.replace(splatParam, "(.*?)");
return new RegExp('^' + route + '$');
},
// Given a route, and a URL fragment that it matches, return the array of
// extracted parameters.
_extractParameters : function(route, fragment) {
return route.exec(fragment).slice(1);
}
});
// Backbone.History
// ----------------
// Handles cross-browser history management, based on URL fragments. If the
// browser does not support `onhashchange`, falls back to polling.
Backbone.History = function() {
this.handlers = [];
_.bindAll(this, 'checkUrl');
};
// Cached regex for cleaning hashes.
var hashStrip = /^#*/;
// Cached regex for detecting MSIE.
var isExplorer = /msie [\w.]+/;
// Has the history handling already been started?
var historyStarted = false;
// Set up all inheritable **Backbone.History** properties and methods.
_.extend(Backbone.History.prototype, {
// The default interval to poll for hash changes, if necessary, is
// twenty times a second.
interval: 50,
// Get the cross-browser normalized URL fragment, either from the URL,
// the hash, or the override.
getFragment : function(fragment, forcePushState) {
if (fragment == null) {
if (this._hasPushState || forcePushState) {
fragment = window.location.pathname;
var search = window.location.search;
if (search) fragment += search;
if (fragment.indexOf(this.options.root) == 0) fragment = fragment.substr(this.options.root.length);
} else {
fragment = window.location.hash;
}
}
return decodeURIComponent(fragment.replace(hashStrip, ''));
},
// Start the hash change handling, returning `true` if the current URL matches
// an existing route, and `false` otherwise.
start : function(options) {
// Figure out the initial configuration. Do we need an iframe?
// Is pushState desired ... is it available?
if (historyStarted) throw new Error("Backbone.history has already been started");
this.options = _.extend({}, {root: '/'}, this.options, options);
this._wantsPushState = !!this.options.pushState;
this._hasPushState = !!(this.options.pushState && window.history && window.history.pushState);
var fragment = this.getFragment();
var docMode = document.documentMode;
var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
if (oldIE) {
this.iframe = $('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
this.navigate(fragment);
}
// Depending on whether we're using pushState or hashes, and whether
// 'onhashchange' is supported, determine how we check the URL state.
if (this._hasPushState) {
$(window).bind('popstate', this.checkUrl);
} else if ('onhashchange' in window && !oldIE) {
$(window).bind('hashchange', this.checkUrl);
} else {
setInterval(this.checkUrl, this.interval);
}
// Determine if we need to change the base url, for a pushState link
// opened by a non-pushState browser.
this.fragment = fragment;
historyStarted = true;
var loc = window.location;
var atRoot = loc.pathname == this.options.root;
if (this._wantsPushState && !this._hasPushState && !atRoot) {
this.fragment = this.getFragment(null, true);
window.location.replace(this.options.root + '#' + this.fragment);
// Return immediately as browser will do redirect to new url
return true;
} else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
this.fragment = loc.hash.replace(hashStrip, '');
window.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment);
}
if (!this.options.silent) {
return this.loadUrl();
}
},
// Add a route to be tested when the fragment changes. Routes added later may
// override previous routes.
route : function(route, callback) {
this.handlers.unshift({route : route, callback : callback});
},
// Checks the current URL to see if it has changed, and if it has,
// calls `loadUrl`, normalizing across the hidden iframe.
checkUrl : function(e) {
var current = this.getFragment();
if (current == this.fragment && this.iframe) current = this.getFragment(this.iframe.location.hash);
if (current == this.fragment || current == decodeURIComponent(this.fragment)) return false;
if (this.iframe) this.navigate(current);
this.loadUrl() || this.loadUrl(window.location.hash);
},
// Attempt to load the current URL fragment. If a route succeeds with a
// match, returns `true`. If no defined routes matches the fragment,
// returns `false`.
loadUrl : function(fragmentOverride) {
var fragment = this.fragment = this.getFragment(fragmentOverride);
var matched = _.any(this.handlers, function(handler) {
if (handler.route.test(fragment)) {
handler.callback(fragment);
return true;
}
});
return matched;
},
// Save a fragment into the hash history. You are responsible for properly
// URL-encoding the fragment in advance. This does not trigger
// a `hashchange` event.
navigate : function(fragment, triggerRoute) {
var frag = (fragment || '').replace(hashStrip, '');
if (this.fragment == frag || this.fragment == decodeURIComponent(frag)) return;
if (this._hasPushState) {
var loc = window.location;
if (frag.indexOf(this.options.root) != 0) frag = this.options.root + frag;
this.fragment = frag;
window.history.pushState({}, document.title, loc.protocol + '//' + loc.host + frag);
} else {
window.location.hash = this.fragment = frag;
if (this.iframe && (frag != this.getFragment(this.iframe.location.hash))) {
this.iframe.document.open().close();
this.iframe.location.hash = frag;
}
}
if (triggerRoute) this.loadUrl(fragment);
}
});
// Backbone.View
// -------------
// Creating a Backbone.View creates its initial element outside of the DOM,
// if an existing element is not provided...
Backbone.View = function(options) {
this.cid = _.uniqueId('view');
this._configure(options || {});
this._ensureElement();
this.delegateEvents();
this.initialize.apply(this, arguments);
};
// Element lookup, scoped to DOM elements within the current view.
// This should be prefered to global lookups, if you're dealing with
// a specific view.
var selectorDelegate = function(selector) {
return $(selector, this.el);
};
// Cached regex to split keys for `delegate`.
var eventSplitter = /^(\S+)\s*(.*)$/;
// List of view options to be merged as properties.
var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName'];
// Set up all inheritable **Backbone.View** properties and methods.
_.extend(Backbone.View.prototype, Backbone.Events, {
// The default `tagName` of a View's element is `"div"`.
tagName : 'div',
// Attach the `selectorDelegate` function as the `$` property.
$ : selectorDelegate,
// Initialize is an empty function by default. Override it with your own
// initialization logic.
initialize : function(){},
// **render** is the core function that your view should override, in order
// to populate its element (`this.el`), with the appropriate HTML. The
// convention is for **render** to always return `this`.
render : function() {
return this;
},
// Remove this view from the DOM. Note that the view isn't present in the
// DOM by default, so calling this method may be a no-op.
remove : function() {
$(this.el).remove();
return this;
},
// For small amounts of DOM Elements, where a full-blown template isn't
// needed, use **make** to manufacture elements, one at a time.
//
// var el = this.make('li', {'class': 'row'}, this.model.escape('title'));
//
make : function(tagName, attributes, content) {
var el = document.createElement(tagName);
if (attributes) $(el).attr(attributes);
if (content) $(el).html(content);
return el;
},
// Set callbacks, where `this.callbacks` is a hash of
//
// *{"event selector": "callback"}*
//
// {
// 'mousedown .title': 'edit',
// 'click .button': 'save'
// }
//
// pairs. Callbacks will be bound to the view, with `this` set properly.
// Uses event delegation for efficiency.
// Omitting the selector binds the event to `this.el`.
// This only works for delegate-able events: not `focus`, `blur`, and
// not `change`, `submit`, and `reset` in Internet Explorer.
delegateEvents : function(events) {
if (!(events || (events = this.events))) return;
if (_.isFunction(events)) events = events.call(this);
$(this.el).unbind('.delegateEvents' + this.cid);
for (var key in events) {
var method = this[events[key]];
if (!method) throw new Error('Event "' + events[key] + '" does not exist');
var match = key.match(eventSplitter);
var eventName = match[1], selector = match[2];
method = _.bind(method, this);
eventName += '.delegateEvents' + this.cid;
if (selector === '') {
$(this.el).bind(eventName, method);
} else {
$(this.el).delegate(selector, eventName, method);
}
}
},
// Performs the initial configuration of a View with a set of options.
// Keys with special meaning *(model, collection, id, className)*, are
// attached directly to the view.
_configure : function(options) {
if (this.options) options = _.extend({}, this.options, options);
for (var i = 0, l = viewOptions.length; i < l; i++) {
var attr = viewOptions[i];
if (options[attr]) this[attr] = options[attr];
}
this.options = options;
},
// Ensure that the View has a DOM element to render into.
// If `this.el` is a string, pass it through `$()`, take the first
// matching element, and re-assign it to `el`. Otherwise, create
// an element from the `id`, `className` and `tagName` proeprties.
_ensureElement : function() {
if (!this.el) {
var attrs = this.attributes || {};
if (this.id) attrs.id = this.id;
if (this.className) attrs['class'] = this.className;
this.el = this.make(this.tagName, attrs);
} else if (_.isString(this.el)) {
this.el = $(this.el).get(0);
}
}
});
// The self-propagating extend function that Backbone classes use.
var extend = function (protoProps, classProps) {
var child = inherits(this, protoProps, classProps);
child.extend = this.extend;
return child;
};
// Set up inheritance for the model, collection, and view.
Backbone.Model.extend = Backbone.Collection.extend =
Backbone.Router.extend = Backbone.View.extend = extend;
// Map from CRUD to HTTP for our default `Backbone.sync` implementation.
var methodMap = {
'create': 'POST',
'update': 'PUT',
'delete': 'DELETE',
'read' : 'GET'
};
// Backbone.sync
// -------------
// Override this function to change the manner in which Backbone persists
// models to the server. You will be passed the type of request, and the
// model in question. By default, uses makes a RESTful Ajax request
// to the model's `url()`. Some possible customizations could be:
//
// * Use `setTimeout` to batch rapid-fire updates into a single request.
// * Send up the models as XML instead of JSON.
// * Persist models via WebSockets instead of Ajax.
//
// Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
// as `POST`, with a `_method` parameter containing the true HTTP method,
// as well as all requests with the body as `application/x-www-form-urlencoded` instead of
// `application/json` with the model in a param named `model`.
// Useful when interfacing with server-side languages like **PHP** that make
// it difficult to read the body of `PUT` requests.
Backbone.sync = function(method, model, options) {
var type = methodMap[method];
// Default JSON-request options.
var params = _.extend({
type: type,
dataType: 'json'
}, options);
// Ensure that we have a URL.
if (!params.url) {
params.url = getUrl(model) || urlError();
}
// Ensure that we have the appropriate request data.
if (!params.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
params.data = JSON.stringify(model.toJSON());
}
// For older servers, emulate JSON by encoding the request into an HTML-form.
if (Backbone.emulateJSON) {
params.contentType = 'application/x-www-form-urlencoded';
params.data = params.data ? {model : params.data} : {};
}
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
// And an `X-HTTP-Method-Override` header.
if (Backbone.emulateHTTP) {
if (type === 'PUT' || type === 'DELETE') {
if (Backbone.emulateJSON) params.data._method = type;
params.type = 'POST';
params.beforeSend = function(xhr) {
xhr.setRequestHeader('X-HTTP-Method-Override', type);
};
}
}
// Don't process data on a non-GET request.
if (params.type !== 'GET' && !Backbone.emulateJSON) {
params.processData = false;
}
// Make the request.
return $.ajax(params);
};
// Helpers
// -------
// Shared empty constructor function to aid in prototype-chain creation.
var ctor = function(){};
// Helper function to correctly set up the prototype chain, for subclasses.
// Similar to `goog.inherits`, but uses a hash of prototype properties and
// class properties to be extended.
var inherits = function(parent, protoProps, staticProps) {
var child;
// The constructor function for the new subclass is either defined by you
// (the "constructor" property in your `extend` definition), or defaulted
// by us to simply call `super()`.
if (protoProps && protoProps.hasOwnProperty('constructor')) {
child = protoProps.constructor;
} else {
child = function(){ return parent.apply(this, arguments); };
}
// Inherit class (static) properties from parent.
_.extend(child, parent);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function.
ctor.prototype = parent.prototype;
child.prototype = new ctor();
// Add prototype properties (instance properties) to the subclass,
// if supplied.
if (protoProps) _.extend(child.prototype, protoProps);
// Add static properties to the constructor function, if supplied.
if (staticProps) _.extend(child, staticProps);
// Correctly set child's `prototype.constructor`.
child.prototype.constructor = child;
// Set a convenience property in case the parent's prototype is needed later.
child.__super__ = parent.prototype;
return child;
};
// Helper function to get a URL from a Model or Collection as a property
// or as a function.
var getUrl = function(object) {
if (!(object && object.url)) return null;
return _.isFunction(object.url) ? object.url() : object.url;
};
// Throw an error when a URL is needed, and none is supplied.
var urlError = function() {
throw new Error('A "url" property or function must be specified');
};
// Wrap an optional error callback with a fallback error event.
var wrapError = function(onError, model, options) {
return function(resp) {
if (onError) {
onError(model, resp, options);
} else {
model.trigger('error', model, resp, options);
}
};
};
// Helper function to escape a string for HTML rendering.
var escapeHTML = function(string) {
return string.replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
};
}).call(this);
/*
knockback.js 0.12.0
(c) 2011 Kevin Malakoff.
Knockback.js is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
Dependencies: Knockout.js, Backbone.js, and Underscore.js.
Optional dependency: Backbone.ModelRef.js.
*/if (!this.ko) {
throw new Error('Knockback: Dependency alert! Knockout.js must be included before this file');
}
if (!this.Backbone) {
throw new Error('Knockback: Dependency alert! Backbone.js must be included before this file');
}
if (!this._ || !this._.VERSION) {
throw new Error('Knockback: Dependency alert! Underscore.js must be included before this file');
}
this.Knockback || (this.Knockback = {});
this.kb || (this.kb = this.Knockback);
Knockback.VERSION = '0.12.0';
Knockback.locale_manager;
Knockback.wrappedObservable = function(instance) {
if (!instance._kb_observable) {
throw new Error('Knockback: _kb_observable missing from your instance');
}
return instance._kb_observable;
};
Knockback.setToDefault = function(observable) {
if (observable && observable.setToDefault) {
return observable.setToDefault();
}
};
Knockback.vmSetToDefault = function(view_model) {
var key, observable, _results;
_results = [];
for (key in view_model) {
observable = view_model[key];
_results.push(kb.setToDefault(observable));
}
return _results;
};
Knockback.vmRelease = function(view_model) {
if (view_model instanceof kb.ViewModel_RCBase) {
view_model.release();
return;
}
return Knockback.vmReleaseObservables(view_model);
};
Knockback.vmReleaseObservables = function(view_model, keys) {
var key, value, _results;
_results = [];
for (key in view_model) {
value = view_model[key];
if (!value) {
continue;
}
if (!(ko.isObservable(value) || (value instanceof kb.Observables) || (value instanceof kb.ViewModel_RCBase))) {
continue;
}
if (keys && !_.contains(keys, key)) {
continue;
}
view_model[key] = null;
_results.push(kb.vmReleaseObservable(value));
}
return _results;
};
Knockback.vmReleaseObservable = function(observable) {
if (!(ko.isObservable(observable) || (observable instanceof kb.Observables) || (observable instanceof kb.ViewModel_RCBase))) {
return;
}
if (observable.destroy) {
return observable.destroy();
} else if (observable.dispose) {
return observable.dispose();
} else if (observable.release) {
return observable.release();
}
};
/*
knockback_collection_observable.js
(c) 2011 Kevin Malakoff.
Knockback.CollectionObservable is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
return child;
};
if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.CollectionObservable = (function() {
function CollectionObservable(collection, vm_observable_array, options) {
var defer, event, _i, _j, _len, _len2, _ref, _ref2;
this.vm_observable_array = vm_observable_array;
if (options == null) {
options = {};
}
if (!collection) {
throw new Error('CollectionObservable: collection is missing');
}
if (options.hasOwnProperty('view_model')) {
options.view_model_constructor = options['view_model'];
delete options['view_model'];
}
if (this.vm_observable_array || options.view_model_create || options.view_model_constructor) {
if (!this.vm_observable_array) {
throw new Error('CollectionObservable: vm_observable_array is missing');
}
}
if (options.hasOwnProperty('defer')) {
defer = options.defer;
delete options['defer'];
}
this.options = _.clone(options);
_.bindAll(this, 'destroy', 'collection', 'sortedIndex', 'sortAttribute', 'viewModelByModel', 'eachViewModel', 'bind', 'unbind', 'trigger');
_.bindAll(this, '_onGetValue', '_onCollectionReset', '_onCollectionResort', '_onModelAdd', '_onModelRemove', '_onModelChanged');
this._kb_collection = collection;
if (this._kb_collection.retain) {
this._kb_collection.retain();
}
this._kb_collection.bind('reset', this._onCollectionReset);
if (!this.options.sorted_index) {
this._kb_collection.bind('resort', this._onCollectionResort);
}
_ref = ['new', 'add'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
event = _ref[_i];
this._kb_collection.bind(event, this._onModelAdd);
}
_ref2 = ['remove', 'destroy'];
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
event = _ref2[_j];
this._kb_collection.bind(event, this._onModelRemove);
}
this._kb_collection.bind('change', this._onModelChanged);
this._kb_value_observable = ko.observableArray([]);
this._kb_observable = ko.dependentObservable(this._onGetValue);
this._kb_observable.destroy = this.destroy;
this._kb_observable.collection = this.collection;
this._kb_observable.viewModelByModel = this.viewModelByModel;
this._kb_observable.eachViewModel = this.eachViewModel;
this._kb_observable.sortedIndex = this.sortedIndex;
this._kb_observable.sortAttribute = this.sortAttribute;
this._kb_observable.bind = this.bind;
this._kb_observable.unbind = this.unbind;
this._kb_observable.trigger = this.trigger;
this.sortedIndex(this.options.sorted_index, this.options.sort_attribute, {
silent: true,
defer: defer
});
return kb.wrappedObservable(this);
}
CollectionObservable.prototype.destroy = function() {
var event, _i, _j, _len, _len2, _ref, _ref2;
this._clearViewModels();
this._kb_collection.unbind('reset', this._onCollectionReset);
if (!this.options.sorted_index) {
this._kb_collection.unbind('resort', this._onCollectionResort);
}
_ref = ['new', 'add'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
event = _ref[_i];
this._kb_collection.unbind(event, this._onModelAdd);
}
_ref2 = ['remove', 'destroy'];
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
event = _ref2[_j];
this._kb_collection.unbind(event, this._onModelRemove);
}
this._kb_collection.unbind('change', this._onModelChanged);
if (this._kb_collection.release) {
this._kb_collection.release();
}
this._kb_collection = null;
this._kb_value_observable = null;
this._kb_observable.dispose();
this._kb_observable = null;
return this.options = null;
};
CollectionObservable.prototype.collection = function() {
this._kb_value_observable();
return this._kb_collection;
};
CollectionObservable.prototype.sortedIndex = function(sorted_index, sort_attribute, options) {
var _resync;
if (options == null) {
options = {};
}
if (sorted_index) {
this.options.sorted_index = sorted_index;
this.options.sort_attribute = sort_attribute;
} else if (sort_attribute) {
this.options.sort_attribute = sort_attribute;
this.options.sorted_index = this._sortAttributeFn(sort_attribute);
} else {
this.options.sort_attribute = null;
this.options.sorted_index = null;
}
_resync = __bind(function() {
if ((this._kb_collection.models.length === 0) && (this._kb_value_observable().length === 0)) {
return;
}
this._collectionResync(true);
if (!options.silent) {
return this.trigger('resort', this.vm_observable_array());
}
}, this);
if (options.defer) {
_.defer(_resync);
} else {
_resync();
}
return this;
};
CollectionObservable.prototype.sortAttribute = function(sort_attribute, sorted_index, silent) {
return this.sortedIndex(sorted_index, sort_attribute, silent);
};
CollectionObservable.prototype._sortAttributeFn = function(sort_attribute) {
return function(models, model) {
return _.sortedIndex(models, model, function(test) {
return test.get(sort_attribute);
});
};
};
CollectionObservable.prototype.viewModelByModel = function(model) {
var id_attribute;
if (!this.vm_observable_array) {
throw new Error("CollectionObservable: cannot get a view model if vm_observable_array was not supplied");
}
id_attribute = model.hasOwnProperty(model.idAttribute) ? model.idAttribute : 'cid';
return _.find(this.vm_observable_array(), function(test) {
return test.__kb_model[id_attribute] === model[id_attribute];
});
};
CollectionObservable.prototype.eachViewModel = function(iterator) {
var view_model, _i, _len, _ref, _results;
_ref = this.vm_observable_array();
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
view_model = _ref[_i];
_results.push(iterator(view_model));
}
return _results;
};
CollectionObservable.prototype._onGetValue = function() {
return this._kb_value_observable();
};
CollectionObservable.prototype._onCollectionReset = function() {
return this._collectionResync();
};
CollectionObservable.prototype._onCollectionResort = function(model_or_models) {
if (this.options.sorted_index) {
throw new Error("CollectionObservable: collection sorted_index unexpected");
}
if (_.isArray(model_or_models)) {
this._collectionResync(true);
return this.trigger('resort', this.vm_observable_array());
} else {
return this._onModelResort(model_or_models);
}
};
CollectionObservable.prototype._onModelAdd = function(model) {
var add_index, sorted_models, view_model;
if (this.options.sorted_index) {
sorted_models = _.pluck(this.vm_observable_array(), '__kb_model');
add_index = this.options.sorted_index(sorted_models, model);
} else {
add_index = this._kb_collection.indexOf(model);
}
if (this.vm_observable_array) {
view_model = this._viewModelCreate(model);
this.vm_observable_array.splice(add_index, 0, view_model);
}
this._kb_value_observable.splice(add_index, 0, model);
if (this.vm_observable_array) {
return this.trigger('add', view_model, this.vm_observable_array());
}
};
CollectionObservable.prototype._onModelRemove = function(model) {
var view_model;
this._kb_value_observable.remove(model);
if (this.vm_observable_array) {
view_model = this.viewModelByModel(model);
if (!view_model) {
return;
}
this.vm_observable_array.remove(view_model);
this.trigger('remove', view_model, this.vm_observable_array());
kb.vmRelease(view_model);
return view_model.__kb_model = null;
}
};
CollectionObservable.prototype._onModelChanged = function(model) {
if (this.options.sorted_index && (!this.options.sort_attribute || model.hasChanged(this.options.sort_attribute))) {
this._onModelResort(model);
}
return this._kb_value_observable.valueHasMutated();
};
CollectionObservable.prototype._onModelResort = function(model) {
var new_index, previous_index, sorted_models, view_model;
previous_index = this._kb_value_observable.indexOf(model);
if (this.options.sorted_index) {
sorted_models = _.clone(this._kb_value_observable());
sorted_models.splice(previous_index, 1);
new_index = this.options.sorted_index(sorted_models, model);
} else {
new_index = this._kb_collection.indexOf(model);
}
if (previous_index === new_index) {
return;
}
if (this.vm_observable_array) {
view_model = this.viewModelByModel(model);
this.vm_observable_array.splice(previous_index, 1);
this.vm_observable_array.splice(new_index, 0, view_model);
}
this._kb_value_observable.splice(previous_index, 1);
this._kb_value_observable.splice(new_index, 0, model);
if (this.vm_observable_array) {
return this.trigger('resort', view_model, this.vm_observable_array(), new_index);
}
};
CollectionObservable.prototype._clearViewModels = function(silent) {
var view_model, view_models, _i, _len, _results;
if (this.vm_observable_array) {
if (!silent) {
this.trigger('remove', this.vm_observable_array());
}
view_models = this.vm_observable_array.removeAll();
_results = [];
for (_i = 0, _len = view_models.length; _i < _len; _i++) {
view_model = view_models[_i];
_results.push(kb.vmRelease(view_model));
}
return _results;
}
};
CollectionObservable.prototype._collectionResync = function(silent) {
var add_index, model, models, view_models, _i, _j, _len, _len2, _ref;
this._clearViewModels(silent);
this._kb_value_observable.removeAll();
if (this.options.sorted_index) {
models = [];
_ref = this._kb_collection.models;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
model = _ref[_i];
add_index = this.options.sorted_index(models, model);
models.splice(add_index, 0, model);
}
} else {
models = _.clone(this._kb_collection.models);
}
if (this.vm_observable_array) {
view_models = [];
for (_j = 0, _len2 = models.length; _j < _len2; _j++) {
model = models[_j];
view_models.push(this._viewModelCreate(model));
}
this.vm_observable_array(view_models);
}
this._kb_value_observable(models);
if (this.vm_observable_array) {
if (!silent) {
return this.trigger('add', this.vm_observable_array());
}
}
};
CollectionObservable.prototype._viewModelCreate = function(model) {
var view_model;
if (this.options.view_model_create) {
view_model = this.options.view_model_create(model);
} else if (this.options.view_model_constructor) {
view_model = new this.options.view_model_constructor(model);
} else {
view_model = kb.viewModel(model);
}
view_model.__kb_model = model;
return view_model;
};
return CollectionObservable;
})();
__extends(Knockback.CollectionObservable.prototype, Backbone.Events);
Knockback.collectionObservable = function(collection, vm_observable_array, options) {
return new Knockback.CollectionObservable(collection, vm_observable_array, options);
};
Knockback.viewModelGetModel = Knockback.vmModel = function(view_model) {
return view_model.__kb_model;
};
Knockback.sortedIndexWrapAttr = Knockback.siwa = function(attribute_name, wrapper_constructor) {
return function(models, model) {
return _.sortedIndex(models, model, function(test) {
return new wrapper_constructor(test.get(attribute_name));
});
};
};
/*
knockback_default_wrapper.js
(c) 2011 Kevin Malakoff.
Knockback.DefaultWrapper is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.DefaultWrapper = (function() {
function DefaultWrapper(observable, default_value) {
this.default_value = default_value;
_.bindAll(this, 'destroy', 'setToDefault');
this._kb_observable = ko.dependentObservable({
read: __bind(function() {
var value;
value = ko.utils.unwrapObservable(observable());
if (!value) {
return ko.utils.unwrapObservable(this.default_value);
} else {
return value;
}
}, this),
write: function(value) {
return observable(value);
},
owner: {}
});
this._kb_observable.destroy = this.destroy;
this._kb_observable.setToDefault = this.setToDefault;
return kb.wrappedObservable(this);
}
DefaultWrapper.prototype.destroy = function() {
this._kb_observable = null;
return this.default_value = null;
};
DefaultWrapper.prototype.setToDefault = function() {
return this._kb_observable(this.default_value);
};
return DefaultWrapper;
})();
Knockback.defaultWrapper = function(observable, default_value) {
return new Knockback.DefaultWrapper(observable, default_value);
};
/*
knockback_formatted_observable.js
(c) 2011 Kevin Malakoff.
Knockback.FormattedObservable is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.toFormattedString = function(format) {
var arg, args, index, parameter_index, result, value;
result = format.slice();
args = Array.prototype.slice.call(arguments, 1);
for (index in args) {
arg = args[index];
value = ko.utils.unwrapObservable(arg);
if (!value) {
value = '';
}
parameter_index = format.indexOf("\{" + index + "\}");
while (parameter_index >= 0) {
result = result.replace("{" + index + "}", value);
parameter_index = format.indexOf("\{" + index + "\}", parameter_index + 1);
}
}
return result;
};
Knockback.parseFormattedString = function(string, format) {
var count, format_indices_to_matched_indices, index, match_index, matches, parameter_count, parameter_index, positions, regex, regex_string, results, sorted_positions, _i, _results;
regex_string = format.slice();
index = 0;
parameter_count = 0;
positions = {};
while (regex_string.search("\\{" + index + "\\}") >= 0) {
parameter_index = format.indexOf("\{" + index + "\}");
while (parameter_index >= 0) {
regex_string = regex_string.replace("\{" + index + "\}", '(.*)');
positions[parameter_index] = index;
parameter_count++;
parameter_index = format.indexOf("\{" + index + "\}", parameter_index + 1);
}
index++;
}
count = index;
regex = new RegExp(regex_string);
matches = regex.exec(string);
if (matches) {
matches.shift();
}
if (!matches || (matches.length !== parameter_count)) {
return _.map((function() {
_results = [];
for (var _i = 1; 1 <= count ? _i <= count : _i >= count; 1 <= count ? _i++ : _i--){ _results.push(_i); }
return _results;
}).apply(this), function() {
return '';
});
}
sorted_positions = _.sortBy(_.keys(positions), function(parameter_index, format_index) {
return parseInt(parameter_index, 10);
});
format_indices_to_matched_indices = {};
for (match_index in sorted_positions) {
parameter_index = sorted_positions[match_index];
index = positions[parameter_index];
if (format_indices_to_matched_indices.hasOwnProperty(index)) {
continue;
}
format_indices_to_matched_indices[index] = match_index;
}
results = [];
index = 0;
while (index < count) {
results.push(matches[format_indices_to_matched_indices[index]]);
index++;
}
return results;
};
Knockback.formattedObservable = function(format, args) {
var observable_args, result;
observable_args = Array.prototype.slice.call(arguments, 1);
result = ko.dependentObservable({
read: function() {
var arg, _i, _len;
args = [ko.utils.unwrapObservable(format)];
for (_i = 0, _len = observable_args.length; _i < _len; _i++) {
arg = observable_args[_i];
args.push(ko.utils.unwrapObservable(arg));
}
return kb.toFormattedString.apply(null, args);
},
write: function(value) {
var index, matches, max_count, _results;
matches = kb.parseFormattedString(value, ko.utils.unwrapObservable(format));
max_count = Math.min(observable_args.length, matches.length);
index = 0;
_results = [];
while (index < max_count) {
observable_args[index](matches[index]);
_results.push(index++);
}
return _results;
},
owner: {}
});
return result;
};
/*
knockback_localized_observable.js
(c) 2011 Kevin Malakoff.
Knockback.LocalizedObservable is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.LocalizedObservable = (function() {
function LocalizedObservable(value, options, view_model) {
this.value = value;
this.options = options != null ? options : {};
this.view_model = view_model;
if (!(this.options.read || this.read)) {
throw new Error('LocalizedObservable: options.read is missing');
}
if (this.options.read && this.read) {
throw new Error('LocalizedObservable: options.read and read class function exist. You need to choose one.');
}
if (this.options.write && this.write) {
throw new Error('LocalizedObservable: options.write and write class function exist. You need to choose one.');
}
if (!kb.locale_manager) {
throw new Error('LocalizedObservable: Knockback.locale_manager is not defined');
}
_.bindAll(this, 'destroy', 'setToDefault', 'resetToCurrent', 'observedValue', '_onGetValue', '_onSetValue', '_onLocaleChange');
this._kb_read = this.options.read ? this.options.read : this.read;
this._kb_write = this.options.write ? this.options.write : this.write;
this._kb_default = this.options["default"] ? this.options["default"] : this["default"];
if (this.value) {
value = ko.utils.unwrapObservable(this.value);
}
this._kb_value_observable = ko.observable(!value ? this._getDefaultValue() : this._kb_read.call(this, value, null));
if (this._kb_write) {
if (!this.view_model) {
this.view_model = {};
}
if (!_.isFunction(this._kb_write)) {
throw new Error('LocalizedObservable: options.write is not a function for read_write model attribute');
}
this._kb_observable = ko.dependentObservable({
read: this._onGetValue,
write: this._onSetValue,
owner: this.view_model
});
} else {
this._kb_observable = ko.dependentObservable(this._onGetValue);
}
this._kb_observable.destroy = this.destroy;
this._kb_observable.observedValue = this.observedValue;
this._kb_observable.setToDefault = this.setToDefault;
this._kb_observable.resetToCurrent = this.resetToCurrent;
kb.locale_manager.bind('change', this._onLocaleChange);
return kb.wrappedObservable(this);
}
LocalizedObservable.prototype.destroy = function() {
kb.locale_manager.unbind('change', this._onLocaleChange);
this._kb_value_observable = null;
this._kb_observable.dispose();
this._kb_observable = null;
this.options = {};
return this.view_model = null;
};
LocalizedObservable.prototype.setToDefault = function() {
var current_value, default_value;
if (!this._kb_default) {
return;
}
default_value = this._getDefaultValue();
current_value = this._kb_value_observable();
if (current_value !== default_value) {
return this._onSetValue(default_value);
} else {
return this._kb_value_observable.valueHasMutated();
}
};
LocalizedObservable.prototype.resetToCurrent = function() {
this._kb_value_observable(null);
return this._onSetValue(this._getCurrentValue());
};
LocalizedObservable.prototype.observedValue = function(value) {
if (arguments.length === 0) {
return this.value;
}
this.value = value;
this._onLocaleChange();
return this;
};
LocalizedObservable.prototype._getDefaultValue = function() {
if (!this._kb_default) {
return '';
}
if (_.isFunction(this._kb_default)) {
return this._kb_default();
} else {
return this._kb_default;
}
};
LocalizedObservable.prototype._getCurrentValue = function() {
if (!(this.value && this._kb_observable)) {
return this._getDefaultValue();
}
return this._kb_read.call(this, ko.utils.unwrapObservable(this.value), this._kb_observable);
};
LocalizedObservable.prototype._onGetValue = function() {
if (this.value) {
ko.utils.unwrapObservable(this.value);
}
return this._kb_value_observable();
};
LocalizedObservable.prototype._onSetValue = function(value) {
this._kb_write.call(this, value, ko.utils.unwrapObservable(this.value), this._kb_observable);
value = this._kb_read.call(this, ko.utils.unwrapObservable(this.value), this._kb_observable);
this._kb_value_observable(value);
if (this.options.onChange) {
return this.options.onChange(value);
}
};
LocalizedObservable.prototype._onLocaleChange = function() {
var value;
value = this._kb_read.call(this, ko.utils.unwrapObservable(this.value), this._kb_observable);
this._kb_value_observable(value);
if (this.options.onChange) {
return this.options.onChange(value);
}
};
return LocalizedObservable;
})();
Knockback.localizedObservable = function(value, options, view_model) {
return new Knockback.LocalizedObservable(value, options, view_model);
};
/*
knockback_observable.js
(c) 2011 Kevin Malakoff.
Knockback.Observable is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.Observable = (function() {
function Observable(model, options, view_model) {
this.model = model;
this.options = options;
this.view_model = view_model;
if (!this.model) {
throw new Error('Observable: model is missing');
}
if (!this.options) {
throw new Error('Observable: options is missing');
}
if (_.isString(this.options) || ko.isObservable(this.options)) {
this.options = {
key: this.options
};
}
if (!this.options.key) {
throw new Error('Observable: options.key is missing');
}
_.bindAll(this, 'destroy', 'setToDefault', '_onGetValue', '_onSetValue', '_onModelChange', '_onModelLoaded', '_onModelUnloaded');
if (Backbone.ModelRef && (this.model instanceof Backbone.ModelRef)) {
this.model_ref = this.model;
this.model_ref.retain();
this.model_ref.bind('loaded', this._onModelLoaded);
this.model_ref.bind('unloaded', this._onModelUnloaded);
this.model = this.model_ref.getModel();
}
this._kb_value_observable = ko.observable();
if (this.options.localizer) {
this._kb_localizer = new this.options.localizer(this._getCurrentValue());
}
if (this.options.write) {
if (!this.view_model) {
throw new Error('Observable: view_model is missing for read_write model attribute');
}
this._kb_observable = ko.dependentObservable({
read: this._onGetValue,
write: this._onSetValue,
owner: this.view_model
});
} else {
this._kb_observable = ko.dependentObservable(this._onGetValue);
}
this._kb_observable.destroy = this.destroy;
this._kb_observable.setToDefault = this.setToDefault;
if (!this.model_ref || this.model_ref.isLoaded()) {
this.model.bind('change', this._onModelChange);
}
return kb.wrappedObservable(this);
}
Observable.prototype.destroy = function() {
this._kb_value_observable = null;
this._kb_observable.dispose();
this._kb_observable = null;
if (this.model) {
this._onModelUnloaded(this.model);
}
if (this.model_ref) {
this.model_ref.unbind('loaded', this._onModelLoaded);
this.model_ref.unbind('unloaded', this._onModelUnloaded);
this.model_ref.release();
this.model_ref = null;
}
this.options = null;
return this.view_model = null;
};
Observable.prototype.setToDefault = function() {
var value;
value = this._getDefaultValue();
if (this._kb_localizer) {
this._kb_localizer.observedValue(value);
value = this._kb_localizer();
}
return this._kb_value_observable(value);
};
Observable.prototype._getDefaultValue = function() {
if (!this.options.hasOwnProperty('default')) {
return '';
}
if (_.isFunction(this.options["default"])) {
return this.options["default"]();
} else {
return this.options["default"];
}
};
Observable.prototype._getCurrentValue = function() {
var arg, args, key, _i, _len, _ref;
if (!this.model) {
return this._getDefaultValue();
}
key = ko.utils.unwrapObservable(this.options.key);
args = [key];
if (!_.isUndefined(this.options.args)) {
if (_.isArray(this.options.args)) {
_ref = this.options.args;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
arg = _ref[_i];
args.push(ko.utils.unwrapObservable(arg));
}
} else {
args.push(ko.utils.unwrapObservable(this.options.args));
}
}
if (this.options.read) {
return this.options.read.apply(this.view_model, args);
} else {
return this.model.get.apply(this.model, args);
}
};
Observable.prototype._onGetValue = function() {
var arg, value, _i, _len, _ref;
this._kb_value_observable();
ko.utils.unwrapObservable(this.options.key);
if (!_.isUndefined(this.options.args)) {
if (_.isArray(this.options.args)) {
_ref = this.options.args;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
arg = _ref[_i];
ko.utils.unwrapObservable(arg);
}
} else {
ko.utils.unwrapObservable(this.options.args);
}
}
value = this._getCurrentValue();
if (this._kb_localizer) {
this._kb_localizer.observedValue(value);
value = this._kb_localizer();
}
return value;
};
Observable.prototype._onSetValue = function(value) {
var arg, args, set_info, _i, _len, _ref;
if (this._kb_localizer) {
this._kb_localizer(value);
value = this._kb_localizer.observedValue();
}
if (this.model) {
set_info = {};
set_info[ko.utils.unwrapObservable(this.options.key)] = value;
args = _.isFunction(this.options.write) ? [value] : [set_info];
if (!_.isUndefined(this.options.args)) {
if (_.isArray(this.options.args)) {
_ref = this.options.args;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
arg = _ref[_i];
args.push(ko.utils.unwrapObservable(arg));
}
} else {
args.push(ko.utils.unwrapObservable(this.options.args));
}
}
if (_.isFunction(this.options.write)) {
this.options.write.apply(this.view_model, args);
} else {
this.model.set.apply(this.model, args);
}
}
if (this._kb_localizer) {
return this._kb_value_observable(this._kb_localizer());
} else {
return this._kb_value_observable(value);
}
};
Observable.prototype._onModelLoaded = function(model) {
this.model = model;
this.model.bind('change', this._onModelChange);
return this._updateValue();
};
Observable.prototype._onModelUnloaded = function(model) {
if (this._kb_localizer && this._kb_localizer.destroy) {
this._kb_localizer.destroy();
this._kb_localizer = null;
}
this.model.unbind('change', this._onModelChange);
return this.model = null;
};
Observable.prototype._onModelChange = function() {
if ((this.model && this.model.hasChanged) && !this.model.hasChanged(ko.utils.unwrapObservable(this.options.key))) {
return;
}
return this._updateValue();
};
Observable.prototype._updateValue = function() {
var value;
value = this._getCurrentValue();
if (this._kb_localizer) {
this._kb_localizer.observedValue(value);
value = this._kb_localizer();
}
return this._kb_value_observable(value);
};
return Observable;
})();
Knockback.observable = function(model, options, view_model) {
return new Knockback.Observable(model, options, view_model);
};
/*
knockback_observables.js
(c) 2011 Kevin Malakoff.
Knockback.Observables is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.Observables = (function() {
function Observables(model, mappings_info, view_model, options_or_writeable) {
var is_string, mapping_info, view_model_property_name, write, _ref, _ref2;
this.model = model;
this.mappings_info = mappings_info;
this.view_model = view_model;
if (!this.model) {
throw new Error('Observables: model is missing');
}
if (!this.mappings_info) {
throw new Error('Observables: mappings_info is missing');
}
if (!!options_or_writeable && ((_.isBoolean(options_or_writeable) && options_or_writeable) || !!options_or_writeable.write)) {
write = _.isBoolean(options_or_writeable) ? options_or_writeable : !!options_or_writeable.write;
_ref = this.mappings_info;
for (view_model_property_name in _ref) {
mapping_info = _ref[view_model_property_name];
is_string = _.isString(mapping_info);
if (is_string || !mapping_info.hasOwnProperty(write)) {
mapping_info = is_string ? {
key: mapping_info,
write: write
} : _.extend({
write: write
}, mapping_info);
}
this.view_model[view_model_property_name] = kb.observable(this.model, mapping_info, this.view_model);
}
} else {
_ref2 = this.mappings_info;
for (view_model_property_name in _ref2) {
mapping_info = _ref2[view_model_property_name];
this.view_model[view_model_property_name] = kb.observable(this.model, mapping_info, this.view_model);
}
}
}
Observables.prototype.destroy = function() {
var mapping_info, view_model_property_name, _ref;
_ref = this.mappings_info;
for (view_model_property_name in _ref) {
mapping_info = _ref[view_model_property_name];
if (this.view_model[view_model_property_name]) {
this.view_model[view_model_property_name].destroy();
}
this.view_model[view_model_property_name] = null;
}
this.view_model = null;
this.mappings_info = null;
return this.model = null;
};
Observables.prototype.setToDefault = function() {
var mapping_info, view_model_property_name, _ref, _results;
_ref = this.mappings_info;
_results = [];
for (view_model_property_name in _ref) {
mapping_info = _ref[view_model_property_name];
_results.push(this.view_model[view_model_property_name].setToDefault());
}
return _results;
};
return Observables;
})();
Knockback.observables = function(model, mappings_info, view_model, options) {
return new Knockback.Observables(model, mappings_info, view_model, options);
};
/*
knockback_triggered_observable.js
(c) 2011 Kevin Malakoff.
Knockback.Observable is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.TriggeredObservable = (function() {
function TriggeredObservable(model, event_name) {
this.model = model;
this.event_name = event_name;
if (!this.model) {
throw new Error('Observable: model is missing');
}
if (!this.event_name) {
throw new Error('Observable: event_name is missing');
}
_.bindAll(this, 'destroy', '_onGetValue', '_onValueChange', '_onModelLoaded', '_onModelUnloaded');
if (Backbone.ModelRef && (this.model instanceof Backbone.ModelRef)) {
this.model_ref = this.model;
this.model_ref.retain();
this.model_ref.bind('loaded', this._onModelLoaded);
this.model_ref.bind('unloaded', this._onModelUnloaded);
this.model = this.model_ref.getModel();
}
this._kb_value_observable = ko.observable();
this._kb_observable = ko.dependentObservable(this._onGetValue);
this._kb_observable.destroy = this.destroy;
if (!this.model_ref || this.model_ref.isLoaded()) {
this._onModelLoaded(this.model);
}
return kb.wrappedObservable(this);
}
TriggeredObservable.prototype.destroy = function() {
this._kb_observable.dispose();
this._kb_observable = null;
this._kb_value_observable = null;
if (this.model) {
this._onModelUnloaded(this.model);
}
if (this.model_ref) {
this.model_ref.unbind('loaded', this._onModelLoaded);
this.model_ref.unbind('unloaded', this._onModelUnloaded);
this.model_ref.release();
this.model_ref = null;
}
this.options = null;
return this.view_model = null;
};
TriggeredObservable.prototype._onGetValue = function() {
return this._kb_value_observable();
};
TriggeredObservable.prototype._onModelLoaded = function(model) {
this.model = model;
this.model.bind(this.event_name, this._onValueChange);
return this._onValueChange();
};
TriggeredObservable.prototype._onModelUnloaded = function() {
if (this._kb_localizer && this._kb_localizer.destroy) {
this._kb_localizer.destroy();
this._kb_localizer = null;
}
this.model.unbind(this.event_name, this._onValueChange);
return this.model = null;
};
TriggeredObservable.prototype._onValueChange = function() {
var current_value;
current_value = this._kb_value_observable();
if (current_value !== this.model) {
return this._kb_value_observable(this.model);
} else {
return this._kb_value_observable.valueHasMutated();
}
};
return TriggeredObservable;
})();
Knockback.triggeredObservable = function(model, event_name) {
return new Knockback.TriggeredObservable(model, event_name);
};
/*
knockback_view_model.js
(c) 2011 Kevin Malakoff.
Knockback.Observable is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/
var AttributeConnector;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
return child;
};
if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
AttributeConnector = (function() {
function AttributeConnector(model, key, read_only) {
this.key = key;
this.read_only = read_only;
_.bindAll(this, 'destroy', 'setModel');
this._kb_observable = ko.observable();
this._kb_observable.subscription = this._kb_observable.subscribe(__bind(function(value) {
var set_info;
if (this.read_only) {
if (this.model) {
value = this.model.get(this.key);
if (this._kb_observable() === value) {
return;
}
this._kb_observable(value);
}
throw "Cannot write a value to a dependentObservable unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.";
} else if (this.model) {
set_info = {};
set_info[this.key] = value;
return this.model.set(set_info);
}
}, this));
this._kb_observable.destroy = this.destroy;
this._kb_observable.setModel = this.setModel;
if (model) {
this.setModel(model);
}
return kb.wrappedObservable(this);
}
AttributeConnector.prototype.destroy = function() {
this.model = null;
return this._kb_observable = null;
};
AttributeConnector.prototype.setModel = function(model) {
if (model) {
this.model = model;
return this._kb_observable(this.model.get(this.key));
} else {
return this.model = null;
}
};
return AttributeConnector;
})();
Knockback.ViewModel_RCBase = (function() {
function ViewModel_RCBase() {
this.ref_count = 1;
}
ViewModel_RCBase.prototype._destroy = function() {
return kb.vmReleaseObservables(this);
};
ViewModel_RCBase.prototype.retain = function() {
if (this.ref_count <= 0) {
throw new Error("ViewModel: ref_count is corrupt: " + this.ref_count);
}
this.ref_count++;
return this;
};
ViewModel_RCBase.prototype.release = function() {
if (this.ref_count <= 0) {
throw new Error("ViewModel: ref_count is corrupt: " + this.ref_count);
}
this.ref_count--;
if (!this.ref_count) {
this._destroy();
}
return this;
};
ViewModel_RCBase.prototype.refCount = function() {
return this.ref_count;
};
return ViewModel_RCBase;
})();
Knockback.ViewModel = (function() {
__extends(ViewModel, kb.ViewModel_RCBase);
function ViewModel(model, options, view_model) {
var key, missing, _i, _len;
if (options == null) {
options = {};
}
this._kb_vm = {};
this._kb_vm.model = model;
this._kb_vm.options = options;
this._kb_vm.view_model = view_model;
if (!this._kb_vm.model) {
throw new Error('ViewModel: model is missing');
}
_.bindAll(this, '_kb_vm_onModelChange', '_kb_vm_onModelLoaded', '_kb_vm_onModelUnloaded');
if (!this._kb_vm.view_model) {
this._kb_vm.view_model = this;
} else {
this._kb_vm.observables = [];
}
if (Backbone.ModelRef && (this._kb_vm.model instanceof Backbone.ModelRef)) {
this._kb_vm.model_ref = this._kb_vm.model;
this._kb_vm.model_ref.retain();
this._kb_vm.model_ref.bind('loaded', this._kb_vm_onModelLoaded);
this._kb_vm.model_ref.bind('unloaded', this._kb_vm_onModelUnloaded);
this._kb_vm.model = this._kb_vm.model_ref.getModel();
}
if (!this._kb_vm.model_ref || this._kb_vm.model_ref.isLoaded()) {
this._kb_vm_onModelLoaded(this._kb_vm.model);
}
if (!this._kb_vm.options.internals && !this._kb_vm.options.requires) {
return this;
}
missing = _.union((this._kb_vm.options.internals ? this._kb_vm.options.internals : []), (this._kb_vm.options.requires ? this._kb_vm.options.requires : []));
if (!this._kb_vm.model_ref || this._kb_vm.model_ref.isLoaded()) {
missing = _.difference(missing, _.keys(this._kb_vm.model.attributes));
}
for (_i = 0, _len = missing.length; _i < _len; _i++) {
key = missing[_i];
this._updateAttributeObservor(this._kb_vm.model, key);
}
}
ViewModel.prototype._destroy = function() {
var view_model;
if (this._kb_vm.model) {
this._kb_vm.model.unbind('change', this._kb_vm_onModelChange);
this._kb_vm.model = null;
}
view_model = this._kb_vm.view_model;
this._kb_vm.view_model = null;
kb.vmReleaseObservables(view_model, this._kb_vm.observables);
if (this._kb_vm.observables) {
return this._kb_vm.observables = null;
}
};
ViewModel.prototype._kb_vm_onModelLoaded = function(model) {
var key, _results;
this._kb_vm.model = model;
this._kb_vm.model.bind('change', this._kb_vm_onModelChange);
_results = [];
for (key in this._kb_vm.model.attributes) {
_results.push(this._updateAttributeObservor(this._kb_vm.model, key));
}
return _results;
};
ViewModel.prototype._kb_vm_onModelUnloaded = function(model) {
var key, _results;
this._kb_vm.model.unbind('change', this._kb_vm_onModelChange);
model = this._kb_vm.model;
this._kb_vm.model = null;
_results = [];
for (key in model.attributes) {
_results.push(this._updateAttributeObservor(this._kb_vm.model, key));
}
return _results;
};
ViewModel.prototype._kb_vm_onModelChange = function() {
var key, _results;
if (!this._kb_vm.model._changed) {
return;
}
_results = [];
for (key in this._kb_vm.model.attributes) {
_results.push((this._kb_vm.model.hasChanged(key) ? this._updateAttributeObservor(this._kb_vm.model, key) : void 0));
}
return _results;
};
ViewModel.prototype._updateAttributeObservor = function(model, key) {
var vm_key;
vm_key = this._kb_vm.options.internals && _.contains(this._kb_vm.options.internals, key) ? '_' + key : key;
if (this._kb_vm.view_model.hasOwnProperty(vm_key)) {
if (this._kb_vm.view_model[vm_key]) {
return this._kb_vm.view_model[vm_key].setModel(model);
}
} else {
if (this._kb_vm.observables) {
this._kb_vm.observables.push(vm_key);
}
return this._kb_vm.view_model[vm_key] = new AttributeConnector(model, key, this._kb_vm.options.read_only);
}
};
return ViewModel;
})();
Knockback.viewModel = function(model, options, view_model) {
return new Knockback.ViewModel(model, options, view_model);
};
\ No newline at end of file
// Knockout JavaScript library v2.0.0
// (c) Steven Sanderson - http://knockoutjs.com/
// License: MIT (http://www.opensource.org/licenses/mit-license.php)
(function(window,undefined){
function c(a){throw a;}var l=void 0,m=!0,o=null,p=!1,r=window.ko={};r.b=function(a,b){for(var d=a.split("."),e=window,f=0;f<d.length-1;f++)e=e[d[f]];e[d[d.length-1]]=b};r.l=function(a,b,d){a[b]=d};
r.a=new function(){function a(a,e){if("INPUT"!=a.tagName||!a.type)return p;if("click"!=e.toLowerCase())return p;var b=a.type.toLowerCase();return"checkbox"==b||"radio"==b}var b=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,d={},e={};d[/Firefox\/2/i.test(navigator.userAgent)?"KeyboardEvent":"UIEvents"]=["keyup","keydown","keypress"];d.MouseEvents="click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave".split(",");for(var f in d){var h=d[f];if(h.length)for(var g=0,i=h.length;g<i;g++)e[h[g]]=
f}var j=function(){for(var a=3,e=document.createElement("div"),b=e.getElementsByTagName("i");e.innerHTML="<\!--[if gt IE "+ ++a+"]><i></i><![endif]--\>",b[0];);return 4<a?a:l}();return{Ba:["authenticity_token",/^__RequestVerificationToken(_.*)?$/],n:function(a,e){for(var b=0,f=a.length;b<f;b++)e(a[b])},k:function(a,e){if("function"==typeof Array.prototype.indexOf)return Array.prototype.indexOf.call(a,e);for(var b=0,f=a.length;b<f;b++)if(a[b]===e)return b;return-1},Wa:function(a,e,b){for(var f=0,d=
a.length;f<d;f++)if(e.call(b,a[f]))return a[f];return o},ca:function(a,e){var b=r.a.k(a,e);0<=b&&a.splice(b,1)},ya:function(a){for(var a=a||[],e=[],b=0,f=a.length;b<f;b++)0>r.a.k(e,a[b])&&e.push(a[b]);return e},ba:function(a,e){for(var a=a||[],b=[],f=0,d=a.length;f<d;f++)b.push(e(a[f]));return b},aa:function(a,e){for(var a=a||[],b=[],f=0,d=a.length;f<d;f++)e(a[f])&&b.push(a[f]);return b},J:function(a,e){for(var b=0,f=e.length;b<f;b++)a.push(e[b]);return a},extend:function(a,e){for(var b in e)e.hasOwnProperty(b)&&
(a[b]=e[b]);return a},U:function(a){for(;a.firstChild;)r.removeNode(a.firstChild)},oa:function(a,e){r.a.U(a);e&&r.a.n(e,function(e){a.appendChild(e)})},Ja:function(a,e){var b=a.nodeType?[a]:a;if(0<b.length){for(var f=b[0],d=f.parentNode,h=0,g=e.length;h<g;h++)d.insertBefore(e[h],f);h=0;for(g=b.length;h<g;h++)r.removeNode(b[h])}},La:function(a,e){0<=navigator.userAgent.indexOf("MSIE 6")?a.setAttribute("selected",e):a.selected=e},z:function(a){return(a||"").replace(b,"")},Db:function(a,e){for(var b=
[],f=(a||"").split(e),d=0,h=f.length;d<h;d++){var g=r.a.z(f[d]);""!==g&&b.push(g)}return b},Cb:function(a,e){a=a||"";return e.length>a.length?p:a.substring(0,e.length)===e},hb:function(a){for(var e=Array.prototype.slice.call(arguments,1),b="return ("+a+")",f=0;f<e.length;f++)e[f]&&"object"==typeof e[f]&&(b="with(sc["+f+"]) { "+b+" } ");return(new Function("sc",b))(e)},fb:function(a,e){if(e.compareDocumentPosition)return 16==(e.compareDocumentPosition(a)&16);for(;a!=o;){if(a==e)return m;a=a.parentNode}return p},
ga:function(a){return r.a.fb(a,document)},s:function(e,b,f){if("undefined"!=typeof jQuery){if(a(e,b))var d=f,f=function(a,e){var b=this.checked;if(e)this.checked=e.Ya!==m;d.call(this,a);this.checked=b};jQuery(e).bind(b,f)}else"function"==typeof e.addEventListener?e.addEventListener(b,f,p):"undefined"!=typeof e.attachEvent?e.attachEvent("on"+b,function(a){f.call(e,a)}):c(Error("Browser doesn't support addEventListener or attachEvent"))},sa:function(b,f){(!b||!b.nodeType)&&c(Error("element must be a DOM node when calling triggerEvent"));
if("undefined"!=typeof jQuery){var d=[];a(b,f)&&d.push({Ya:b.checked});jQuery(b).trigger(f,d)}else if("function"==typeof document.createEvent)"function"==typeof b.dispatchEvent?(d=document.createEvent(e[f]||"HTMLEvents"),d.initEvent(f,m,m,window,0,0,0,0,0,p,p,p,p,0,b),b.dispatchEvent(d)):c(Error("The supplied element doesn't support dispatchEvent"));else if("undefined"!=typeof b.fireEvent){if("click"==f&&"INPUT"==b.tagName&&("checkbox"==b.type.toLowerCase()||"radio"==b.type.toLowerCase()))b.checked=
b.checked!==m;b.fireEvent("on"+f)}else c(Error("Browser doesn't support triggering events"))},d:function(a){return r.V(a)?a():a},eb:function(a,e){return 0<=r.a.k((a.className||"").split(/\s+/),e)},Qa:function(a,e,b){var f=r.a.eb(a,e);if(b&&!f)a.className=(a.className||"")+" "+e;else if(f&&!b){for(var b=(a.className||"").split(/\s+/),f="",d=0;d<b.length;d++)b[d]!=e&&(f+=b[d]+" ");a.className=r.a.z(f)}},outerHTML:function(a){if(j===l){var e=a.outerHTML;if("string"==typeof e)return e}e=window.document.createElement("div");
e.appendChild(a.cloneNode(m));return e.innerHTML},Ma:function(a,e){var b=r.a.d(e);if(b===o||b===l)b="";"innerText"in a?a.innerText=b:a.textContent=b;if(9<=j)a.innerHTML=a.innerHTML},yb:function(a,e){for(var a=r.a.d(a),e=r.a.d(e),b=[],f=a;f<=e;f++)b.push(f);return b},X:function(a){for(var e=[],b=0,f=a.length;b<f;b++)e.push(a[b]);return e},ob:6===j,pb:7===j,Ca:function(a,e){for(var b=r.a.X(a.getElementsByTagName("INPUT")).concat(r.a.X(a.getElementsByTagName("TEXTAREA"))),f="string"==typeof e?function(a){return a.name===
e}:function(a){return e.test(a.name)},d=[],h=b.length-1;0<=h;h--)f(b[h])&&d.push(b[h]);return d},vb:function(a){return"string"==typeof a&&(a=r.a.z(a))?window.JSON&&window.JSON.parse?window.JSON.parse(a):(new Function("return "+a))():o},qa:function(a){("undefined"==typeof JSON||"undefined"==typeof JSON.stringify)&&c(Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js"));
return JSON.stringify(r.a.d(a))},wb:function(a,e,b){var b=b||{},f=b.params||{},d=b.includeFields||this.Ba,h=a;if("object"==typeof a&&"FORM"==a.tagName)for(var h=a.action,g=d.length-1;0<=g;g--)for(var j=r.a.Ca(a,d[g]),i=j.length-1;0<=i;i--)f[j[i].name]=j[i].value;var e=r.a.d(e),u=document.createElement("FORM");u.style.display="none";u.action=h;u.method="post";for(var y in e)a=document.createElement("INPUT"),a.name=y,a.value=r.a.qa(r.a.d(e[y])),u.appendChild(a);for(y in f)a=document.createElement("INPUT"),
a.name=y,a.value=f[y],u.appendChild(a);document.body.appendChild(u);b.submitter?b.submitter(u):u.submit();setTimeout(function(){u.parentNode.removeChild(u)},0)}}};r.b("ko.utils",r.a);
r.a.n([["arrayForEach",r.a.n],["arrayFirst",r.a.Wa],["arrayFilter",r.a.aa],["arrayGetDistinctValues",r.a.ya],["arrayIndexOf",r.a.k],["arrayMap",r.a.ba],["arrayPushAll",r.a.J],["arrayRemoveItem",r.a.ca],["extend",r.a.extend],["fieldsIncludedWithJsonPost",r.a.Ba],["getFormFields",r.a.Ca],["postJson",r.a.wb],["parseJson",r.a.vb],["registerEventHandler",r.a.s],["stringifyJson",r.a.qa],["range",r.a.yb],["toggleDomNodeCssClass",r.a.Qa],["triggerEvent",r.a.sa],["unwrapObservable",r.a.d]],function(a){r.b("ko.utils."+
a[0],a[1])});Function.prototype.bind||(Function.prototype.bind=function(a){var b=this,d=Array.prototype.slice.call(arguments),a=d.shift();return function(){return b.apply(a,d.concat(Array.prototype.slice.call(arguments)))}});
r.a.e=new function(){var a=0,b="__ko__"+(new Date).getTime(),d={};return{get:function(a,b){var d=r.a.e.getAll(a,p);return d===l?l:d[b]},set:function(a,b,d){d===l&&r.a.e.getAll(a,p)===l||(r.a.e.getAll(a,m)[b]=d)},getAll:function(e,f){var h=e[b];if(!(h&&"null"!==h)){if(!f)return;h=e[b]="ko"+a++;d[h]={}}return d[h]},clear:function(a){var f=a[b];f&&(delete d[f],a[b]=o)}}};r.b("ko.utils.domData",r.a.e);r.b("ko.utils.domData.clear",r.a.e.clear);
r.a.A=new function(){function a(a,b){var h=r.a.e.get(a,d);h===l&&b&&(h=[],r.a.e.set(a,d,h));return h}function b(e){var b=a(e,p);if(b)for(var b=b.slice(0),d=0;d<b.length;d++)b[d](e);r.a.e.clear(e);"function"==typeof jQuery&&"function"==typeof jQuery.cleanData&&jQuery.cleanData([e])}var d="__ko_domNodeDisposal__"+(new Date).getTime();return{va:function(e,b){"function"!=typeof b&&c(Error("Callback must be a function"));a(e,m).push(b)},Ia:function(e,b){var h=a(e,p);h&&(r.a.ca(h,b),0==h.length&&r.a.e.set(e,
d,l))},F:function(a){if(!(1!=a.nodeType&&9!=a.nodeType)){b(a);var f=[];r.a.J(f,a.getElementsByTagName("*"));for(var a=0,d=f.length;a<d;a++)b(f[a])}},removeNode:function(a){r.F(a);a.parentNode&&a.parentNode.removeChild(a)}}};r.F=r.a.A.F;r.removeNode=r.a.A.removeNode;r.b("ko.cleanNode",r.F);r.b("ko.removeNode",r.removeNode);r.b("ko.utils.domNodeDisposal",r.a.A);r.b("ko.utils.domNodeDisposal.addDisposeCallback",r.a.A.va);r.b("ko.utils.domNodeDisposal.removeDisposeCallback",r.a.A.Ia);
r.a.ma=function(a){var b;if("undefined"!=typeof jQuery){if((b=jQuery.clean([a]))&&b[0]){for(a=b[0];a.parentNode&&11!==a.parentNode.nodeType;)a=a.parentNode;a.parentNode&&a.parentNode.removeChild(a)}}else{var d=r.a.z(a).toLowerCase();b=document.createElement("div");d=d.match(/^<(thead|tbody|tfoot)/)&&[1,"<table>","</table>"]||!d.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!d.indexOf("<td")||!d.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||[0,"",""];a="ignored<div>"+
d[1]+a+d[2]+"</div>";for("function"==typeof window.innerShiv?b.appendChild(window.innerShiv(a)):b.innerHTML=a;d[0]--;)b=b.lastChild;b=r.a.X(b.lastChild.childNodes)}return b};r.a.Z=function(a,b){r.a.U(a);if(b!==o&&b!==l)if("string"!=typeof b&&(b=b.toString()),"undefined"!=typeof jQuery)jQuery(a).html(b);else for(var d=r.a.ma(b),e=0;e<d.length;e++)a.appendChild(d[e])};r.b("ko.utils.parseHtmlFragment",r.a.ma);r.b("ko.utils.setHtml",r.a.Z);
r.r=function(){function a(){return(4294967296*(1+Math.random())|0).toString(16).substring(1)}function b(a,f){if(a)if(8==a.nodeType){var d=r.r.Ga(a.nodeValue);d!=o&&f.push({cb:a,tb:d})}else if(1==a.nodeType)for(var d=0,g=a.childNodes,i=g.length;d<i;d++)b(g[d],f)}var d={};return{ka:function(b){"function"!=typeof b&&c(Error("You can only pass a function to ko.memoization.memoize()"));var f=a()+a();d[f]=b;return"<\!--[ko_memo:"+f+"]--\>"},Ra:function(a,b){var h=d[a];h===l&&c(Error("Couldn't find any memo with ID "+
a+". Perhaps it's already been unmemoized."));try{return h.apply(o,b||[]),m}finally{delete d[a]}},Sa:function(a,f){var d=[];b(a,d);for(var g=0,i=d.length;g<i;g++){var j=d[g].cb,k=[j];f&&r.a.J(k,f);r.r.Ra(d[g].tb,k);j.nodeValue="";j.parentNode&&j.parentNode.removeChild(j)}},Ga:function(a){return(a=a.match(/^\[ko_memo\:(.*?)\]$/))?a[1]:o}}}();r.b("ko.memoization",r.r);r.b("ko.memoization.memoize",r.r.ka);r.b("ko.memoization.unmemoize",r.r.Ra);r.b("ko.memoization.parseMemoText",r.r.Ga);
r.b("ko.memoization.unmemoizeDomNodeAndDescendants",r.r.Sa);r.Aa={throttle:function(a,b){a.throttleEvaluation=b;var d=o;return r.i({read:a,write:function(e){clearTimeout(d);d=setTimeout(function(){a(e)},b)}})},notify:function(a,b){a.equalityComparer="always"==b?function(){return p}:r.w.fn.equalityComparer;return a}};r.b("ko.extenders",r.Aa);r.Oa=function(a,b){this.da=a;this.bb=b;r.l(this,"dispose",this.v)};r.Oa.prototype.v=function(){this.nb=m;this.bb()};
r.R=function(){this.u={};r.a.extend(this,r.R.fn);r.l(this,"subscribe",this.ra);r.l(this,"extend",this.extend);r.l(this,"getSubscriptionsCount",this.kb)};
r.R.fn={ra:function(a,b,d){var d=d||"change",a=b?a.bind(b):a,e=new r.Oa(a,function(){r.a.ca(this.u[d],e)}.bind(this));this.u[d]||(this.u[d]=[]);this.u[d].push(e);return e},notifySubscribers:function(a,b){b=b||"change";this.u[b]&&r.a.n(this.u[b].slice(0),function(b){b&&b.nb!==m&&b.da(a)})},kb:function(){var a=0,b;for(b in this.u)this.u.hasOwnProperty(b)&&(a+=this.u[b].length);return a},extend:function(a){var b=this;if(a)for(var d in a){var e=r.Aa[d];"function"==typeof e&&(b=e(b,a[d]))}return b}};
r.Ea=function(a){return"function"==typeof a.ra&&"function"==typeof a.notifySubscribers};r.b("ko.subscribable",r.R);r.b("ko.isSubscribable",r.Ea);r.T=function(){var a=[];return{Xa:function(b){a.push({da:b,za:[]})},end:function(){a.pop()},Ha:function(b){r.Ea(b)||c("Only subscribable things can act as dependencies");if(0<a.length){var d=a[a.length-1];0<=r.a.k(d.za,b)||(d.za.push(b),d.da(b))}}}}();var B={undefined:m,"boolean":m,number:m,string:m};
r.w=function(a){function b(){if(0<arguments.length){if(!b.equalityComparer||!b.equalityComparer(d,arguments[0]))b.H(),d=arguments[0],b.G();return this}r.T.Ha(b);return d}var d=a;r.R.call(b);b.G=function(){b.notifySubscribers(d)};b.H=function(){b.notifySubscribers(d,"beforeChange")};r.a.extend(b,r.w.fn);r.l(b,"valueHasMutated",b.G);r.l(b,"valueWillMutate",b.H);return b};r.w.fn={B:r.w,equalityComparer:function(a,b){return a===o||typeof a in B?a===b:p}};
r.V=function(a){return a===o||a===l||a.B===l?p:a.B===r.w?m:r.V(a.B)};r.P=function(a){return"function"==typeof a&&a.B===r.w?m:"function"==typeof a&&a.B===r.i&&a.lb?m:p};r.b("ko.observable",r.w);r.b("ko.isObservable",r.V);r.b("ko.isWriteableObservable",r.P);
r.Q=function(a){0==arguments.length&&(a=[]);a!==o&&a!==l&&!("length"in a)&&c(Error("The argument passed when initializing an observable array must be an array, or null, or undefined."));var b=new r.w(a);r.a.extend(b,r.Q.fn);r.l(b,"remove",b.remove);r.l(b,"removeAll",b.zb);r.l(b,"destroy",b.fa);r.l(b,"destroyAll",b.ab);r.l(b,"indexOf",b.indexOf);r.l(b,"replace",b.replace);return b};
r.Q.fn={remove:function(a){for(var b=this(),d=[],e="function"==typeof a?a:function(b){return b===a},f=0;f<b.length;f++){var h=b[f];e(h)&&(0===d.length&&this.H(),d.push(h),b.splice(f,1),f--)}d.length&&this.G();return d},zb:function(a){if(a===l){var b=this(),d=b.slice(0);this.H();b.splice(0,b.length);this.G();return d}return!a?[]:this.remove(function(b){return 0<=r.a.k(a,b)})},fa:function(a){var b=this(),d="function"==typeof a?a:function(b){return b===a};this.H();for(var e=b.length-1;0<=e;e--)d(b[e])&&
(b[e]._destroy=m);this.G()},ab:function(a){return a===l?this.fa(function(){return m}):!a?[]:this.fa(function(b){return 0<=r.a.k(a,b)})},indexOf:function(a){var b=this();return r.a.k(b,a)},replace:function(a,b){var d=this.indexOf(a);0<=d&&(this.H(),this()[d]=b,this.G())}};r.a.n("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){r.Q.fn[a]=function(){var b=this();this.H();b=b[a].apply(b,arguments);this.G();return b}});
r.a.n(["slice"],function(a){r.Q.fn[a]=function(){var b=this();return b[a].apply(b,arguments)}});r.b("ko.observableArray",r.Q);function C(a,b){a&&"object"==typeof a?b=a:(b=b||{},b.read=a||b.read);"function"!=typeof b.read&&c("Pass a function that returns the value of the dependentObservable");return b}
r.i=function(a,b,d){function e(){r.a.n(q,function(a){a.v()});q=[]}function f(){var a=g.throttleEvaluation;a&&0<=a?(clearTimeout(v),v=setTimeout(h,a)):h()}function h(){if(j&&"function"==typeof d.disposeWhen&&d.disposeWhen())g.v();else{try{e();r.T.Xa(function(a){q.push(a.ra(f))});var a=d.read.call(d.owner||b);g.notifySubscribers(i,"beforeChange");i=a}finally{r.T.end()}g.notifySubscribers(i);j=m}}function g(){if(0<arguments.length)"function"===typeof d.write?d.write.apply(d.owner||b,arguments):c("Cannot write a value to a dependentObservable unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
else return j||h(),r.T.Ha(g),i}var i,j=p,d=C(a,d),k="object"==typeof d.disposeWhenNodeIsRemoved?d.disposeWhenNodeIsRemoved:o,n=o;if(k){n=function(){g.v()};r.a.A.va(k,n);var t=d.disposeWhen;d.disposeWhen=function(){return!r.a.ga(k)||"function"==typeof t&&t()}}var q=[],v=o;g.jb=function(){return q.length};g.lb="function"===typeof d.write;g.v=function(){k&&r.a.A.Ia(k,n);e()};r.R.call(g);r.a.extend(g,r.i.fn);d.deferEvaluation!==m&&h();r.l(g,"dispose",g.v);r.l(g,"getDependenciesCount",g.jb);return g};
r.i.fn={B:r.i};r.i.B=r.w;r.b("ko.dependentObservable",r.i);r.b("ko.computed",r.i);
(function(){function a(e,f,h){h=h||new d;e=f(e);if(!("object"==typeof e&&e!==o&&e!==l&&!(e instanceof Date)))return e;var g=e instanceof Array?[]:{};h.save(e,g);b(e,function(b){var d=f(e[b]);switch(typeof d){case "boolean":case "number":case "string":case "function":g[b]=d;break;case "object":case "undefined":var k=h.get(d);g[b]=k!==l?k:a(d,f,h)}});return g}function b(a,b){if(a instanceof Array)for(var d=0;d<a.length;d++)b(d);else for(d in a)b(d)}function d(){var a=[],b=[];this.save=function(d,g){var i=
r.a.k(a,d);0<=i?b[i]=g:(a.push(d),b.push(g))};this.get=function(d){d=r.a.k(a,d);return 0<=d?b[d]:l}}r.Pa=function(b){0==arguments.length&&c(Error("When calling ko.toJS, pass the object you want to convert."));return a(b,function(a){for(var b=0;r.V(a)&&10>b;b++)a=a();return a})};r.toJSON=function(a){a=r.Pa(a);return r.a.qa(a)}})();r.b("ko.toJS",r.Pa);r.b("ko.toJSON",r.toJSON);
r.h={q:function(a){return"OPTION"==a.tagName?a.__ko__hasDomDataOptionValue__===m?r.a.e.get(a,r.c.options.la):a.getAttribute("value"):"SELECT"==a.tagName?0<=a.selectedIndex?r.h.q(a.options[a.selectedIndex]):l:a.value},S:function(a,b){if("OPTION"==a.tagName)switch(typeof b){case "string":r.a.e.set(a,r.c.options.la,l);"__ko__hasDomDataOptionValue__"in a&&delete a.__ko__hasDomDataOptionValue__;a.value=b;break;default:r.a.e.set(a,r.c.options.la,b),a.__ko__hasDomDataOptionValue__=m,a.value="number"===typeof b?
b:""}else if("SELECT"==a.tagName)for(var d=a.options.length-1;0<=d;d--){if(r.h.q(a.options[d])==b){a.selectedIndex=d;break}}else{if(b===o||b===l)b="";a.value=b}}};r.b("ko.selectExtensions",r.h);r.b("ko.selectExtensions.readValue",r.h.q);r.b("ko.selectExtensions.writeValue",r.h.S);
r.j=function(){function a(a,e){for(var d=o;a!=d;)d=a,a=a.replace(b,function(a,b){return e[b]});return a}var b=/\@ko_token_(\d+)\@/g,d=/^[\_$a-z][\_$a-z0-9]*(\[.*?\])*(\.[\_$a-z][\_$a-z0-9]*(\[.*?\])*)*$/i,e=["true","false"];return{D:[],Y:function(b){var e=r.a.z(b);if(3>e.length)return[];"{"===e.charAt(0)&&(e=e.substring(1,e.length-1));for(var b=[],d=o,i,j=0;j<e.length;j++){var k=e.charAt(j);if(d===o)switch(k){case '"':case "'":case "/":d=j,i=k}else if(k==i&&"\\"!==e.charAt(j-1)){k=e.substring(d,j+
1);b.push(k);var n="@ko_token_"+(b.length-1)+"@",e=e.substring(0,d)+n+e.substring(j+1),j=j-(k.length-n.length),d=o}}i=d=o;for(var t=0,q=o,j=0;j<e.length;j++){k=e.charAt(j);if(d===o)switch(k){case "{":d=j;q=k;i="}";break;case "(":d=j;q=k;i=")";break;case "[":d=j,q=k,i="]"}k===q?t++:k===i&&(t--,0===t&&(k=e.substring(d,j+1),b.push(k),n="@ko_token_"+(b.length-1)+"@",e=e.substring(0,d)+n+e.substring(j+1),j-=k.length-n.length,d=o))}i=[];e=e.split(",");d=0;for(j=e.length;d<j;d++)t=e[d],q=t.indexOf(":"),
0<q&&q<t.length-1?(k=t.substring(q+1),i.push({key:a(t.substring(0,q),b),value:a(k,b)})):i.push({unknown:a(t,b)});return i},ia:function(a){for(var b="string"===typeof a?r.j.Y(a):a,g=[],a=[],i,j=0;i=b[j];j++)if(0<g.length&&g.push(","),i.key){var k;a:{k=i.key;var n=r.a.z(k);switch(n.length&&n.charAt(0)){case "'":case '"':break a;default:k="'"+n+"'"}}i=i.value;g.push(k);g.push(":");g.push(i);n=r.a.z(i);if(0<=r.a.k(e,r.a.z(n).toLowerCase())?0:n.match(d)!==o)0<a.length&&a.push(", "),a.push(k+" : function(__ko_value) { "+
i+" = __ko_value; }")}else i.unknown&&g.push(i.unknown);b=g.join("");0<a.length&&(b=b+", '_ko_property_writers' : { "+a.join("")+" } ");return b},rb:function(a,b){for(var e=0;e<a.length;e++)if(r.a.z(a[e].key)==b)return m;return p}}}();r.b("ko.jsonExpressionRewriting",r.j);r.b("ko.jsonExpressionRewriting.bindingRewriteValidators",r.j.D);r.b("ko.jsonExpressionRewriting.parseObjectLiteral",r.j.Y);r.b("ko.jsonExpressionRewriting.insertPropertyAccessorsIntoJson",r.j.ia);
(function(){function a(a){return 8==a.nodeType&&(f?a.text:a.nodeValue).match(h)}function b(a){return 8==a.nodeType&&(f?a.text:a.nodeValue).match(g)}function d(e,d){for(var f=e,g=1,h=[];f=f.nextSibling;){if(b(f)&&(g--,0===g))return h;h.push(f);a(f)&&g++}d||c(Error("Cannot find closing comment tag to match: "+e.nodeValue));return o}function e(a,b){var e=d(a,b);return e?0<e.length?e[e.length-1].nextSibling:a.nextSibling:o}var f="<\!--test--\>"===document.createComment("test").text,h=f?/^<\!--\s*ko\s+(.*\:.*)\s*--\>$/:
/^\s*ko\s+(.*\:.*)\s*$/,g=f?/^<\!--\s*\/ko\s*--\>$/:/^\s*\/ko\s*$/,i={ul:m,ol:m};r.f={C:{},childNodes:function(b){return a(b)?d(b):b.childNodes},ha:function(b){if(a(b))for(var b=r.f.childNodes(b),e=0,d=b.length;e<d;e++)r.removeNode(b[e]);else r.a.U(b)},oa:function(b,e){if(a(b)){r.f.ha(b);for(var d=b.nextSibling,f=0,g=e.length;f<g;f++)d.parentNode.insertBefore(e[f],d)}else r.a.oa(b,e)},xb:function(b,e){a(b)?b.parentNode.insertBefore(e,b.nextSibling):b.firstChild?b.insertBefore(e,b.firstChild):b.appendChild(e)},
mb:function(b,e,d){a(b)?b.parentNode.insertBefore(e,d.nextSibling):d.nextSibling?b.insertBefore(e,d.nextSibling):b.appendChild(e)},nextSibling:function(d){return a(d)?e(d).nextSibling:d.nextSibling&&b(d.nextSibling)?l:d.nextSibling},ta:function(b){return(b=a(b))?b[1]:o},ib:function(a){if(r.f.ta(a)){var b;b=r.f.childNodes(a);for(var e=[],d=0,f=b.length;d<f;d++)r.a.A.F(b[d]),e.push(r.a.outerHTML(b[d]));b=String.prototype.concat.apply("",e);r.f.ha(a);(new r.m.I(a)).text(b)}},Fa:function(d){if(i[d.tagName.toLowerCase()]){var f=
d.firstChild;if(f){do if(1===f.nodeType){var g;g=f.firstChild;var h=o;if(g){do if(h)h.push(g);else if(a(g)){var q=e(g,m);q?g=q:h=[g]}else b(g)&&(h=[g]);while(g=g.nextSibling)}if(g=h){h=f.nextSibling;for(q=0;q<g.length;q++)h?d.insertBefore(g[q],h):d.appendChild(g[q])}}while(f=f.nextSibling)}}}}})();r.L=function(){};
r.a.extend(r.L.prototype,{nodeHasBindings:function(a){switch(a.nodeType){case 1:return a.getAttribute("data-bind")!=o;case 8:return r.f.ta(a)!=o;default:return p}},getBindings:function(a,b){var d=this.getBindingsString(a,b);return d?this.parseBindingsString(d,b):o},getBindingsString:function(a){switch(a.nodeType){case 1:return a.getAttribute("data-bind");case 8:return r.f.ta(a);default:return o}},parseBindingsString:function(a,b){try{var d=b.$data,e=" { "+r.j.ia(a)+" } ";return r.a.hb(e,d===o?window:
d,b)}catch(f){c(Error("Unable to parse bindings.\nMessage: "+f+";\nBindings value: "+a))}}});r.L.instance=new r.L;r.b("ko.bindingProvider",r.L);
(function(){function a(a,d){for(var h,g=d.childNodes[0];h=g;)g=r.f.nextSibling(h),b(a,h,p)}function b(b,f,h){var g=m,i=1==f.nodeType;i&&r.f.Fa(f);if(i&&h||r.L.instance.nodeHasBindings(f))g=d(f,o,b,h).Bb;i&&g&&a(b,f)}function d(a,b,d,g){function i(a){return function(){return n[a]}}function j(){return n}var k=0;r.f.ib(a);var n,t;new r.i(function(){var q=d&&d instanceof r.K?d:new r.K(r.a.d(d)),v=q.$data;g&&r.Na(a,q);if(n=("function"==typeof b?b():b)||r.L.instance.getBindings(a,q)){if(0===k){k=1;for(var s in n){var w=
r.c[s];w&&8===a.nodeType&&!r.f.C[s]&&c(Error("The binding '"+s+"' cannot be used with virtual elements"));if(w&&"function"==typeof w.init&&(w=(0,w.init)(a,i(s),j,v,q))&&w.controlsDescendantBindings)t!==l&&c(Error("Multiple bindings ("+t+" and "+s+") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.")),t=s}k=2}if(2===k)for(s in n)(w=r.c[s])&&"function"==typeof w.update&&(0,w.update)(a,i(s),j,v,q)}},o,{disposeWhenNodeIsRemoved:a});
return{Bb:t===l}}r.c={};r.K=function(a,b){this.$data=a;b?(this.$parent=b.$data,this.$parents=(b.$parents||[]).slice(0),this.$parents.unshift(this.$parent),this.$root=b.$root):(this.$parents=[],this.$root=a)};r.K.prototype.createChildContext=function(a){return new r.K(a,this)};r.Na=function(a,b){if(2==arguments.length)r.a.e.set(a,"__ko_bindingContext__",b);else return r.a.e.get(a,"__ko_bindingContext__")};r.xa=function(a,b,h){1===a.nodeType&&r.f.Fa(a);return d(a,b,h,m)};r.Ta=function(b,d){1===d.nodeType&&
a(b,d)};r.wa=function(a,d){d&&1!==d.nodeType&&8!==d.nodeType&&c(Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node"));d=d||window.document.body;b(a,d,m)};r.ea=function(a){switch(a.nodeType){case 1:case 8:var b=r.Na(a);if(b)return b;if(a.parentNode)return r.ea(a.parentNode)}};r.$a=function(a){return(a=r.ea(a))?a.$data:l};r.b("ko.bindingHandlers",r.c);r.b("ko.applyBindings",r.wa);r.b("ko.applyBindingsToDescendants",r.Ta);r.b("ko.applyBindingsToNode",
r.xa);r.b("ko.contextFor",r.ea);r.b("ko.dataFor",r.$a)})();r.a.n(["click"],function(a){r.c[a]={init:function(b,d,e,f){return r.c.event.init.call(this,b,function(){var b={};b[a]=d();return b},e,f)}}});
r.c.event={init:function(a,b,d,e){var f=b()||{},h;for(h in f)(function(){var f=h;"string"==typeof f&&r.a.s(a,f,function(a){var h,k=b()[f];if(k){var n=d();try{var t=r.a.X(arguments);t.unshift(e);h=k.apply(e,t)}finally{if(h!==m)a.preventDefault?a.preventDefault():a.returnValue=p}if(n[f+"Bubble"]===p)a.cancelBubble=m,a.stopPropagation&&a.stopPropagation()}})})()}};
r.c.submit={init:function(a,b,d,e){"function"!=typeof b()&&c(Error("The value for a submit binding must be a function"));r.a.s(a,"submit",function(d){var h,g=b();try{h=g.call(e,a)}finally{if(h!==m)d.preventDefault?d.preventDefault():d.returnValue=p}})}};r.c.visible={update:function(a,b){var d=r.a.d(b()),e="none"!=a.style.display;if(d&&!e)a.style.display="";else if(!d&&e)a.style.display="none"}};
r.c.enable={update:function(a,b){var d=r.a.d(b());if(d&&a.disabled)a.removeAttribute("disabled");else if(!d&&!a.disabled)a.disabled=m}};r.c.disable={update:function(a,b){r.c.enable.update(a,function(){return!r.a.d(b())})}};function D(a,b,d){d&&b!==r.h.q(a)&&r.h.S(a,b);b!==r.h.q(a)&&r.a.sa(a,"change")}
r.c.value={init:function(a,b,d){var e=["change"],f=d().valueUpdate;f&&("string"==typeof f&&(f=[f]),r.a.J(e,f),e=r.a.ya(e));r.a.n(e,function(e){var f=p;r.a.Cb(e,"after")&&(f=m,e=e.substring(5));var i=f?function(a){setTimeout(a,0)}:function(a){a()};r.a.s(a,e,function(){i(function(){var e=b(),f=r.h.q(a);r.P(e)?e(f):(e=d(),e._ko_property_writers&&e._ko_property_writers.value&&e._ko_property_writers.value(f))})})})},update:function(a,b){var d=r.a.d(b()),e=r.h.q(a),f=d!=e;0===d&&0!==e&&"0"!==e&&(f=m);f&&
(e=function(){r.h.S(a,d)},e(),"SELECT"==a.tagName&&setTimeout(e,0));"SELECT"==a.tagName&&0<a.length&&D(a,d,p)}};
r.c.options={update:function(a,b,d){"SELECT"!=a.tagName&&c(Error("options binding applies only to SELECT elements"));var e=0==a.length,f=r.a.ba(r.a.aa(a.childNodes,function(a){return a.tagName&&"OPTION"==a.tagName&&a.selected}),function(a){return r.h.q(a)||a.innerText||a.textContent}),h=a.scrollTop;a.scrollTop=0;for(var g=r.a.d(b());0<a.length;)r.F(a.options[0]),a.remove(0);if(g){d=d();"number"!=typeof g.length&&(g=[g]);if(d.optionsCaption){var i=document.createElement("OPTION");r.a.Z(i,d.optionsCaption);
r.h.S(i,l);a.appendChild(i)}for(var b=0,j=g.length;b<j;b++){var i=document.createElement("OPTION"),k="string"==typeof d.optionsValue?g[b][d.optionsValue]:g[b],k=r.a.d(k);r.h.S(i,k);var n=d.optionsText,k="function"==typeof n?n(g[b]):"string"==typeof n?g[b][n]:k;if(k===o||k===l)k="";r.a.Ma(i,k);a.appendChild(i)}g=a.getElementsByTagName("OPTION");b=i=0;for(j=g.length;b<j;b++)0<=r.a.k(f,r.h.q(g[b]))&&(r.a.La(g[b],m),i++);if(h)a.scrollTop=h;e&&"value"in d&&D(a,r.a.d(d.value),m)}}};r.c.options.la="__ko.optionValueDomData__";
r.c.selectedOptions={Da:function(a){for(var b=[],a=a.childNodes,d=0,e=a.length;d<e;d++){var f=a[d];"OPTION"==f.tagName&&f.selected&&b.push(r.h.q(f))}return b},init:function(a,b,d){r.a.s(a,"change",function(){var a=b();r.P(a)?a(r.c.selectedOptions.Da(this)):(a=d(),a._ko_property_writers&&a._ko_property_writers.value&&a._ko_property_writers.value(r.c.selectedOptions.Da(this)))})},update:function(a,b){"SELECT"!=a.tagName&&c(Error("values binding applies only to SELECT elements"));var d=r.a.d(b());if(d&&
"number"==typeof d.length)for(var e=a.childNodes,f=0,h=e.length;f<h;f++){var g=e[f];"OPTION"==g.tagName&&r.a.La(g,0<=r.a.k(d,r.h.q(g)))}}};r.c.text={update:function(a,b){r.a.Ma(a,b())}};r.c.html={init:function(){return{controlsDescendantBindings:m}},update:function(a,b){var d=r.a.d(b());r.a.Z(a,d)}};r.c.css={update:function(a,b){var d=r.a.d(b()||{}),e;for(e in d)if("string"==typeof e){var f=r.a.d(d[e]);r.a.Qa(a,e,f)}}};
r.c.style={update:function(a,b){var d=r.a.d(b()||{}),e;for(e in d)if("string"==typeof e){var f=r.a.d(d[e]);a.style[e]=f||""}}};r.c.uniqueName={init:function(a,b){if(b())a.name="ko_unique_"+ ++r.c.uniqueName.Za,(r.a.ob||r.a.pb)&&a.mergeAttributes(document.createElement("<input name='"+a.name+"'/>"),p)}};r.c.uniqueName.Za=0;
r.c.checked={init:function(a,b,d){r.a.s(a,"click",function(){var e;if("checkbox"==a.type)e=a.checked;else if("radio"==a.type&&a.checked)e=a.value;else return;var f=b();"checkbox"==a.type&&r.a.d(f)instanceof Array?(e=r.a.k(r.a.d(f),a.value),a.checked&&0>e?f.push(a.value):!a.checked&&0<=e&&f.splice(e,1)):r.P(f)?f()!==e&&f(e):(f=d(),f._ko_property_writers&&f._ko_property_writers.checked&&f._ko_property_writers.checked(e))});"radio"==a.type&&!a.name&&r.c.uniqueName.init(a,function(){return m})},update:function(a,
b){var d=r.a.d(b());if("checkbox"==a.type)a.checked=d instanceof Array?0<=r.a.k(d,a.value):d;else if("radio"==a.type)a.checked=a.value==d}};r.c.attr={update:function(a,b){var d=r.a.d(b())||{},e;for(e in d)if("string"==typeof e){var f=r.a.d(d[e]);f===p||f===o||f===l?a.removeAttribute(e):a.setAttribute(e,f.toString())}}};
r.c.hasfocus={init:function(a,b,d){function e(a){var e=b();a!=r.a.d(e)&&(r.P(e)?e(a):(e=d(),e._ko_property_writers&&e._ko_property_writers.hasfocus&&e._ko_property_writers.hasfocus(a)))}r.a.s(a,"focus",function(){e(m)});r.a.s(a,"focusin",function(){e(m)});r.a.s(a,"blur",function(){e(p)});r.a.s(a,"focusout",function(){e(p)})},update:function(a,b){var d=r.a.d(b());d?a.focus():a.blur();r.a.sa(a,d?"focusin":"focusout")}};
r.c["with"]={o:function(a){return function(){var b=a();return{"if":b,data:b,templateEngine:r.p.M}}},init:function(a,b){return r.c.template.init(a,r.c["with"].o(b))},update:function(a,b,d,e,f){return r.c.template.update(a,r.c["with"].o(b),d,e,f)}};r.j.D["with"]=p;r.f.C["with"]=m;r.c["if"]={o:function(a){return function(){return{"if":a(),templateEngine:r.p.M}}},init:function(a,b){return r.c.template.init(a,r.c["if"].o(b))},update:function(a,b,d,e,f){return r.c.template.update(a,r.c["if"].o(b),d,e,f)}};
r.j.D["if"]=p;r.f.C["if"]=m;r.c.ifnot={o:function(a){return function(){return{ifnot:a(),templateEngine:r.p.M}}},init:function(a,b){return r.c.template.init(a,r.c.ifnot.o(b))},update:function(a,b,d,e,f){return r.c.template.update(a,r.c.ifnot.o(b),d,e,f)}};r.j.D.ifnot=p;r.f.C.ifnot=m;
r.c.foreach={o:function(a){return function(){var b=r.a.d(a());return!b||"number"==typeof b.length?{foreach:b,templateEngine:r.p.M}:{foreach:b.data,includeDestroyed:b.includeDestroyed,afterAdd:b.afterAdd,beforeRemove:b.beforeRemove,afterRender:b.afterRender,templateEngine:r.p.M}}},init:function(a,b){return r.c.template.init(a,r.c.foreach.o(b))},update:function(a,b,d,e,f){return r.c.template.update(a,r.c.foreach.o(b),d,e,f)}};r.j.D.foreach=p;r.f.C.foreach=m;r.b("ko.allowedVirtualElementBindings",r.f.C);
r.t=function(){};r.t.prototype.renderTemplateSource=function(){c("Override renderTemplateSource")};r.t.prototype.createJavaScriptEvaluatorBlock=function(){c("Override createJavaScriptEvaluatorBlock")};r.t.prototype.makeTemplateSource=function(a){if("string"==typeof a){var b=document.getElementById(a);b||c(Error("Cannot find template with ID "+a));return new r.m.g(b)}if(1==a.nodeType||8==a.nodeType)return new r.m.I(a);c(Error("Unknown template type: "+a))};
r.t.prototype.renderTemplate=function(a,b,d){return this.renderTemplateSource(this.makeTemplateSource(a),b,d)};r.t.prototype.isTemplateRewritten=function(a){return this.allowTemplateRewriting===p?m:this.W&&this.W[a]?m:this.makeTemplateSource(a).data("isRewritten")};r.t.prototype.rewriteTemplate=function(a,b){var d=this.makeTemplateSource(a),e=b(d.text());d.text(e);d.data("isRewritten",m);if("string"==typeof a)this.W=this.W||{},this.W[a]=m};r.b("ko.templateEngine",r.t);
r.$=function(){function a(a,b,d){for(var a=r.j.Y(a),g=r.j.D,i=0;i<a.length;i++){var j=a[i].key;if(g.hasOwnProperty(j)){var k=g[j];"function"===typeof k?(j=k(a[i].value))&&c(Error(j)):k||c(Error("This template engine does not support the '"+j+"' binding within its templates"))}}a="ko.templateRewriting.applyMemoizedBindingsToNextSibling(function() { return (function() { return { "+r.j.ia(a)+" } })() })";return d.createJavaScriptEvaluatorBlock(a)+b}var b=/(<[a-z]+\d*(\s+(?!data-bind=)[a-z0-9\-]+(=(\"[^\"]*\"|\'[^\']*\'))?)*\s+)data-bind=(["'])([\s\S]*?)\5/gi,
d=/<\!--\s*ko\b\s*([\s\S]*?)\s*--\>/g;return{gb:function(a,b){b.isTemplateRewritten(a)||b.rewriteTemplate(a,function(a){return r.$.ub(a,b)})},ub:function(e,f){return e.replace(b,function(b,e,d,j,k,n,t){return a(t,e,f)}).replace(d,function(b,e){return a(e,"<\!-- ko --\>",f)})},Ua:function(a){return r.r.ka(function(b,d){b.nextSibling&&r.xa(b.nextSibling,a,d)})}}}();r.b("ko.templateRewriting",r.$);r.b("ko.templateRewriting.applyMemoizedBindingsToNextSibling",r.$.Ua);r.m={};r.m.g=function(a){this.g=a};
r.m.g.prototype.text=function(){if(0==arguments.length)return"script"==this.g.tagName.toLowerCase()?this.g.text:this.g.innerHTML;var a=arguments[0];"script"==this.g.tagName.toLowerCase()?this.g.text=a:r.a.Z(this.g,a)};r.m.g.prototype.data=function(a){if(1===arguments.length)return r.a.e.get(this.g,"templateSourceData_"+a);r.a.e.set(this.g,"templateSourceData_"+a,arguments[1])};r.m.I=function(a){this.g=a};r.m.I.prototype=new r.m.g;
r.m.I.prototype.text=function(){if(0==arguments.length)return r.a.e.get(this.g,"__ko_anon_template__");r.a.e.set(this.g,"__ko_anon_template__",arguments[0])};r.b("ko.templateSources",r.m);r.b("ko.templateSources.domElement",r.m.g);r.b("ko.templateSources.anonymousTemplate",r.m.I);
(function(){function a(a,b,d){for(var g=0;node=a[g];g++)node.parentNode===b&&(1===node.nodeType||8===node.nodeType)&&d(node)}function b(a,b,h,g,i){var i=i||{},j=i.templateEngine||d;r.$.gb(h,j);h=j.renderTemplate(h,g,i);("number"!=typeof h.length||0<h.length&&"number"!=typeof h[0].nodeType)&&c("Template engine must return an array of DOM nodes");j=p;switch(b){case "replaceChildren":r.f.oa(a,h);j=m;break;case "replaceNode":r.a.Ja(a,h);j=m;break;case "ignoreTargetNode":break;default:c(Error("Unknown renderMode: "+
b))}j&&(r.ua(h,g),i.afterRender&&i.afterRender(h,g.$data));return h}var d;r.pa=function(a){a!=l&&!(a instanceof r.t)&&c("templateEngine must inherit from ko.templateEngine");d=a};r.ua=function(b,d){var h=r.a.J([],b),g=0<b.length?b[0].parentNode:o;a(h,g,function(a){r.wa(d,a)});a(h,g,function(a){r.r.Sa(a,[d])})};r.na=function(a,f,h,g,i){h=h||{};(h.templateEngine||d)==l&&c("Set a template engine before calling renderTemplate");i=i||"replaceChildren";if(g){var j=g.nodeType?g:0<g.length?g[0]:o;return new r.i(function(){var d=
f&&f instanceof r.K?f:new r.K(r.a.d(f)),n="function"==typeof a?a(d.$data):a,d=b(g,i,n,d,h);"replaceNode"==i&&(g=d,j=g.nodeType?g:0<g.length?g[0]:o)},o,{disposeWhen:function(){return!j||!r.a.ga(j)},disposeWhenNodeIsRemoved:j&&"replaceNode"==i?j.parentNode:j})}return r.r.ka(function(b){r.na(a,f,h,b,"replaceNode")})};r.Ab=function(a,d,h,g,i){function j(a,b){var d=k(a);r.ua(b,d);h.afterRender&&h.afterRender(b,d.$data)}function k(a){return i.createChildContext(r.a.d(a))}return new r.i(function(){var i=
r.a.d(d)||[];"undefined"==typeof i.length&&(i=[i]);i=r.a.aa(i,function(a){return h.includeDestroyed||a===l||a===o||!r.a.d(a._destroy)});r.a.Ka(g,i,function(d){var f="function"==typeof a?a(d):a;return b(o,"ignoreTargetNode",f,k(d),h)},h,j)},o,{disposeWhenNodeIsRemoved:g})};r.c.template={init:function(a,b){var d=r.a.d(b());"string"!=typeof d&&!d.name&&1==a.nodeType&&((new r.m.I(a)).text(a.innerHTML),r.a.U(a));return{controlsDescendantBindings:m}},update:function(a,b,d,g,i){b=r.a.d(b());g=m;"string"==
typeof b?d=b:(d=b.name,"if"in b&&(g=g&&r.a.d(b["if"])),"ifnot"in b&&(g=g&&!r.a.d(b.ifnot)));var j=o;"object"===typeof b&&"foreach"in b?j=r.Ab(d||a,g&&b.foreach||[],b,a,i):g?(i="object"==typeof b&&"data"in b?i.createChildContext(r.a.d(b.data)):i,j=r.na(d||a,i,b,a)):r.f.ha(a);i=j;(b=r.a.e.get(a,"__ko__templateSubscriptionDomDataKey__"))&&"function"==typeof b.v&&b.v();r.a.e.set(a,"__ko__templateSubscriptionDomDataKey__",i)}};r.j.D.template=function(a){a=r.j.Y(a);return 1==a.length&&a[0].unknown?o:r.j.rb(a,
"name")?o:"This template engine does not support anonymous templates nested within its templates"};r.f.C.template=m})();r.b("ko.setTemplateEngine",r.pa);r.b("ko.renderTemplate",r.na);
r.a.N=function(a,b,d){if(d===l)return r.a.N(a,b,1)||r.a.N(a,b,10)||r.a.N(a,b,Number.MAX_VALUE);for(var a=a||[],b=b||[],e=a,f=b,h=[],g=0;g<=f.length;g++)h[g]=[];for(var g=0,i=Math.min(e.length,d);g<=i;g++)h[0][g]=g;g=1;for(i=Math.min(f.length,d);g<=i;g++)h[g][0]=g;for(var i=e.length,j,k=f.length,g=1;g<=i;g++){j=Math.max(1,g-d);for(var n=Math.min(k,g+d);j<=n;j++)h[j][g]=e[g-1]===f[j-1]?h[j-1][g-1]:Math.min(h[j-1][g]===l?Number.MAX_VALUE:h[j-1][g]+1,h[j][g-1]===l?Number.MAX_VALUE:h[j][g-1]+1)}d=a.length;
e=b.length;f=[];g=h[e][d];if(g===l)h=o;else{for(;0<d||0<e;){i=h[e][d];k=0<e?h[e-1][d]:g+1;n=0<d?h[e][d-1]:g+1;j=0<e&&0<d?h[e-1][d-1]:g+1;if(k===l||k<i-1)k=g+1;if(n===l||n<i-1)n=g+1;j<i-1&&(j=g+1);k<=n&&k<j?(f.push({status:"added",value:b[e-1]}),e--):(n<k&&n<j?f.push({status:"deleted",value:a[d-1]}):(f.push({status:"retained",value:a[d-1]}),e--),d--)}h=f.reverse()}return h};r.b("ko.utils.compareArrays",r.a.N);
(function(){function a(a){if(2<a.length){for(var b=a[0],f=a[a.length-1],h=[b];b!==f;){b=b.nextSibling;if(!b)return;h.push(b)}Array.prototype.splice.apply(a,[0,a.length].concat(h))}}function b(b,e,f,h){var g=[],b=r.i(function(){var b=e(f)||[];0<g.length&&(a(g),r.a.Ja(g,b),h&&h(f,b));g.splice(0,g.length);r.a.J(g,b)},o,{disposeWhenNodeIsRemoved:b,disposeWhen:function(){return 0==g.length||!r.a.ga(g[0])}});return{sb:g,i:b}}r.a.Ka=function(d,e,f,h,g){for(var e=e||[],h=h||{},i=r.a.e.get(d,"setDomNodeChildrenFromArrayMapping_lastMappingResult")===
l,j=r.a.e.get(d,"setDomNodeChildrenFromArrayMapping_lastMappingResult")||[],k=r.a.ba(j,function(a){return a.Va}),n=r.a.N(k,e),e=[],t=0,q=[],k=[],v=o,s=0,w=n.length;s<w;s++)switch(n[s].status){case "retained":var x=j[t];e.push(x);0<x.O.length&&(v=x.O[x.O.length-1]);t++;break;case "deleted":j[t].i.v();a(j[t].O);r.a.n(j[t].O,function(a){q.push({element:a,index:s,value:n[s].value});v=a});t++;break;case "added":var x=n[s].value,z=b(d,f,x,g),u=z.sb;e.push({Va:n[s].value,O:u,i:z.i});for(var z=0,y=u.length;z<
y;z++){var A=u[z];k.push({element:A,index:s,value:n[s].value});v==o?r.f.xb(d,A):r.f.mb(d,A,v);v=A}g&&g(x,u)}r.a.n(q,function(a){r.F(a.element)});f=p;if(!i){if(h.afterAdd)for(s=0;s<k.length;s++)h.afterAdd(k[s].element,k[s].index,k[s].value);if(h.beforeRemove){for(s=0;s<q.length;s++)h.beforeRemove(q[s].element,q[s].index,q[s].value);f=m}}f||r.a.n(q,function(a){r.removeNode(a.element)});r.a.e.set(d,"setDomNodeChildrenFromArrayMapping_lastMappingResult",e)}})();
r.b("ko.utils.setDomNodeChildrenFromArrayMapping",r.a.Ka);r.p=function(){this.allowTemplateRewriting=p};r.p.prototype=new r.t;r.p.prototype.renderTemplateSource=function(a){a=a.text();return r.a.ma(a)};r.p.M=new r.p;r.pa(r.p.M);r.b("ko.nativeTemplateEngine",r.p);
(function(){r.ja=function(){var a=this.qb=function(){if("undefined"==typeof jQuery||!jQuery.tmpl)return 0;try{if(0<=jQuery.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}();this.renderTemplateSource=function(d,e,f){f=f||{};2>a&&c(Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later."));var h=d.data("precompiled");h||(h=d.text()||"",h=jQuery.template(o,"{{ko_with $item.koBindingContext}}"+h+"{{/ko_with}}"),d.data("precompiled",h));
d=[e.$data];e=jQuery.extend({koBindingContext:e},f.templateOptions);e=jQuery.tmpl(h,d,e);e.appendTo(document.createElement("div"));jQuery.fragments={};return e};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+a+" })()) }}"};this.addTemplate=function(a,b){document.write("<script type='text/html' id='"+a+"'>"+b+"<\/script>")};if(0<a)jQuery.tmpl.tag.ko_code={open:"__.push($1 || '');"},jQuery.tmpl.tag.ko_with={open:"with($1) {",close:"} "}};r.ja.prototype=new r.t;
var a=new r.ja;0<a.qb&&r.pa(a);r.b("ko.jqueryTmplTemplateEngine",r.ja)})();
})(window);
// Underscore.js 1.2.1
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore
(function() {
// Baseline setup
// --------------
// Establish the root object, `window` in the browser, or `global` on the server.
var root = this;
// Save the previous value of the `_` variable.
var previousUnderscore = root._;
// Establish the object that gets returned to break out of a loop iteration.
var breaker = {};
// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
// Create quick reference variables for speed access to core prototypes.
var slice = ArrayProto.slice,
unshift = ArrayProto.unshift,
toString = ObjProto.toString,
hasOwnProperty = ObjProto.hasOwnProperty;
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
var
nativeForEach = ArrayProto.forEach,
nativeMap = ArrayProto.map,
nativeReduce = ArrayProto.reduce,
nativeReduceRight = ArrayProto.reduceRight,
nativeFilter = ArrayProto.filter,
nativeEvery = ArrayProto.every,
nativeSome = ArrayProto.some,
nativeIndexOf = ArrayProto.indexOf,
nativeLastIndexOf = ArrayProto.lastIndexOf,
nativeIsArray = Array.isArray,
nativeKeys = Object.keys,
nativeBind = FuncProto.bind;
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) { return new wrapper(obj); };
// Export the Underscore object for **Node.js** and **"CommonJS"**, with
// backwards-compatibility for the old `require()` API. If we're not in
// CommonJS, add `_` to the global object.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else if (typeof define === 'function' && define.amd) {
// Register as a named module with AMD.
define('underscore', function() {
return _;
});
} else {
// Exported as a string, for Closure Compiler "advanced" mode.
root['_'] = _;
}
// Current version.
_.VERSION = '1.2.1';
// Collection Functions
// --------------------
// The cornerstone, an `each` implementation, aka `forEach`.
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
}
};
// Return the results of applying the iterator to each element.
// Delegates to **ECMAScript 5**'s native `map` if available.
_.map = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
each(obj, function(value, index, list) {
results[results.length] = iterator.call(context, value, index, list);
});
return results;
};
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
var initial = memo !== void 0;
if (obj == null) obj = [];
if (nativeReduce && obj.reduce === nativeReduce) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
each(obj, function(value, index, list) {
if (!initial) {
memo = value;
initial = true;
} else {
memo = iterator.call(context, memo, value, index, list);
}
});
if (!initial) throw new TypeError("Reduce of empty array with no initial value");
return memo;
};
// The right-associative version of reduce, also known as `foldr`.
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
if (obj == null) obj = [];
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if (context) iterator = _.bind(iterator, context);
return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
}
var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
return _.reduce(reversed, iterator, memo, context);
};
// Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, iterator, context) {
var result;
any(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) {
result = value;
return true;
}
});
return result;
};
// Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`.
_.filter = _.select = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
each(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
// Return all the elements for which a truth test fails.
_.reject = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
each(obj, function(value, index, list) {
if (!iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
// Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
_.every = _.all = function(obj, iterator, context) {
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
each(obj, function(value, index, list) {
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
});
return result;
};
// Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`.
var any = _.some = _.any = function(obj, iterator, context) {
iterator = iterator || _.identity;
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
each(obj, function(value, index, list) {
if (result |= iterator.call(context, value, index, list)) return breaker;
});
return !!result;
};
// Determine if a given value is included in the array or object using `===`.
// Aliased as `contains`.
_.include = _.contains = function(obj, target) {
var found = false;
if (obj == null) return found;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
found = any(obj, function(value) {
if (value === target) return true;
});
return found;
};
// Invoke a method (with arguments) on every item in a collection.
_.invoke = function(obj, method) {
var args = slice.call(arguments, 2);
return _.map(obj, function(value) {
return (method.call ? method || value : value[method]).apply(value, args);
});
};
// Convenience version of a common use case of `map`: fetching a property.
_.pluck = function(obj, key) {
return _.map(obj, function(value){ return value[key]; });
};
// Return the maximum element or (element-based computation).
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return -Infinity;
var result = {computed : -Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed >= result.computed && (result = {value : value, computed : computed});
});
return result.value;
};
// Return the minimum element (or element-based computation).
_.min = function(obj, iterator, context) {
if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return Infinity;
var result = {computed : Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed < result.computed && (result = {value : value, computed : computed});
});
return result.value;
};
// Shuffle an array.
_.shuffle = function(obj) {
var shuffled = [], rand;
each(obj, function(value, index, list) {
if (index == 0) {
shuffled[0] = value;
} else {
rand = Math.floor(Math.random() * (index + 1));
shuffled[index] = shuffled[rand];
shuffled[rand] = value;
}
});
return shuffled;
};
// Sort the object's values by a criterion produced by an iterator.
_.sortBy = function(obj, iterator, context) {
return _.pluck(_.map(obj, function(value, index, list) {
return {
value : value,
criteria : iterator.call(context, value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
}), 'value');
};
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = function(obj, val) {
var result = {};
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
each(obj, function(value, index) {
var key = iterator(value, index);
(result[key] || (result[key] = [])).push(value);
});
return result;
};
// Use a comparator function to figure out at what index an object should
// be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iterator) {
iterator || (iterator = _.identity);
var low = 0, high = array.length;
while (low < high) {
var mid = (low + high) >> 1;
iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
}
return low;
};
// Safely convert anything iterable into a real, live array.
_.toArray = function(iterable) {
if (!iterable) return [];
if (iterable.toArray) return iterable.toArray();
if (_.isArray(iterable)) return slice.call(iterable);
if (_.isArguments(iterable)) return slice.call(iterable);
return _.values(iterable);
};
// Return the number of elements in an object.
_.size = function(obj) {
return _.toArray(obj).length;
};
// Array Functions
// ---------------
// Get the first element of an array. Passing **n** will return the first N
// values in the array. Aliased as `head`. The **guard** check allows it to work
// with `_.map`.
_.first = _.head = function(array, n, guard) {
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
};
// Returns everything but the last entry of the array. Especcialy useful on
// the arguments object. Passing **n** will return all the values in
// the array, excluding the last N. The **guard** check allows it to work with
// `_.map`.
_.initial = function(array, n, guard) {
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
};
// Get the last element of an array. Passing **n** will return the last N
// values in the array. The **guard** check allows it to work with `_.map`.
_.last = function(array, n, guard) {
return (n != null) && !guard ? slice.call(array, array.length - n) : array[array.length - 1];
};
// Returns everything but the first entry of the array. Aliased as `tail`.
// Especially useful on the arguments object. Passing an **index** will return
// the rest of the values in the array from that index onward. The **guard**
// check allows it to work with `_.map`.
_.rest = _.tail = function(array, index, guard) {
return slice.call(array, (index == null) || guard ? 1 : index);
};
// Trim out all falsy values from an array.
_.compact = function(array) {
return _.filter(array, function(value){ return !!value; });
};
// Return a completely flattened version of an array.
_.flatten = function(array, shallow) {
return _.reduce(array, function(memo, value) {
if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
memo[memo.length] = value;
return memo;
}, []);
};
// Return a version of the array that does not contain the specified value(s).
_.without = function(array) {
return _.difference(array, slice.call(arguments, 1));
};
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
_.uniq = _.unique = function(array, isSorted, iterator) {
var initial = iterator ? _.map(array, iterator) : array;
var result = [];
_.reduce(initial, function(memo, el, i) {
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
memo[memo.length] = el;
result[result.length] = array[i];
}
return memo;
}, []);
return result;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
return _.uniq(_.flatten(arguments, true));
};
// Produce an array that contains every item shared between all the
// passed-in arrays. (Aliased as "intersect" for back-compat.)
_.intersection = _.intersect = function(array) {
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
return _.indexOf(other, item) >= 0;
});
});
};
// Take the difference between one array and another.
// Only the elements present in just the first array will remain.
_.difference = function(array, other) {
return _.filter(array, function(value){ return !_.include(other, value); });
};
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
var args = slice.call(arguments);
var length = _.max(_.pluck(args, 'length'));
var results = new Array(length);
for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
return results;
};
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
// we need this function. Return the position of the first occurrence of an
// item in an array, or -1 if the item is not included in the array.
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
var i, l;
if (isSorted) {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
return -1;
};
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_.lastIndexOf = function(array, item) {
if (array == null) return -1;
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
var i = array.length;
while (i--) if (array[i] === item) return i;
return -1;
};
// Generate an integer Array containing an arithmetic progression. A port of
// the native Python `range()` function. See
// [the Python documentation](http://docs.python.org/library/functions.html#range).
_.range = function(start, stop, step) {
if (arguments.length <= 1) {
stop = start || 0;
start = 0;
}
step = arguments[2] || 1;
var len = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
var range = new Array(len);
while(idx < len) {
range[idx++] = start;
start += step;
}
return range;
};
// Function (ahem) Functions
// ------------------
// Reusable constructor function for prototype setting.
var ctor = function(){};
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Binding with arguments is also known as `curry`.
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
// We check for `func.bind` first, to fail fast when `func` is undefined.
_.bind = function bind(func, context) {
var bound, args;
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError;
args = slice.call(arguments, 2);
return bound = function() {
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
ctor.prototype = func.prototype;
var self = new ctor;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
};
};
// Bind all of an object's methods to that object. Useful for ensuring that
// all callbacks defined on an object belong to it.
_.bindAll = function(obj) {
var funcs = slice.call(arguments, 1);
if (funcs.length == 0) funcs = _.functions(obj);
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
return obj;
};
// Memoize an expensive function by storing its results.
_.memoize = function(func, hasher) {
var memo = {};
hasher || (hasher = _.identity);
return function() {
var key = hasher.apply(this, arguments);
return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
};
};
// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
_.delay = function(func, wait) {
var args = slice.call(arguments, 2);
return setTimeout(function(){ return func.apply(func, args); }, wait);
};
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_.defer = function(func) {
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
};
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time.
_.throttle = function(func, wait) {
var timeout, context, args, throttling, finishThrottle;
finishThrottle = _.debounce(function(){ throttling = false; }, wait);
return function() {
context = this; args = arguments;
var throttler = function() {
timeout = null;
func.apply(context, args);
finishThrottle();
};
if (!timeout) timeout = setTimeout(throttler, wait);
if (!throttling) func.apply(context, args);
if (finishThrottle) finishThrottle();
throttling = true;
};
};
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds.
_.debounce = function(func, wait) {
var timeout;
return function() {
var context = this, args = arguments;
var throttler = function() {
timeout = null;
func.apply(context, args);
};
clearTimeout(timeout);
timeout = setTimeout(throttler, wait);
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = function(func) {
var ran = false, memo;
return function() {
if (ran) return memo;
ran = true;
return memo = func.apply(this, arguments);
};
};
// Returns the first function passed as an argument to the second,
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
_.wrap = function(func, wrapper) {
return function() {
var args = [func].concat(slice.call(arguments));
return wrapper.apply(this, args);
};
};
// Returns a function that is the composition of a list of functions, each
// consuming the return value of the function that follows.
_.compose = function() {
var funcs = slice.call(arguments);
return function() {
var args = slice.call(arguments);
for (var i = funcs.length - 1; i >= 0; i--) {
args = [funcs[i].apply(this, args)];
}
return args[0];
};
};
// Returns a function that will only be executed after being called N times.
_.after = function(times, func) {
return function() {
if (--times < 1) { return func.apply(this, arguments); }
};
};
// Object Functions
// ----------------
// Retrieve the names of an object's properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = nativeKeys || function(obj) {
if (obj !== Object(obj)) throw new TypeError('Invalid object');
var keys = [];
for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
return keys;
};
// Retrieve the values of an object's properties.
_.values = function(obj) {
return _.map(obj, _.identity);
};
// Return a sorted list of the function names available on the object.
// Aliased as `methods`
_.functions = _.methods = function(obj) {
var names = [];
for (var key in obj) {
if (_.isFunction(obj[key])) names.push(key);
}
return names.sort();
};
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
if (source[prop] !== void 0) obj[prop] = source[prop];
}
});
return obj;
};
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
if (obj[prop] == null) obj[prop] = source[prop];
}
});
return obj;
};
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
// Invokes interceptor with the obj, and then returns obj.
// The primary purpose of this method is to "tap into" a method chain, in
// order to perform operations on intermediate results within the chain.
_.tap = function(obj, interceptor) {
interceptor(obj);
return obj;
};
// Internal recursive comparison function.
function eq(a, b, stack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
if (a === b) return a !== 0 || 1 / a == 1 / b;
// A strict comparison is necessary because `null == undefined`.
if ((a == null) || (b == null)) return a === b;
// Unwrap any wrapped objects.
if (a._chain) a = a._wrapped;
if (b._chain) b = b._wrapped;
// Invoke a custom `isEqual` method if one is provided.
if (_.isFunction(a.isEqual)) return a.isEqual(b);
if (_.isFunction(b.isEqual)) return b.isEqual(a);
// Compare object types.
var typeA = typeof a;
if (typeA != typeof b) return false;
// Optimization; ensure that both values are truthy or falsy.
if (!a != !b) return false;
// `NaN` values are equal.
if (_.isNaN(a)) return _.isNaN(b);
// Compare string objects by value.
var isStringA = _.isString(a), isStringB = _.isString(b);
if (isStringA || isStringB) return isStringA && isStringB && String(a) == String(b);
// Compare number objects by value.
var isNumberA = _.isNumber(a), isNumberB = _.isNumber(b);
if (isNumberA || isNumberB) return isNumberA && isNumberB && +a == +b;
// Compare boolean objects by value. The value of `true` is 1; the value of `false` is 0.
var isBooleanA = _.isBoolean(a), isBooleanB = _.isBoolean(b);
if (isBooleanA || isBooleanB) return isBooleanA && isBooleanB && +a == +b;
// Compare dates by their millisecond values.
var isDateA = _.isDate(a), isDateB = _.isDate(b);
if (isDateA || isDateB) return isDateA && isDateB && a.getTime() == b.getTime();
// Compare RegExps by their source patterns and flags.
var isRegExpA = _.isRegExp(a), isRegExpB = _.isRegExp(b);
if (isRegExpA || isRegExpB) {
// Ensure commutative equality for RegExps.
return isRegExpA && isRegExpB &&
a.source == b.source &&
a.global == b.global &&
a.multiline == b.multiline &&
a.ignoreCase == b.ignoreCase;
}
// Ensure that both values are objects.
if (typeA != 'object') return false;
// Arrays or Arraylikes with different lengths are not equal.
if (a.length !== b.length) return false;
// Objects with different constructors are not equal.
if (a.constructor !== b.constructor) return false;
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
var length = stack.length;
while (length--) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if (stack[length] == a) return true;
}
// Add the first object to the stack of traversed objects.
stack.push(a);
var size = 0, result = true;
// Deep compare objects.
for (var key in a) {
if (hasOwnProperty.call(a, key)) {
// Count the expected number of properties.
size++;
// Deep compare each member.
if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
}
}
// Ensure that both objects contain the same number of properties.
if (result) {
for (key in b) {
if (hasOwnProperty.call(b, key) && !size--) break;
}
result = !size;
}
// Remove the first object from the stack of traversed objects.
stack.pop();
return result;
}
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
return eq(a, b, []);
};
// Is a given array, string, or object empty?
// An "empty" object has no enumerable own-properties.
_.isEmpty = function(obj) {
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
return true;
};
// Is a given value a DOM element?
_.isElement = function(obj) {
return !!(obj && obj.nodeType == 1);
};
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) == '[object Array]';
};
// Is a given variable an object?
_.isObject = function(obj) {
return obj === Object(obj);
};
// Is a given variable an arguments object?
if (toString.call(arguments) == '[object Arguments]') {
_.isArguments = function(obj) {
return toString.call(obj) == '[object Arguments]';
};
} else {
_.isArguments = function(obj) {
return !!(obj && hasOwnProperty.call(obj, 'callee'));
};
}
// Is a given value a function?
_.isFunction = function(obj) {
return toString.call(obj) == '[object Function]';
};
// Is a given value a string?
_.isString = function(obj) {
return toString.call(obj) == '[object String]';
};
// Is a given value a number?
_.isNumber = function(obj) {
return toString.call(obj) == '[object Number]';
};
// Is the given value `NaN`?
_.isNaN = function(obj) {
// `NaN` is the only value for which `===` is not reflexive.
return obj !== obj;
};
// Is a given value a boolean?
_.isBoolean = function(obj) {
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
};
// Is a given value a date?
_.isDate = function(obj) {
return toString.call(obj) == '[object Date]';
};
// Is the given value a regular expression?
_.isRegExp = function(obj) {
return toString.call(obj) == '[object RegExp]';
};
// Is a given value equal to null?
_.isNull = function(obj) {
return obj === null;
};
// Is a given variable undefined?
_.isUndefined = function(obj) {
return obj === void 0;
};
// Utility Functions
// -----------------
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
// previous owner. Returns a reference to the Underscore object.
_.noConflict = function() {
root._ = previousUnderscore;
return this;
};
// Keep the identity function around for default iterators.
_.identity = function(value) {
return value;
};
// Run a function **n** times.
_.times = function (n, iterator, context) {
for (var i = 0; i < n; i++) iterator.call(context, i);
};
// Escape a string for HTML interpolation.
_.escape = function(string) {
return (''+string).replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
};
// Add your own custom functions to the Underscore object, ensuring that
// they're correctly added to the OOP wrapper as well.
_.mixin = function(obj) {
each(_.functions(obj), function(name){
addToWrapper(name, _[name] = obj[name]);
});
};
// Generate a unique integer id (unique within the entire client session).
// Useful for temporary DOM ids.
var idCounter = 0;
_.uniqueId = function(prefix) {
var id = idCounter++;
return prefix ? prefix + id : id;
};
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(str, data) {
var c = _.templateSettings;
var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
'with(obj||{}){__p.push(\'' +
str.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
.replace(c.escape, function(match, code) {
return "',_.escape(" + code.replace(/\\'/g, "'") + "),'";
})
.replace(c.interpolate, function(match, code) {
return "'," + code.replace(/\\'/g, "'") + ",'";
})
.replace(c.evaluate || null, function(match, code) {
return "');" + code.replace(/\\'/g, "'")
.replace(/[\r\n\t]/g, ' ') + "__p.push('";
})
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
.replace(/\t/g, '\\t')
+ "');}return __p.join('');";
var func = new Function('obj', tmpl);
return data ? func(data) : func;
};
// The OOP Wrapper
// ---------------
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
var wrapper = function(obj) { this._wrapped = obj; };
// Expose `wrapper.prototype` as `_.prototype`
_.prototype = wrapper.prototype;
// Helper function to continue chaining intermediate results.
var result = function(obj, chain) {
return chain ? _(obj).chain() : obj;
};
// A method to easily add functions to the OOP wrapper.
var addToWrapper = function(name, func) {
wrapper.prototype[name] = function() {
var args = slice.call(arguments);
unshift.call(args, this._wrapped);
return result(func.apply(_, args), this._chain);
};
};
// Add all of the Underscore functions to the wrapper object.
_.mixin(_);
// Add all mutator Array functions to the wrapper.
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = ArrayProto[name];
wrapper.prototype[name] = function() {
method.apply(this._wrapped, arguments);
return result(this._wrapped, this._chain);
};
});
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
wrapper.prototype[name] = function() {
return result(method.apply(this._wrapped, arguments), this._chain);
};
});
// Start chaining a wrapped Underscore object.
wrapper.prototype.chain = function() {
this._chain = true;
return this;
};
// Extracts the result from a wrapped and chained object.
wrapper.prototype.value = function() {
return this._wrapped;
};
})();
<!DOCTYPE html>
<html>
<!-- Support Localization -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<head>
<title>Knockback Demo: Todos</title>
<!-- Demo Dependencies -->
<script src="../vendor/json2.js"></script>
<script src="../vendor/jquery-1.7.min.js"></script>
<script src="../vendor/jquery.tmpl.min.js"></script>
<!-- Knockback Dependencies -->
<script src="dependencies/underscore.js"></script>
<script src="dependencies/backbone.js"></script>
<script src="dependencies/knockout-2.0.0.js"></script>
<script src="dependencies/knockback.js"></script>
<!-- The Demo -->
<link href="../css/todos.css" media="all" rel="stylesheet" type="text/css"/>
<script src="../vendor/backbone-localstorage.js"></script>
<script src="todos_classic.js"></script>
</head>
<body>
<!-- Todo App Interface -->
<div id="todoapp">
<!-- Header Section -->
<div id="todo-header">
<div class="title">
<h1>Todos</h1>
</div>
</div>
<!-- Create Todo Section -->
<div id="todo-create">
<div class="content">
<div id="create-todo">
<input id="new-todo" type="text" placeholder="What needs to be done?" data-bind="value: create.input_text, event: {keyup: create.addTodo}"/>
</div>
</div>
</div>
<!-- Todos List Section -->
<div id="todo-list">
<ul class="todo-list" data-bind="template: {name: 'item-template', foreach: todo_list.todos}"></ul>
</div>
<!-- Stats Section -->
<div id="todo-stats">
<span class="todo-count" data-bind="text: stats.remaining_text"></span>
<span class="todo-clear"> <a href="#" data-bind="text: stats.clear_text, click: stats.onDestroyDone"></a></span>
</div>
<!-- Footer Section -->
<div id="todo-footer">
<ul id="instructions">
<li>Double-click to edit a todo.</li>
</ul>
</div>
</div>
<div id="credits">
Created by
<br />
<a href="http://jgn.me/">J&eacute;r&ocirc;me Gravel-Niquet</a>
<br />
<br />
Modified to use <a href="https://github.com/kmalakoff/knockback">Knockback.js</a> by
<br />
<a href="https://github.com/kmalakoff">Kevin Malakoff</a>
<br />
and
<br />
<a href="https://github.com/yuchi">Pier Paolo Ramon</a>
</div>
<!-- Templates -->
<script type="text/x-jquery-tmpl" id="item-template">
<li>
<div class="todo" data-bind="css: {done: done, editing: edit_mode}">
<div class="display">
<input class="check" type="checkbox" data-bind="checked: done" />
<div class="todo-text" data-bind="text: text, dblclick: toggleEditMode"></div>
<div class="todo-destroy" data-bind="click: destroyTodo"></div>
</div>
<div class="edit">
<input class="todo-input" type="text" data-bind="value: text, event: {keyup: onEnterEndEdit}" />
</div>
</div>
</li>
</script>
</body>
</html>
###
knockback-todos.js
(c) 2011 Kevin Malakoff.
Knockback-Todos is freely distributable under the MIT license.
See the following for full license details:
https:#github.com/kmalakoff/knockback-todos/blob/master/LICENSE
###
$(document).ready(->
# add a doubleclick and placeholder handlers to KO
ko.bindingHandlers.dblclick =
init: (element, value_accessor, all_bindings_accessor, view_model) ->
$(element).dblclick(ko.utils.unwrapObservable(value_accessor()))
###################################
# Model: http://en.wikipedia.org/wiki/Model_view_controller
# ORM: http://en.wikipedia.org/wiki/Object-relational_mapping
###################################
# Todos
class TodoList extends Backbone.Collection
localStorage: new Store("kb_todos") # Save all of the todo items under the `"kb_todos"` namespace.
doneCount: -> @models.reduce(((prev,cur)-> return prev + if !!cur.get('done') then 1 else 0), 0)
remainingCount: -> @models.length - @doneCount()
allDone: -> return @filter((todo) -> return !!todo.get('done'))
todos = new TodoList()
todos.fetch()
###################################
# MVVM: http://en.wikipedia.org/wiki/Model_View_ViewModel
###################################
CreateTodoViewModel = ->
@input_text = ko.observable('')
@addTodo = (view_model, event) ->
text = @create.input_text()
return true if (!text || event.keyCode != 13)
todos.create({text: text})
@create.input_text('')
@
TodoViewModel = (model) ->
@text = kb.observable(model, {key: 'text', write: ((text) -> model.save({text: text}))}, this)
@edit_mode = ko.observable(false)
@toggleEditMode = (event) => @edit_mode(!@edit_mode()) if not @done()
@onEnterEndEdit = (event) => @edit_mode(false) if (event.keyCode == 13)
@done = kb.observable(model, {key: 'done', write: ((done) -> model.save({done: done})) }, this)
@destroyTodo = => model.destroy()
@
TodoListViewModel = (todos) ->
@todos = ko.observableArray([])
@collection_observable = kb.collectionObservable(todos, @todos, { view_model: TodoViewModel })
@
# Stats Footer
StatsViewModel = (todos) ->
@collection_observable = kb.collectionObservable(todos)
@remaining_text = ko.dependentObservable(=>
count = @collection_observable.collection().remainingCount(); return '' if not count
return "#{count} #{if count == 1 then 'item' else 'items'} remaining."
)
@clear_text = ko.dependentObservable(=>
count = @collection_observable.collection().doneCount(); return '' if not count
return "Clear #{count} completed #{if count == 1 then 'item' else 'items'}."
)
@onDestroyDone = => model.destroy() for model in todos.allDone()
@
app_view_model =
create: new CreateTodoViewModel()
todo_list: new TodoListViewModel(todos)
stats: new StatsViewModel(todos)
ko.applyBindings(app_view_model, $('#todoapp')[0])
# Destroy when finished with the view model
# kb.vmRelease(app_view_model)
)
\ No newline at end of file
/*
knockback-todos.js
(c) 2011 Kevin Malakoff.
Knockback-Todos is freely distributable under the MIT license.
See the following for full license details:
https:#github.com/kmalakoff/knockback-todos/blob/master/LICENSE
*/
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
return child;
}, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
$(document).ready(function() {
var CreateTodoViewModel, StatsViewModel, TodoList, TodoListViewModel, TodoViewModel, app_view_model, todos;
ko.bindingHandlers.dblclick = {
init: function(element, value_accessor, all_bindings_accessor, view_model) {
return $(element).dblclick(ko.utils.unwrapObservable(value_accessor()));
}
};
TodoList = (function() {
__extends(TodoList, Backbone.Collection);
function TodoList() {
TodoList.__super__.constructor.apply(this, arguments);
}
TodoList.prototype.localStorage = new Store("kb_todos");
TodoList.prototype.doneCount = function() {
return this.models.reduce((function(prev, cur) {
return prev + (!!cur.get('done') ? 1 : 0);
}), 0);
};
TodoList.prototype.remainingCount = function() {
return this.models.length - this.doneCount();
};
TodoList.prototype.allDone = function() {
return this.filter(function(todo) {
return !!todo.get('done');
});
};
return TodoList;
})();
todos = new TodoList();
todos.fetch();
CreateTodoViewModel = function() {
this.input_text = ko.observable('');
this.addTodo = function(view_model, event) {
var text;
text = this.create.input_text();
if (!text || event.keyCode !== 13) {
return true;
}
todos.create({
text: text
});
return this.create.input_text('');
};
return this;
};
TodoViewModel = function(model) {
this.text = kb.observable(model, {
key: 'text',
write: (function(text) {
return model.save({
text: text
});
})
}, this);
this.edit_mode = ko.observable(false);
this.toggleEditMode = __bind(function(event) {
if (!this.done()) {
return this.edit_mode(!this.edit_mode());
}
}, this);
this.onEnterEndEdit = __bind(function(event) {
if (event.keyCode === 13) {
return this.edit_mode(false);
}
}, this);
this.done = kb.observable(model, {
key: 'done',
write: (function(done) {
return model.save({
done: done
});
})
}, this);
this.destroyTodo = __bind(function() {
return model.destroy();
}, this);
return this;
};
TodoListViewModel = function(todos) {
this.todos = ko.observableArray([]);
this.collection_observable = kb.collectionObservable(todos, this.todos, {
view_model: TodoViewModel
});
return this;
};
StatsViewModel = function(todos) {
this.collection_observable = kb.collectionObservable(todos);
this.remaining_text = ko.dependentObservable(__bind(function() {
var count;
count = this.collection_observable.collection().remainingCount();
if (!count) {
return '';
}
return "" + count + " " + (count === 1 ? 'item' : 'items') + " remaining.";
}, this));
this.clear_text = ko.dependentObservable(__bind(function() {
var count;
count = this.collection_observable.collection().doneCount();
if (!count) {
return '';
}
return "Clear " + count + " completed " + (count === 1 ? 'item' : 'items') + ".";
}, this));
this.onDestroyDone = __bind(function() {
var model, _i, _len, _ref, _results;
_ref = todos.allDone();
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
model = _ref[_i];
_results.push(model.destroy());
}
return _results;
}, this);
return this;
};
app_view_model = {
create: new CreateTodoViewModel(),
todo_list: new TodoListViewModel(todos),
stats: new StatsViewModel(todos)
};
return ko.applyBindings(app_view_model, $('#todoapp')[0]);
});
\ No newline at end of file
// Backbone.js 0.5.3
// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
// Backbone may be freely distributed under the MIT license.
// For all details and documentation:
// http://documentcloud.github.com/backbone
(function(){
// Initial Setup
// -------------
// Save a reference to the global object.
var root = this;
// Save the previous value of the `Backbone` variable.
var previousBackbone = root.Backbone;
// The top-level namespace. All public Backbone classes and modules will
// be attached to this. Exported for both CommonJS and the browser.
var Backbone;
if (typeof exports !== 'undefined') {
Backbone = exports;
} else {
Backbone = root.Backbone = {};
}
// Current version of the library. Keep in sync with `package.json`.
Backbone.VERSION = '0.5.3';
// Require Underscore, if we're on the server, and it's not already present.
var _ = root._;
if (!_ && (typeof require !== 'undefined')) _ = require('underscore')._;
// For Backbone's purposes, jQuery or Zepto owns the `$` variable.
var $ = root.jQuery || root.Zepto;
// Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
// to its previous owner. Returns a reference to this Backbone object.
Backbone.noConflict = function() {
root.Backbone = previousBackbone;
return this;
};
// Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option will
// fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and set a
// `X-Http-Method-Override` header.
Backbone.emulateHTTP = false;
// Turn on `emulateJSON` to support legacy servers that can't deal with direct
// `application/json` requests ... will encode the body as
// `application/x-www-form-urlencoded` instead and will send the model in a
// form param named `model`.
Backbone.emulateJSON = false;
// Backbone.Events
// -----------------
// A module that can be mixed in to *any object* in order to provide it with
// custom events. You may `bind` or `unbind` a callback function to an event;
// `trigger`-ing an event fires all callbacks in succession.
//
// var object = {};
// _.extend(object, Backbone.Events);
// object.bind('expand', function(){ alert('expanded'); });
// object.trigger('expand');
//
Backbone.Events = {
// Bind an event, specified by a string name, `ev`, to a `callback` function.
// Passing `"all"` will bind the callback to all events fired.
bind : function(ev, callback, context) {
var calls = this._callbacks || (this._callbacks = {});
var list = calls[ev] || (calls[ev] = []);
list.push([callback, context]);
return this;
},
// Remove one or many callbacks. If `callback` is null, removes all
// callbacks for the event. If `ev` is null, removes all bound callbacks
// for all events.
unbind : function(ev, callback) {
var calls;
if (!ev) {
this._callbacks = {};
} else if (calls = this._callbacks) {
if (!callback) {
calls[ev] = [];
} else {
var list = calls[ev];
if (!list) return this;
for (var i = 0, l = list.length; i < l; i++) {
if (list[i] && callback === list[i][0]) {
list[i] = null;
break;
}
}
}
}
return this;
},
// Trigger an event, firing all bound callbacks. Callbacks are passed the
// same arguments as `trigger` is, apart from the event name.
// Listening for `"all"` passes the true event name as the first argument.
trigger : function(eventName) {
var list, calls, ev, callback, args;
var both = 2;
if (!(calls = this._callbacks)) return this;
while (both--) {
ev = both ? eventName : 'all';
if (list = calls[ev]) {
for (var i = 0, l = list.length; i < l; i++) {
if (!(callback = list[i])) {
list.splice(i, 1); i--; l--;
} else {
args = both ? Array.prototype.slice.call(arguments, 1) : arguments;
callback[0].apply(callback[1] || this, args);
}
}
}
}
return this;
}
};
// Backbone.Model
// --------------
// Create a new model, with defined attributes. A client id (`cid`)
// is automatically generated and assigned for you.
Backbone.Model = function(attributes, options) {
var defaults;
attributes || (attributes = {});
if (defaults = this.defaults) {
if (_.isFunction(defaults)) defaults = defaults.call(this);
attributes = _.extend({}, defaults, attributes);
}
this.attributes = {};
this._escapedAttributes = {};
this.cid = _.uniqueId('c');
this.set(attributes, {silent : true});
this._changed = false;
this._previousAttributes = _.clone(this.attributes);
if (options && options.collection) this.collection = options.collection;
this.initialize(attributes, options);
};
// Attach all inheritable methods to the Model prototype.
_.extend(Backbone.Model.prototype, Backbone.Events, {
// A snapshot of the model's previous attributes, taken immediately
// after the last `"change"` event was fired.
_previousAttributes : null,
// Has the item been changed since the last `"change"` event?
_changed : false,
// The default name for the JSON `id` attribute is `"id"`. MongoDB and
// CouchDB users may want to set this to `"_id"`.
idAttribute : 'id',
// Initialize is an empty function by default. Override it with your own
// initialization logic.
initialize : function(){},
// Return a copy of the model's `attributes` object.
toJSON : function() {
return _.clone(this.attributes);
},
// Get the value of an attribute.
get : function(attr) {
return this.attributes[attr];
},
// Get the HTML-escaped value of an attribute.
escape : function(attr) {
var html;
if (html = this._escapedAttributes[attr]) return html;
var val = this.attributes[attr];
return this._escapedAttributes[attr] = escapeHTML(val == null ? '' : '' + val);
},
// Returns `true` if the attribute contains a value that is not null
// or undefined.
has : function(attr) {
return this.attributes[attr] != null;
},
// Set a hash of model attributes on the object, firing `"change"` unless you
// choose to silence it.
set : function(attrs, options) {
// Extract attributes and options.
options || (options = {});
if (!attrs) return this;
if (attrs.attributes) attrs = attrs.attributes;
var now = this.attributes, escaped = this._escapedAttributes;
// Run validation.
if (!options.silent && this.validate && !this._performValidation(attrs, options)) return false;
// Check for changes of `id`.
if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
// We're about to start triggering change events.
var alreadyChanging = this._changing;
this._changing = true;
// Update attributes.
for (var attr in attrs) {
var val = attrs[attr];
if (!_.isEqual(now[attr], val)) {
now[attr] = val;
delete escaped[attr];
this._changed = true;
if (!options.silent) this.trigger('change:' + attr, this, val, options);
}
}
// Fire the `"change"` event, if the model has been changed.
if (!alreadyChanging && !options.silent && this._changed) this.change(options);
this._changing = false;
return this;
},
// Remove an attribute from the model, firing `"change"` unless you choose
// to silence it. `unset` is a noop if the attribute doesn't exist.
unset : function(attr, options) {
if (!(attr in this.attributes)) return this;
options || (options = {});
var value = this.attributes[attr];
// Run validation.
var validObj = {};
validObj[attr] = void 0;
if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;
// Remove the attribute.
delete this.attributes[attr];
delete this._escapedAttributes[attr];
if (attr == this.idAttribute) delete this.id;
this._changed = true;
if (!options.silent) {
this.trigger('change:' + attr, this, void 0, options);
this.change(options);
}
return this;
},
// Clear all attributes on the model, firing `"change"` unless you choose
// to silence it.
clear : function(options) {
options || (options = {});
var attr;
var old = this.attributes;
// Run validation.
var validObj = {};
for (attr in old) validObj[attr] = void 0;
if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;
this.attributes = {};
this._escapedAttributes = {};
this._changed = true;
if (!options.silent) {
for (attr in old) {
this.trigger('change:' + attr, this, void 0, options);
}
this.change(options);
}
return this;
},
// Fetch the model from the server. If the server's representation of the
// model differs from its current attributes, they will be overriden,
// triggering a `"change"` event.
fetch : function(options) {
options || (options = {});
var model = this;
var success = options.success;
options.success = function(resp, status, xhr) {
if (!model.set(model.parse(resp, xhr), options)) return false;
if (success) success(model, resp);
};
options.error = wrapError(options.error, model, options);
return (this.sync || Backbone.sync).call(this, 'read', this, options);
},
// Set a hash of model attributes, and sync the model to the server.
// If the server returns an attributes hash that differs, the model's
// state will be `set` again.
save : function(attrs, options) {
options || (options = {});
if (attrs && !this.set(attrs, options)) return false;
var model = this;
var success = options.success;
options.success = function(resp, status, xhr) {
if (!model.set(model.parse(resp, xhr), options)) return false;
if (success) success(model, resp, xhr);
};
options.error = wrapError(options.error, model, options);
var method = this.isNew() ? 'create' : 'update';
return (this.sync || Backbone.sync).call(this, method, this, options);
},
// Destroy this model on the server if it was already persisted. Upon success, the model is removed
// from its collection, if it has one.
destroy : function(options) {
options || (options = {});
if (this.isNew()) return this.trigger('destroy', this, this.collection, options);
var model = this;
var success = options.success;
options.success = function(resp) {
model.trigger('destroy', model, model.collection, options);
if (success) success(model, resp);
};
options.error = wrapError(options.error, model, options);
return (this.sync || Backbone.sync).call(this, 'delete', this, options);
},
// Default URL for the model's representation on the server -- if you're
// using Backbone's restful methods, override this to change the endpoint
// that will be called.
url : function() {
var base = getUrl(this.collection) || this.urlRoot || urlError();
if (this.isNew()) return base;
return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
},
// **parse** converts a response into the hash of attributes to be `set` on
// the model. The default implementation is just to pass the response along.
parse : function(resp, xhr) {
return resp;
},
// Create a new model with identical attributes to this one.
clone : function() {
return new this.constructor(this);
},
// A model is new if it has never been saved to the server, and lacks an id.
isNew : function() {
return this.id == null;
},
// Call this method to manually fire a `change` event for this model.
// Calling this will cause all objects observing the model to update.
change : function(options) {
this.trigger('change', this, options);
this._previousAttributes = _.clone(this.attributes);
this._changed = false;
},
// Determine if the model has changed since the last `"change"` event.
// If you specify an attribute name, determine if that attribute has changed.
hasChanged : function(attr) {
if (attr) return this._previousAttributes[attr] != this.attributes[attr];
return this._changed;
},
// Return an object containing all the attributes that have changed, or false
// if there are no changed attributes. Useful for determining what parts of a
// view need to be updated and/or what attributes need to be persisted to
// the server.
changedAttributes : function(now) {
now || (now = this.attributes);
var old = this._previousAttributes;
var changed = false;
for (var attr in now) {
if (!_.isEqual(old[attr], now[attr])) {
changed = changed || {};
changed[attr] = now[attr];
}
}
return changed;
},
// Get the previous value of an attribute, recorded at the time the last
// `"change"` event was fired.
previous : function(attr) {
if (!attr || !this._previousAttributes) return null;
return this._previousAttributes[attr];
},
// Get all of the attributes of the model at the time of the previous
// `"change"` event.
previousAttributes : function() {
return _.clone(this._previousAttributes);
},
// Run validation against a set of incoming attributes, returning `true`
// if all is well. If a specific `error` callback has been passed,
// call that instead of firing the general `"error"` event.
_performValidation : function(attrs, options) {
var error = this.validate(attrs);
if (error) {
if (options.error) {
options.error(this, error, options);
} else {
this.trigger('error', this, error, options);
}
return false;
}
return true;
}
});
// Backbone.Collection
// -------------------
// Provides a standard collection class for our sets of models, ordered
// or unordered. If a `comparator` is specified, the Collection will maintain
// its models in sort order, as they're added and removed.
Backbone.Collection = function(models, options) {
options || (options = {});
if (options.comparator) this.comparator = options.comparator;
_.bindAll(this, '_onModelEvent', '_removeReference');
this._reset();
if (models) this.reset(models, {silent: true});
this.initialize.apply(this, arguments);
};
// Define the Collection's inheritable methods.
_.extend(Backbone.Collection.prototype, Backbone.Events, {
// The default model for a collection is just a **Backbone.Model**.
// This should be overridden in most cases.
model : Backbone.Model,
// Initialize is an empty function by default. Override it with your own
// initialization logic.
initialize : function(){},
// The JSON representation of a Collection is an array of the
// models' attributes.
toJSON : function() {
return this.map(function(model){ return model.toJSON(); });
},
// Add a model, or list of models to the set. Pass **silent** to avoid
// firing the `added` event for every new model.
add : function(models, options) {
if (_.isArray(models)) {
for (var i = 0, l = models.length; i < l; i++) {
this._add(models[i], options);
}
} else {
this._add(models, options);
}
return this;
},
// Remove a model, or a list of models from the set. Pass silent to avoid
// firing the `removed` event for every model removed.
remove : function(models, options) {
if (_.isArray(models)) {
for (var i = 0, l = models.length; i < l; i++) {
this._remove(models[i], options);
}
} else {
this._remove(models, options);
}
return this;
},
// Get a model from the set by id.
get : function(id) {
if (id == null) return null;
return this._byId[id.id != null ? id.id : id];
},
// Get a model from the set by client id.
getByCid : function(cid) {
return cid && this._byCid[cid.cid || cid];
},
// Get the model at the given index.
at: function(index) {
return this.models[index];
},
// Force the collection to re-sort itself. You don't need to call this under normal
// circumstances, as the set will maintain sort order as each item is added.
sort : function(options) {
options || (options = {});
if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
this.models = this.sortBy(this.comparator);
if (!options.silent) this.trigger('reset', this, options);
return this;
},
// Pluck an attribute from each model in the collection.
pluck : function(attr) {
return _.map(this.models, function(model){ return model.get(attr); });
},
// When you have more items than you want to add or remove individually,
// you can reset the entire set with a new list of models, without firing
// any `added` or `removed` events. Fires `reset` when finished.
reset : function(models, options) {
models || (models = []);
options || (options = {});
this.each(this._removeReference);
this._reset();
this.add(models, {silent: true});
if (!options.silent) this.trigger('reset', this, options);
return this;
},
// Fetch the default set of models for this collection, resetting the
// collection when they arrive. If `add: true` is passed, appends the
// models to the collection instead of resetting.
fetch : function(options) {
options || (options = {});
var collection = this;
var success = options.success;
options.success = function(resp, status, xhr) {
collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
if (success) success(collection, resp);
};
options.error = wrapError(options.error, collection, options);
return (this.sync || Backbone.sync).call(this, 'read', this, options);
},
// Create a new instance of a model in this collection. After the model
// has been created on the server, it will be added to the collection.
// Returns the model, or 'false' if validation on a new model fails.
create : function(model, options) {
var coll = this;
options || (options = {});
model = this._prepareModel(model, options);
if (!model) return false;
var success = options.success;
options.success = function(nextModel, resp, xhr) {
coll.add(nextModel, options);
if (success) success(nextModel, resp, xhr);
};
model.save(null, options);
return model;
},
// **parse** converts a response into a list of models to be added to the
// collection. The default implementation is just to pass it through.
parse : function(resp, xhr) {
return resp;
},
// Proxy to _'s chain. Can't be proxied the same way the rest of the
// underscore methods are proxied because it relies on the underscore
// constructor.
chain: function () {
return _(this.models).chain();
},
// Reset all internal state. Called when the collection is reset.
_reset : function(options) {
this.length = 0;
this.models = [];
this._byId = {};
this._byCid = {};
},
// Prepare a model to be added to this collection
_prepareModel: function(model, options) {
if (!(model instanceof Backbone.Model)) {
var attrs = model;
model = new this.model(attrs, {collection: this});
if (model.validate && !model._performValidation(attrs, options)) model = false;
} else if (!model.collection) {
model.collection = this;
}
return model;
},
// Internal implementation of adding a single model to the set, updating
// hash indexes for `id` and `cid` lookups.
// Returns the model, or 'false' if validation on a new model fails.
_add : function(model, options) {
options || (options = {});
model = this._prepareModel(model, options);
if (!model) return false;
var already = this.getByCid(model);
if (already) throw new Error(["Can't add the same model to a set twice", already.id]);
this._byId[model.id] = model;
this._byCid[model.cid] = model;
var index = options.at != null ? options.at :
this.comparator ? this.sortedIndex(model, this.comparator) :
this.length;
this.models.splice(index, 0, model);
model.bind('all', this._onModelEvent);
this.length++;
if (!options.silent) model.trigger('add', model, this, options);
return model;
},
// Internal implementation of removing a single model from the set, updating
// hash indexes for `id` and `cid` lookups.
_remove : function(model, options) {
options || (options = {});
model = this.getByCid(model) || this.get(model);
if (!model) return null;
delete this._byId[model.id];
delete this._byCid[model.cid];
this.models.splice(this.indexOf(model), 1);
this.length--;
if (!options.silent) model.trigger('remove', model, this, options);
this._removeReference(model);
return model;
},
// Internal method to remove a model's ties to a collection.
_removeReference : function(model) {
if (this == model.collection) {
delete model.collection;
}
model.unbind('all', this._onModelEvent);
},
// Internal method called every time a model in the set fires an event.
// Sets need to update their indexes when models change ids. All other
// events simply proxy through. "add" and "remove" events that originate
// in other collections are ignored.
_onModelEvent : function(ev, model, collection, options) {
if ((ev == 'add' || ev == 'remove') && collection != this) return;
if (ev == 'destroy') {
this._remove(model, options);
}
if (model && ev === 'change:' + model.idAttribute) {
delete this._byId[model.previous(model.idAttribute)];
this._byId[model.id] = model;
}
this.trigger.apply(this, arguments);
}
});
// Underscore methods that we want to implement on the Collection.
var methods = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find', 'detect',
'filter', 'select', 'reject', 'every', 'all', 'some', 'any', 'include',
'contains', 'invoke', 'max', 'min', 'sortBy', 'sortedIndex', 'toArray', 'size',
'first', 'rest', 'last', 'without', 'indexOf', 'lastIndexOf', 'isEmpty', 'groupBy'];
// Mix in each Underscore method as a proxy to `Collection#models`.
_.each(methods, function(method) {
Backbone.Collection.prototype[method] = function() {
return _[method].apply(_, [this.models].concat(_.toArray(arguments)));
};
});
// Backbone.Router
// -------------------
// Routers map faux-URLs to actions, and fire events when routes are
// matched. Creating a new one sets its `routes` hash, if not set statically.
Backbone.Router = function(options) {
options || (options = {});
if (options.routes) this.routes = options.routes;
this._bindRoutes();
this.initialize.apply(this, arguments);
};
// Cached regular expressions for matching named param parts and splatted
// parts of route strings.
var namedParam = /:([\w\d]+)/g;
var splatParam = /\*([\w\d]+)/g;
var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g;
// Set up all inheritable **Backbone.Router** properties and methods.
_.extend(Backbone.Router.prototype, Backbone.Events, {
// Initialize is an empty function by default. Override it with your own
// initialization logic.
initialize : function(){},
// Manually bind a single named route to a callback. For example:
//
// this.route('search/:query/p:num', 'search', function(query, num) {
// ...
// });
//
route : function(route, name, callback) {
Backbone.history || (Backbone.history = new Backbone.History);
if (!_.isRegExp(route)) route = this._routeToRegExp(route);
Backbone.history.route(route, _.bind(function(fragment) {
var args = this._extractParameters(route, fragment);
callback.apply(this, args);
this.trigger.apply(this, ['route:' + name].concat(args));
}, this));
},
// Simple proxy to `Backbone.history` to save a fragment into the history.
navigate : function(fragment, triggerRoute) {
Backbone.history.navigate(fragment, triggerRoute);
},
// Bind all defined routes to `Backbone.history`. We have to reverse the
// order of the routes here to support behavior where the most general
// routes can be defined at the bottom of the route map.
_bindRoutes : function() {
if (!this.routes) return;
var routes = [];
for (var route in this.routes) {
routes.unshift([route, this.routes[route]]);
}
for (var i = 0, l = routes.length; i < l; i++) {
this.route(routes[i][0], routes[i][1], this[routes[i][1]]);
}
},
// Convert a route string into a regular expression, suitable for matching
// against the current location hash.
_routeToRegExp : function(route) {
route = route.replace(escapeRegExp, "\\$&")
.replace(namedParam, "([^\/]*)")
.replace(splatParam, "(.*?)");
return new RegExp('^' + route + '$');
},
// Given a route, and a URL fragment that it matches, return the array of
// extracted parameters.
_extractParameters : function(route, fragment) {
return route.exec(fragment).slice(1);
}
});
// Backbone.History
// ----------------
// Handles cross-browser history management, based on URL fragments. If the
// browser does not support `onhashchange`, falls back to polling.
Backbone.History = function() {
this.handlers = [];
_.bindAll(this, 'checkUrl');
};
// Cached regex for cleaning hashes.
var hashStrip = /^#*/;
// Cached regex for detecting MSIE.
var isExplorer = /msie [\w.]+/;
// Has the history handling already been started?
var historyStarted = false;
// Set up all inheritable **Backbone.History** properties and methods.
_.extend(Backbone.History.prototype, {
// The default interval to poll for hash changes, if necessary, is
// twenty times a second.
interval: 50,
// Get the cross-browser normalized URL fragment, either from the URL,
// the hash, or the override.
getFragment : function(fragment, forcePushState) {
if (fragment == null) {
if (this._hasPushState || forcePushState) {
fragment = window.location.pathname;
var search = window.location.search;
if (search) fragment += search;
if (fragment.indexOf(this.options.root) == 0) fragment = fragment.substr(this.options.root.length);
} else {
fragment = window.location.hash;
}
}
return decodeURIComponent(fragment.replace(hashStrip, ''));
},
// Start the hash change handling, returning `true` if the current URL matches
// an existing route, and `false` otherwise.
start : function(options) {
// Figure out the initial configuration. Do we need an iframe?
// Is pushState desired ... is it available?
if (historyStarted) throw new Error("Backbone.history has already been started");
this.options = _.extend({}, {root: '/'}, this.options, options);
this._wantsPushState = !!this.options.pushState;
this._hasPushState = !!(this.options.pushState && window.history && window.history.pushState);
var fragment = this.getFragment();
var docMode = document.documentMode;
var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
if (oldIE) {
this.iframe = $('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
this.navigate(fragment);
}
// Depending on whether we're using pushState or hashes, and whether
// 'onhashchange' is supported, determine how we check the URL state.
if (this._hasPushState) {
$(window).bind('popstate', this.checkUrl);
} else if ('onhashchange' in window && !oldIE) {
$(window).bind('hashchange', this.checkUrl);
} else {
setInterval(this.checkUrl, this.interval);
}
// Determine if we need to change the base url, for a pushState link
// opened by a non-pushState browser.
this.fragment = fragment;
historyStarted = true;
var loc = window.location;
var atRoot = loc.pathname == this.options.root;
if (this._wantsPushState && !this._hasPushState && !atRoot) {
this.fragment = this.getFragment(null, true);
window.location.replace(this.options.root + '#' + this.fragment);
// Return immediately as browser will do redirect to new url
return true;
} else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
this.fragment = loc.hash.replace(hashStrip, '');
window.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment);
}
if (!this.options.silent) {
return this.loadUrl();
}
},
// Add a route to be tested when the fragment changes. Routes added later may
// override previous routes.
route : function(route, callback) {
this.handlers.unshift({route : route, callback : callback});
},
// Checks the current URL to see if it has changed, and if it has,
// calls `loadUrl`, normalizing across the hidden iframe.
checkUrl : function(e) {
var current = this.getFragment();
if (current == this.fragment && this.iframe) current = this.getFragment(this.iframe.location.hash);
if (current == this.fragment || current == decodeURIComponent(this.fragment)) return false;
if (this.iframe) this.navigate(current);
this.loadUrl() || this.loadUrl(window.location.hash);
},
// Attempt to load the current URL fragment. If a route succeeds with a
// match, returns `true`. If no defined routes matches the fragment,
// returns `false`.
loadUrl : function(fragmentOverride) {
var fragment = this.fragment = this.getFragment(fragmentOverride);
var matched = _.any(this.handlers, function(handler) {
if (handler.route.test(fragment)) {
handler.callback(fragment);
return true;
}
});
return matched;
},
// Save a fragment into the hash history. You are responsible for properly
// URL-encoding the fragment in advance. This does not trigger
// a `hashchange` event.
navigate : function(fragment, triggerRoute) {
var frag = (fragment || '').replace(hashStrip, '');
if (this.fragment == frag || this.fragment == decodeURIComponent(frag)) return;
if (this._hasPushState) {
var loc = window.location;
if (frag.indexOf(this.options.root) != 0) frag = this.options.root + frag;
this.fragment = frag;
window.history.pushState({}, document.title, loc.protocol + '//' + loc.host + frag);
} else {
window.location.hash = this.fragment = frag;
if (this.iframe && (frag != this.getFragment(this.iframe.location.hash))) {
this.iframe.document.open().close();
this.iframe.location.hash = frag;
}
}
if (triggerRoute) this.loadUrl(fragment);
}
});
// Backbone.View
// -------------
// Creating a Backbone.View creates its initial element outside of the DOM,
// if an existing element is not provided...
Backbone.View = function(options) {
this.cid = _.uniqueId('view');
this._configure(options || {});
this._ensureElement();
this.delegateEvents();
this.initialize.apply(this, arguments);
};
// Element lookup, scoped to DOM elements within the current view.
// This should be prefered to global lookups, if you're dealing with
// a specific view.
var selectorDelegate = function(selector) {
return $(selector, this.el);
};
// Cached regex to split keys for `delegate`.
var eventSplitter = /^(\S+)\s*(.*)$/;
// List of view options to be merged as properties.
var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName'];
// Set up all inheritable **Backbone.View** properties and methods.
_.extend(Backbone.View.prototype, Backbone.Events, {
// The default `tagName` of a View's element is `"div"`.
tagName : 'div',
// Attach the `selectorDelegate` function as the `$` property.
$ : selectorDelegate,
// Initialize is an empty function by default. Override it with your own
// initialization logic.
initialize : function(){},
// **render** is the core function that your view should override, in order
// to populate its element (`this.el`), with the appropriate HTML. The
// convention is for **render** to always return `this`.
render : function() {
return this;
},
// Remove this view from the DOM. Note that the view isn't present in the
// DOM by default, so calling this method may be a no-op.
remove : function() {
$(this.el).remove();
return this;
},
// For small amounts of DOM Elements, where a full-blown template isn't
// needed, use **make** to manufacture elements, one at a time.
//
// var el = this.make('li', {'class': 'row'}, this.model.escape('title'));
//
make : function(tagName, attributes, content) {
var el = document.createElement(tagName);
if (attributes) $(el).attr(attributes);
if (content) $(el).html(content);
return el;
},
// Set callbacks, where `this.callbacks` is a hash of
//
// *{"event selector": "callback"}*
//
// {
// 'mousedown .title': 'edit',
// 'click .button': 'save'
// }
//
// pairs. Callbacks will be bound to the view, with `this` set properly.
// Uses event delegation for efficiency.
// Omitting the selector binds the event to `this.el`.
// This only works for delegate-able events: not `focus`, `blur`, and
// not `change`, `submit`, and `reset` in Internet Explorer.
delegateEvents : function(events) {
if (!(events || (events = this.events))) return;
if (_.isFunction(events)) events = events.call(this);
$(this.el).unbind('.delegateEvents' + this.cid);
for (var key in events) {
var method = this[events[key]];
if (!method) throw new Error('Event "' + events[key] + '" does not exist');
var match = key.match(eventSplitter);
var eventName = match[1], selector = match[2];
method = _.bind(method, this);
eventName += '.delegateEvents' + this.cid;
if (selector === '') {
$(this.el).bind(eventName, method);
} else {
$(this.el).delegate(selector, eventName, method);
}
}
},
// Performs the initial configuration of a View with a set of options.
// Keys with special meaning *(model, collection, id, className)*, are
// attached directly to the view.
_configure : function(options) {
if (this.options) options = _.extend({}, this.options, options);
for (var i = 0, l = viewOptions.length; i < l; i++) {
var attr = viewOptions[i];
if (options[attr]) this[attr] = options[attr];
}
this.options = options;
},
// Ensure that the View has a DOM element to render into.
// If `this.el` is a string, pass it through `$()`, take the first
// matching element, and re-assign it to `el`. Otherwise, create
// an element from the `id`, `className` and `tagName` proeprties.
_ensureElement : function() {
if (!this.el) {
var attrs = this.attributes || {};
if (this.id) attrs.id = this.id;
if (this.className) attrs['class'] = this.className;
this.el = this.make(this.tagName, attrs);
} else if (_.isString(this.el)) {
this.el = $(this.el).get(0);
}
}
});
// The self-propagating extend function that Backbone classes use.
var extend = function (protoProps, classProps) {
var child = inherits(this, protoProps, classProps);
child.extend = this.extend;
return child;
};
// Set up inheritance for the model, collection, and view.
Backbone.Model.extend = Backbone.Collection.extend =
Backbone.Router.extend = Backbone.View.extend = extend;
// Map from CRUD to HTTP for our default `Backbone.sync` implementation.
var methodMap = {
'create': 'POST',
'update': 'PUT',
'delete': 'DELETE',
'read' : 'GET'
};
// Backbone.sync
// -------------
// Override this function to change the manner in which Backbone persists
// models to the server. You will be passed the type of request, and the
// model in question. By default, uses makes a RESTful Ajax request
// to the model's `url()`. Some possible customizations could be:
//
// * Use `setTimeout` to batch rapid-fire updates into a single request.
// * Send up the models as XML instead of JSON.
// * Persist models via WebSockets instead of Ajax.
//
// Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
// as `POST`, with a `_method` parameter containing the true HTTP method,
// as well as all requests with the body as `application/x-www-form-urlencoded` instead of
// `application/json` with the model in a param named `model`.
// Useful when interfacing with server-side languages like **PHP** that make
// it difficult to read the body of `PUT` requests.
Backbone.sync = function(method, model, options) {
var type = methodMap[method];
// Default JSON-request options.
var params = _.extend({
type: type,
dataType: 'json'
}, options);
// Ensure that we have a URL.
if (!params.url) {
params.url = getUrl(model) || urlError();
}
// Ensure that we have the appropriate request data.
if (!params.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
params.data = JSON.stringify(model.toJSON());
}
// For older servers, emulate JSON by encoding the request into an HTML-form.
if (Backbone.emulateJSON) {
params.contentType = 'application/x-www-form-urlencoded';
params.data = params.data ? {model : params.data} : {};
}
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
// And an `X-HTTP-Method-Override` header.
if (Backbone.emulateHTTP) {
if (type === 'PUT' || type === 'DELETE') {
if (Backbone.emulateJSON) params.data._method = type;
params.type = 'POST';
params.beforeSend = function(xhr) {
xhr.setRequestHeader('X-HTTP-Method-Override', type);
};
}
}
// Don't process data on a non-GET request.
if (params.type !== 'GET' && !Backbone.emulateJSON) {
params.processData = false;
}
// Make the request.
return $.ajax(params);
};
// Helpers
// -------
// Shared empty constructor function to aid in prototype-chain creation.
var ctor = function(){};
// Helper function to correctly set up the prototype chain, for subclasses.
// Similar to `goog.inherits`, but uses a hash of prototype properties and
// class properties to be extended.
var inherits = function(parent, protoProps, staticProps) {
var child;
// The constructor function for the new subclass is either defined by you
// (the "constructor" property in your `extend` definition), or defaulted
// by us to simply call `super()`.
if (protoProps && protoProps.hasOwnProperty('constructor')) {
child = protoProps.constructor;
} else {
child = function(){ return parent.apply(this, arguments); };
}
// Inherit class (static) properties from parent.
_.extend(child, parent);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function.
ctor.prototype = parent.prototype;
child.prototype = new ctor();
// Add prototype properties (instance properties) to the subclass,
// if supplied.
if (protoProps) _.extend(child.prototype, protoProps);
// Add static properties to the constructor function, if supplied.
if (staticProps) _.extend(child, staticProps);
// Correctly set child's `prototype.constructor`.
child.prototype.constructor = child;
// Set a convenience property in case the parent's prototype is needed later.
child.__super__ = parent.prototype;
return child;
};
// Helper function to get a URL from a Model or Collection as a property
// or as a function.
var getUrl = function(object) {
if (!(object && object.url)) return null;
return _.isFunction(object.url) ? object.url() : object.url;
};
// Throw an error when a URL is needed, and none is supplied.
var urlError = function() {
throw new Error('A "url" property or function must be specified');
};
// Wrap an optional error callback with a fallback error event.
var wrapError = function(onError, model, options) {
return function(resp) {
if (onError) {
onError(model, resp, options);
} else {
model.trigger('error', model, resp, options);
}
};
};
// Helper function to escape a string for HTML rendering.
var escapeHTML = function(string) {
return string.replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
};
}).call(this);
/*
knockback.js 0.12.0
(c) 2011 Kevin Malakoff.
Knockback.js is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
Dependencies: Knockout.js, Backbone.js, and Underscore.js.
Optional dependency: Backbone.ModelRef.js.
*/if (!this.ko) {
throw new Error('Knockback: Dependency alert! Knockout.js must be included before this file');
}
if (!this.Backbone) {
throw new Error('Knockback: Dependency alert! Backbone.js must be included before this file');
}
if (!this._ || !this._.VERSION) {
throw new Error('Knockback: Dependency alert! Underscore.js must be included before this file');
}
this.Knockback || (this.Knockback = {});
this.kb || (this.kb = this.Knockback);
Knockback.VERSION = '0.12.0';
Knockback.locale_manager;
Knockback.wrappedObservable = function(instance) {
if (!instance._kb_observable) {
throw new Error('Knockback: _kb_observable missing from your instance');
}
return instance._kb_observable;
};
Knockback.setToDefault = function(observable) {
if (observable && observable.setToDefault) {
return observable.setToDefault();
}
};
Knockback.vmSetToDefault = function(view_model) {
var key, observable, _results;
_results = [];
for (key in view_model) {
observable = view_model[key];
_results.push(kb.setToDefault(observable));
}
return _results;
};
Knockback.vmRelease = function(view_model) {
if (view_model instanceof kb.ViewModel_RCBase) {
view_model.release();
return;
}
return Knockback.vmReleaseObservables(view_model);
};
Knockback.vmReleaseObservables = function(view_model, keys) {
var key, value, _results;
_results = [];
for (key in view_model) {
value = view_model[key];
if (!value) {
continue;
}
if (!(ko.isObservable(value) || (value instanceof kb.Observables) || (value instanceof kb.ViewModel_RCBase))) {
continue;
}
if (keys && !_.contains(keys, key)) {
continue;
}
view_model[key] = null;
_results.push(kb.vmReleaseObservable(value));
}
return _results;
};
Knockback.vmReleaseObservable = function(observable) {
if (!(ko.isObservable(observable) || (observable instanceof kb.Observables) || (observable instanceof kb.ViewModel_RCBase))) {
return;
}
if (observable.destroy) {
return observable.destroy();
} else if (observable.dispose) {
return observable.dispose();
} else if (observable.release) {
return observable.release();
}
};
/*
knockback_collection_observable.js
(c) 2011 Kevin Malakoff.
Knockback.CollectionObservable is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
return child;
};
if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.CollectionObservable = (function() {
function CollectionObservable(collection, vm_observable_array, options) {
var defer, event, _i, _j, _len, _len2, _ref, _ref2;
this.vm_observable_array = vm_observable_array;
if (options == null) {
options = {};
}
if (!collection) {
throw new Error('CollectionObservable: collection is missing');
}
if (options.hasOwnProperty('view_model')) {
options.view_model_constructor = options['view_model'];
delete options['view_model'];
}
if (this.vm_observable_array || options.view_model_create || options.view_model_constructor) {
if (!this.vm_observable_array) {
throw new Error('CollectionObservable: vm_observable_array is missing');
}
}
if (options.hasOwnProperty('defer')) {
defer = options.defer;
delete options['defer'];
}
this.options = _.clone(options);
_.bindAll(this, 'destroy', 'collection', 'sortedIndex', 'sortAttribute', 'viewModelByModel', 'eachViewModel', 'bind', 'unbind', 'trigger');
_.bindAll(this, '_onGetValue', '_onCollectionReset', '_onCollectionResort', '_onModelAdd', '_onModelRemove', '_onModelChanged');
this._kb_collection = collection;
if (this._kb_collection.retain) {
this._kb_collection.retain();
}
this._kb_collection.bind('reset', this._onCollectionReset);
if (!this.options.sorted_index) {
this._kb_collection.bind('resort', this._onCollectionResort);
}
_ref = ['new', 'add'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
event = _ref[_i];
this._kb_collection.bind(event, this._onModelAdd);
}
_ref2 = ['remove', 'destroy'];
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
event = _ref2[_j];
this._kb_collection.bind(event, this._onModelRemove);
}
this._kb_collection.bind('change', this._onModelChanged);
this._kb_value_observable = ko.observableArray([]);
this._kb_observable = ko.dependentObservable(this._onGetValue);
this._kb_observable.destroy = this.destroy;
this._kb_observable.collection = this.collection;
this._kb_observable.viewModelByModel = this.viewModelByModel;
this._kb_observable.eachViewModel = this.eachViewModel;
this._kb_observable.sortedIndex = this.sortedIndex;
this._kb_observable.sortAttribute = this.sortAttribute;
this._kb_observable.bind = this.bind;
this._kb_observable.unbind = this.unbind;
this._kb_observable.trigger = this.trigger;
this.sortedIndex(this.options.sorted_index, this.options.sort_attribute, {
silent: true,
defer: defer
});
return kb.wrappedObservable(this);
}
CollectionObservable.prototype.destroy = function() {
var event, _i, _j, _len, _len2, _ref, _ref2;
this._clearViewModels();
this._kb_collection.unbind('reset', this._onCollectionReset);
if (!this.options.sorted_index) {
this._kb_collection.unbind('resort', this._onCollectionResort);
}
_ref = ['new', 'add'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
event = _ref[_i];
this._kb_collection.unbind(event, this._onModelAdd);
}
_ref2 = ['remove', 'destroy'];
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
event = _ref2[_j];
this._kb_collection.unbind(event, this._onModelRemove);
}
this._kb_collection.unbind('change', this._onModelChanged);
if (this._kb_collection.release) {
this._kb_collection.release();
}
this._kb_collection = null;
this._kb_value_observable = null;
this._kb_observable.dispose();
this._kb_observable = null;
return this.options = null;
};
CollectionObservable.prototype.collection = function() {
this._kb_value_observable();
return this._kb_collection;
};
CollectionObservable.prototype.sortedIndex = function(sorted_index, sort_attribute, options) {
var _resync;
if (options == null) {
options = {};
}
if (sorted_index) {
this.options.sorted_index = sorted_index;
this.options.sort_attribute = sort_attribute;
} else if (sort_attribute) {
this.options.sort_attribute = sort_attribute;
this.options.sorted_index = this._sortAttributeFn(sort_attribute);
} else {
this.options.sort_attribute = null;
this.options.sorted_index = null;
}
_resync = __bind(function() {
if ((this._kb_collection.models.length === 0) && (this._kb_value_observable().length === 0)) {
return;
}
this._collectionResync(true);
if (!options.silent) {
return this.trigger('resort', this.vm_observable_array());
}
}, this);
if (options.defer) {
_.defer(_resync);
} else {
_resync();
}
return this;
};
CollectionObservable.prototype.sortAttribute = function(sort_attribute, sorted_index, silent) {
return this.sortedIndex(sorted_index, sort_attribute, silent);
};
CollectionObservable.prototype._sortAttributeFn = function(sort_attribute) {
return function(models, model) {
return _.sortedIndex(models, model, function(test) {
return test.get(sort_attribute);
});
};
};
CollectionObservable.prototype.viewModelByModel = function(model) {
var id_attribute;
if (!this.vm_observable_array) {
throw new Error("CollectionObservable: cannot get a view model if vm_observable_array was not supplied");
}
id_attribute = model.hasOwnProperty(model.idAttribute) ? model.idAttribute : 'cid';
return _.find(this.vm_observable_array(), function(test) {
return test.__kb_model[id_attribute] === model[id_attribute];
});
};
CollectionObservable.prototype.eachViewModel = function(iterator) {
var view_model, _i, _len, _ref, _results;
_ref = this.vm_observable_array();
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
view_model = _ref[_i];
_results.push(iterator(view_model));
}
return _results;
};
CollectionObservable.prototype._onGetValue = function() {
return this._kb_value_observable();
};
CollectionObservable.prototype._onCollectionReset = function() {
return this._collectionResync();
};
CollectionObservable.prototype._onCollectionResort = function(model_or_models) {
if (this.options.sorted_index) {
throw new Error("CollectionObservable: collection sorted_index unexpected");
}
if (_.isArray(model_or_models)) {
this._collectionResync(true);
return this.trigger('resort', this.vm_observable_array());
} else {
return this._onModelResort(model_or_models);
}
};
CollectionObservable.prototype._onModelAdd = function(model) {
var add_index, sorted_models, view_model;
if (this.options.sorted_index) {
sorted_models = _.pluck(this.vm_observable_array(), '__kb_model');
add_index = this.options.sorted_index(sorted_models, model);
} else {
add_index = this._kb_collection.indexOf(model);
}
if (this.vm_observable_array) {
view_model = this._viewModelCreate(model);
this.vm_observable_array.splice(add_index, 0, view_model);
}
this._kb_value_observable.splice(add_index, 0, model);
if (this.vm_observable_array) {
return this.trigger('add', view_model, this.vm_observable_array());
}
};
CollectionObservable.prototype._onModelRemove = function(model) {
var view_model;
this._kb_value_observable.remove(model);
if (this.vm_observable_array) {
view_model = this.viewModelByModel(model);
if (!view_model) {
return;
}
this.vm_observable_array.remove(view_model);
this.trigger('remove', view_model, this.vm_observable_array());
kb.vmRelease(view_model);
return view_model.__kb_model = null;
}
};
CollectionObservable.prototype._onModelChanged = function(model) {
if (this.options.sorted_index && (!this.options.sort_attribute || model.hasChanged(this.options.sort_attribute))) {
this._onModelResort(model);
}
return this._kb_value_observable.valueHasMutated();
};
CollectionObservable.prototype._onModelResort = function(model) {
var new_index, previous_index, sorted_models, view_model;
previous_index = this._kb_value_observable.indexOf(model);
if (this.options.sorted_index) {
sorted_models = _.clone(this._kb_value_observable());
sorted_models.splice(previous_index, 1);
new_index = this.options.sorted_index(sorted_models, model);
} else {
new_index = this._kb_collection.indexOf(model);
}
if (previous_index === new_index) {
return;
}
if (this.vm_observable_array) {
view_model = this.viewModelByModel(model);
this.vm_observable_array.splice(previous_index, 1);
this.vm_observable_array.splice(new_index, 0, view_model);
}
this._kb_value_observable.splice(previous_index, 1);
this._kb_value_observable.splice(new_index, 0, model);
if (this.vm_observable_array) {
return this.trigger('resort', view_model, this.vm_observable_array(), new_index);
}
};
CollectionObservable.prototype._clearViewModels = function(silent) {
var view_model, view_models, _i, _len, _results;
if (this.vm_observable_array) {
if (!silent) {
this.trigger('remove', this.vm_observable_array());
}
view_models = this.vm_observable_array.removeAll();
_results = [];
for (_i = 0, _len = view_models.length; _i < _len; _i++) {
view_model = view_models[_i];
_results.push(kb.vmRelease(view_model));
}
return _results;
}
};
CollectionObservable.prototype._collectionResync = function(silent) {
var add_index, model, models, view_models, _i, _j, _len, _len2, _ref;
this._clearViewModels(silent);
this._kb_value_observable.removeAll();
if (this.options.sorted_index) {
models = [];
_ref = this._kb_collection.models;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
model = _ref[_i];
add_index = this.options.sorted_index(models, model);
models.splice(add_index, 0, model);
}
} else {
models = _.clone(this._kb_collection.models);
}
if (this.vm_observable_array) {
view_models = [];
for (_j = 0, _len2 = models.length; _j < _len2; _j++) {
model = models[_j];
view_models.push(this._viewModelCreate(model));
}
this.vm_observable_array(view_models);
}
this._kb_value_observable(models);
if (this.vm_observable_array) {
if (!silent) {
return this.trigger('add', this.vm_observable_array());
}
}
};
CollectionObservable.prototype._viewModelCreate = function(model) {
var view_model;
if (this.options.view_model_create) {
view_model = this.options.view_model_create(model);
} else if (this.options.view_model_constructor) {
view_model = new this.options.view_model_constructor(model);
} else {
view_model = kb.viewModel(model);
}
view_model.__kb_model = model;
return view_model;
};
return CollectionObservable;
})();
__extends(Knockback.CollectionObservable.prototype, Backbone.Events);
Knockback.collectionObservable = function(collection, vm_observable_array, options) {
return new Knockback.CollectionObservable(collection, vm_observable_array, options);
};
Knockback.viewModelGetModel = Knockback.vmModel = function(view_model) {
return view_model.__kb_model;
};
Knockback.sortedIndexWrapAttr = Knockback.siwa = function(attribute_name, wrapper_constructor) {
return function(models, model) {
return _.sortedIndex(models, model, function(test) {
return new wrapper_constructor(test.get(attribute_name));
});
};
};
/*
knockback_default_wrapper.js
(c) 2011 Kevin Malakoff.
Knockback.DefaultWrapper is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.DefaultWrapper = (function() {
function DefaultWrapper(observable, default_value) {
this.default_value = default_value;
_.bindAll(this, 'destroy', 'setToDefault');
this._kb_observable = ko.dependentObservable({
read: __bind(function() {
var value;
value = ko.utils.unwrapObservable(observable());
if (!value) {
return ko.utils.unwrapObservable(this.default_value);
} else {
return value;
}
}, this),
write: function(value) {
return observable(value);
},
owner: {}
});
this._kb_observable.destroy = this.destroy;
this._kb_observable.setToDefault = this.setToDefault;
return kb.wrappedObservable(this);
}
DefaultWrapper.prototype.destroy = function() {
this._kb_observable = null;
return this.default_value = null;
};
DefaultWrapper.prototype.setToDefault = function() {
return this._kb_observable(this.default_value);
};
return DefaultWrapper;
})();
Knockback.defaultWrapper = function(observable, default_value) {
return new Knockback.DefaultWrapper(observable, default_value);
};
/*
knockback_formatted_observable.js
(c) 2011 Kevin Malakoff.
Knockback.FormattedObservable is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.toFormattedString = function(format) {
var arg, args, index, parameter_index, result, value;
result = format.slice();
args = Array.prototype.slice.call(arguments, 1);
for (index in args) {
arg = args[index];
value = ko.utils.unwrapObservable(arg);
if (!value) {
value = '';
}
parameter_index = format.indexOf("\{" + index + "\}");
while (parameter_index >= 0) {
result = result.replace("{" + index + "}", value);
parameter_index = format.indexOf("\{" + index + "\}", parameter_index + 1);
}
}
return result;
};
Knockback.parseFormattedString = function(string, format) {
var count, format_indices_to_matched_indices, index, match_index, matches, parameter_count, parameter_index, positions, regex, regex_string, results, sorted_positions, _i, _results;
regex_string = format.slice();
index = 0;
parameter_count = 0;
positions = {};
while (regex_string.search("\\{" + index + "\\}") >= 0) {
parameter_index = format.indexOf("\{" + index + "\}");
while (parameter_index >= 0) {
regex_string = regex_string.replace("\{" + index + "\}", '(.*)');
positions[parameter_index] = index;
parameter_count++;
parameter_index = format.indexOf("\{" + index + "\}", parameter_index + 1);
}
index++;
}
count = index;
regex = new RegExp(regex_string);
matches = regex.exec(string);
if (matches) {
matches.shift();
}
if (!matches || (matches.length !== parameter_count)) {
return _.map((function() {
_results = [];
for (var _i = 1; 1 <= count ? _i <= count : _i >= count; 1 <= count ? _i++ : _i--){ _results.push(_i); }
return _results;
}).apply(this), function() {
return '';
});
}
sorted_positions = _.sortBy(_.keys(positions), function(parameter_index, format_index) {
return parseInt(parameter_index, 10);
});
format_indices_to_matched_indices = {};
for (match_index in sorted_positions) {
parameter_index = sorted_positions[match_index];
index = positions[parameter_index];
if (format_indices_to_matched_indices.hasOwnProperty(index)) {
continue;
}
format_indices_to_matched_indices[index] = match_index;
}
results = [];
index = 0;
while (index < count) {
results.push(matches[format_indices_to_matched_indices[index]]);
index++;
}
return results;
};
Knockback.formattedObservable = function(format, args) {
var observable_args, result;
observable_args = Array.prototype.slice.call(arguments, 1);
result = ko.dependentObservable({
read: function() {
var arg, _i, _len;
args = [ko.utils.unwrapObservable(format)];
for (_i = 0, _len = observable_args.length; _i < _len; _i++) {
arg = observable_args[_i];
args.push(ko.utils.unwrapObservable(arg));
}
return kb.toFormattedString.apply(null, args);
},
write: function(value) {
var index, matches, max_count, _results;
matches = kb.parseFormattedString(value, ko.utils.unwrapObservable(format));
max_count = Math.min(observable_args.length, matches.length);
index = 0;
_results = [];
while (index < max_count) {
observable_args[index](matches[index]);
_results.push(index++);
}
return _results;
},
owner: {}
});
return result;
};
/*
knockback_localized_observable.js
(c) 2011 Kevin Malakoff.
Knockback.LocalizedObservable is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.LocalizedObservable = (function() {
function LocalizedObservable(value, options, view_model) {
this.value = value;
this.options = options != null ? options : {};
this.view_model = view_model;
if (!(this.options.read || this.read)) {
throw new Error('LocalizedObservable: options.read is missing');
}
if (this.options.read && this.read) {
throw new Error('LocalizedObservable: options.read and read class function exist. You need to choose one.');
}
if (this.options.write && this.write) {
throw new Error('LocalizedObservable: options.write and write class function exist. You need to choose one.');
}
if (!kb.locale_manager) {
throw new Error('LocalizedObservable: Knockback.locale_manager is not defined');
}
_.bindAll(this, 'destroy', 'setToDefault', 'resetToCurrent', 'observedValue', '_onGetValue', '_onSetValue', '_onLocaleChange');
this._kb_read = this.options.read ? this.options.read : this.read;
this._kb_write = this.options.write ? this.options.write : this.write;
this._kb_default = this.options["default"] ? this.options["default"] : this["default"];
if (this.value) {
value = ko.utils.unwrapObservable(this.value);
}
this._kb_value_observable = ko.observable(!value ? this._getDefaultValue() : this._kb_read.call(this, value, null));
if (this._kb_write) {
if (!this.view_model) {
this.view_model = {};
}
if (!_.isFunction(this._kb_write)) {
throw new Error('LocalizedObservable: options.write is not a function for read_write model attribute');
}
this._kb_observable = ko.dependentObservable({
read: this._onGetValue,
write: this._onSetValue,
owner: this.view_model
});
} else {
this._kb_observable = ko.dependentObservable(this._onGetValue);
}
this._kb_observable.destroy = this.destroy;
this._kb_observable.observedValue = this.observedValue;
this._kb_observable.setToDefault = this.setToDefault;
this._kb_observable.resetToCurrent = this.resetToCurrent;
kb.locale_manager.bind('change', this._onLocaleChange);
return kb.wrappedObservable(this);
}
LocalizedObservable.prototype.destroy = function() {
kb.locale_manager.unbind('change', this._onLocaleChange);
this._kb_value_observable = null;
this._kb_observable.dispose();
this._kb_observable = null;
this.options = {};
return this.view_model = null;
};
LocalizedObservable.prototype.setToDefault = function() {
var current_value, default_value;
if (!this._kb_default) {
return;
}
default_value = this._getDefaultValue();
current_value = this._kb_value_observable();
if (current_value !== default_value) {
return this._onSetValue(default_value);
} else {
return this._kb_value_observable.valueHasMutated();
}
};
LocalizedObservable.prototype.resetToCurrent = function() {
this._kb_value_observable(null);
return this._onSetValue(this._getCurrentValue());
};
LocalizedObservable.prototype.observedValue = function(value) {
if (arguments.length === 0) {
return this.value;
}
this.value = value;
this._onLocaleChange();
return this;
};
LocalizedObservable.prototype._getDefaultValue = function() {
if (!this._kb_default) {
return '';
}
if (_.isFunction(this._kb_default)) {
return this._kb_default();
} else {
return this._kb_default;
}
};
LocalizedObservable.prototype._getCurrentValue = function() {
if (!(this.value && this._kb_observable)) {
return this._getDefaultValue();
}
return this._kb_read.call(this, ko.utils.unwrapObservable(this.value), this._kb_observable);
};
LocalizedObservable.prototype._onGetValue = function() {
if (this.value) {
ko.utils.unwrapObservable(this.value);
}
return this._kb_value_observable();
};
LocalizedObservable.prototype._onSetValue = function(value) {
this._kb_write.call(this, value, ko.utils.unwrapObservable(this.value), this._kb_observable);
value = this._kb_read.call(this, ko.utils.unwrapObservable(this.value), this._kb_observable);
this._kb_value_observable(value);
if (this.options.onChange) {
return this.options.onChange(value);
}
};
LocalizedObservable.prototype._onLocaleChange = function() {
var value;
value = this._kb_read.call(this, ko.utils.unwrapObservable(this.value), this._kb_observable);
this._kb_value_observable(value);
if (this.options.onChange) {
return this.options.onChange(value);
}
};
return LocalizedObservable;
})();
Knockback.localizedObservable = function(value, options, view_model) {
return new Knockback.LocalizedObservable(value, options, view_model);
};
/*
knockback_observable.js
(c) 2011 Kevin Malakoff.
Knockback.Observable is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.Observable = (function() {
function Observable(model, options, view_model) {
this.model = model;
this.options = options;
this.view_model = view_model;
if (!this.model) {
throw new Error('Observable: model is missing');
}
if (!this.options) {
throw new Error('Observable: options is missing');
}
if (_.isString(this.options) || ko.isObservable(this.options)) {
this.options = {
key: this.options
};
}
if (!this.options.key) {
throw new Error('Observable: options.key is missing');
}
_.bindAll(this, 'destroy', 'setToDefault', '_onGetValue', '_onSetValue', '_onModelChange', '_onModelLoaded', '_onModelUnloaded');
if (Backbone.ModelRef && (this.model instanceof Backbone.ModelRef)) {
this.model_ref = this.model;
this.model_ref.retain();
this.model_ref.bind('loaded', this._onModelLoaded);
this.model_ref.bind('unloaded', this._onModelUnloaded);
this.model = this.model_ref.getModel();
}
this._kb_value_observable = ko.observable();
if (this.options.localizer) {
this._kb_localizer = new this.options.localizer(this._getCurrentValue());
}
if (this.options.write) {
if (!this.view_model) {
throw new Error('Observable: view_model is missing for read_write model attribute');
}
this._kb_observable = ko.dependentObservable({
read: this._onGetValue,
write: this._onSetValue,
owner: this.view_model
});
} else {
this._kb_observable = ko.dependentObservable(this._onGetValue);
}
this._kb_observable.destroy = this.destroy;
this._kb_observable.setToDefault = this.setToDefault;
if (!this.model_ref || this.model_ref.isLoaded()) {
this.model.bind('change', this._onModelChange);
}
return kb.wrappedObservable(this);
}
Observable.prototype.destroy = function() {
this._kb_value_observable = null;
this._kb_observable.dispose();
this._kb_observable = null;
if (this.model) {
this._onModelUnloaded(this.model);
}
if (this.model_ref) {
this.model_ref.unbind('loaded', this._onModelLoaded);
this.model_ref.unbind('unloaded', this._onModelUnloaded);
this.model_ref.release();
this.model_ref = null;
}
this.options = null;
return this.view_model = null;
};
Observable.prototype.setToDefault = function() {
var value;
value = this._getDefaultValue();
if (this._kb_localizer) {
this._kb_localizer.observedValue(value);
value = this._kb_localizer();
}
return this._kb_value_observable(value);
};
Observable.prototype._getDefaultValue = function() {
if (!this.options.hasOwnProperty('default')) {
return '';
}
if (_.isFunction(this.options["default"])) {
return this.options["default"]();
} else {
return this.options["default"];
}
};
Observable.prototype._getCurrentValue = function() {
var arg, args, key, _i, _len, _ref;
if (!this.model) {
return this._getDefaultValue();
}
key = ko.utils.unwrapObservable(this.options.key);
args = [key];
if (!_.isUndefined(this.options.args)) {
if (_.isArray(this.options.args)) {
_ref = this.options.args;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
arg = _ref[_i];
args.push(ko.utils.unwrapObservable(arg));
}
} else {
args.push(ko.utils.unwrapObservable(this.options.args));
}
}
if (this.options.read) {
return this.options.read.apply(this.view_model, args);
} else {
return this.model.get.apply(this.model, args);
}
};
Observable.prototype._onGetValue = function() {
var arg, value, _i, _len, _ref;
this._kb_value_observable();
ko.utils.unwrapObservable(this.options.key);
if (!_.isUndefined(this.options.args)) {
if (_.isArray(this.options.args)) {
_ref = this.options.args;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
arg = _ref[_i];
ko.utils.unwrapObservable(arg);
}
} else {
ko.utils.unwrapObservable(this.options.args);
}
}
value = this._getCurrentValue();
if (this._kb_localizer) {
this._kb_localizer.observedValue(value);
value = this._kb_localizer();
}
return value;
};
Observable.prototype._onSetValue = function(value) {
var arg, args, set_info, _i, _len, _ref;
if (this._kb_localizer) {
this._kb_localizer(value);
value = this._kb_localizer.observedValue();
}
if (this.model) {
set_info = {};
set_info[ko.utils.unwrapObservable(this.options.key)] = value;
args = _.isFunction(this.options.write) ? [value] : [set_info];
if (!_.isUndefined(this.options.args)) {
if (_.isArray(this.options.args)) {
_ref = this.options.args;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
arg = _ref[_i];
args.push(ko.utils.unwrapObservable(arg));
}
} else {
args.push(ko.utils.unwrapObservable(this.options.args));
}
}
if (_.isFunction(this.options.write)) {
this.options.write.apply(this.view_model, args);
} else {
this.model.set.apply(this.model, args);
}
}
if (this._kb_localizer) {
return this._kb_value_observable(this._kb_localizer());
} else {
return this._kb_value_observable(value);
}
};
Observable.prototype._onModelLoaded = function(model) {
this.model = model;
this.model.bind('change', this._onModelChange);
return this._updateValue();
};
Observable.prototype._onModelUnloaded = function(model) {
if (this._kb_localizer && this._kb_localizer.destroy) {
this._kb_localizer.destroy();
this._kb_localizer = null;
}
this.model.unbind('change', this._onModelChange);
return this.model = null;
};
Observable.prototype._onModelChange = function() {
if ((this.model && this.model.hasChanged) && !this.model.hasChanged(ko.utils.unwrapObservable(this.options.key))) {
return;
}
return this._updateValue();
};
Observable.prototype._updateValue = function() {
var value;
value = this._getCurrentValue();
if (this._kb_localizer) {
this._kb_localizer.observedValue(value);
value = this._kb_localizer();
}
return this._kb_value_observable(value);
};
return Observable;
})();
Knockback.observable = function(model, options, view_model) {
return new Knockback.Observable(model, options, view_model);
};
/*
knockback_observables.js
(c) 2011 Kevin Malakoff.
Knockback.Observables is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.Observables = (function() {
function Observables(model, mappings_info, view_model, options_or_writeable) {
var is_string, mapping_info, view_model_property_name, write, _ref, _ref2;
this.model = model;
this.mappings_info = mappings_info;
this.view_model = view_model;
if (!this.model) {
throw new Error('Observables: model is missing');
}
if (!this.mappings_info) {
throw new Error('Observables: mappings_info is missing');
}
if (!!options_or_writeable && ((_.isBoolean(options_or_writeable) && options_or_writeable) || !!options_or_writeable.write)) {
write = _.isBoolean(options_or_writeable) ? options_or_writeable : !!options_or_writeable.write;
_ref = this.mappings_info;
for (view_model_property_name in _ref) {
mapping_info = _ref[view_model_property_name];
is_string = _.isString(mapping_info);
if (is_string || !mapping_info.hasOwnProperty(write)) {
mapping_info = is_string ? {
key: mapping_info,
write: write
} : _.extend({
write: write
}, mapping_info);
}
this.view_model[view_model_property_name] = kb.observable(this.model, mapping_info, this.view_model);
}
} else {
_ref2 = this.mappings_info;
for (view_model_property_name in _ref2) {
mapping_info = _ref2[view_model_property_name];
this.view_model[view_model_property_name] = kb.observable(this.model, mapping_info, this.view_model);
}
}
}
Observables.prototype.destroy = function() {
var mapping_info, view_model_property_name, _ref;
_ref = this.mappings_info;
for (view_model_property_name in _ref) {
mapping_info = _ref[view_model_property_name];
if (this.view_model[view_model_property_name]) {
this.view_model[view_model_property_name].destroy();
}
this.view_model[view_model_property_name] = null;
}
this.view_model = null;
this.mappings_info = null;
return this.model = null;
};
Observables.prototype.setToDefault = function() {
var mapping_info, view_model_property_name, _ref, _results;
_ref = this.mappings_info;
_results = [];
for (view_model_property_name in _ref) {
mapping_info = _ref[view_model_property_name];
_results.push(this.view_model[view_model_property_name].setToDefault());
}
return _results;
};
return Observables;
})();
Knockback.observables = function(model, mappings_info, view_model, options) {
return new Knockback.Observables(model, mappings_info, view_model, options);
};
/*
knockback_triggered_observable.js
(c) 2011 Kevin Malakoff.
Knockback.Observable is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
Knockback.TriggeredObservable = (function() {
function TriggeredObservable(model, event_name) {
this.model = model;
this.event_name = event_name;
if (!this.model) {
throw new Error('Observable: model is missing');
}
if (!this.event_name) {
throw new Error('Observable: event_name is missing');
}
_.bindAll(this, 'destroy', '_onGetValue', '_onValueChange', '_onModelLoaded', '_onModelUnloaded');
if (Backbone.ModelRef && (this.model instanceof Backbone.ModelRef)) {
this.model_ref = this.model;
this.model_ref.retain();
this.model_ref.bind('loaded', this._onModelLoaded);
this.model_ref.bind('unloaded', this._onModelUnloaded);
this.model = this.model_ref.getModel();
}
this._kb_value_observable = ko.observable();
this._kb_observable = ko.dependentObservable(this._onGetValue);
this._kb_observable.destroy = this.destroy;
if (!this.model_ref || this.model_ref.isLoaded()) {
this._onModelLoaded(this.model);
}
return kb.wrappedObservable(this);
}
TriggeredObservable.prototype.destroy = function() {
this._kb_observable.dispose();
this._kb_observable = null;
this._kb_value_observable = null;
if (this.model) {
this._onModelUnloaded(this.model);
}
if (this.model_ref) {
this.model_ref.unbind('loaded', this._onModelLoaded);
this.model_ref.unbind('unloaded', this._onModelUnloaded);
this.model_ref.release();
this.model_ref = null;
}
this.options = null;
return this.view_model = null;
};
TriggeredObservable.prototype._onGetValue = function() {
return this._kb_value_observable();
};
TriggeredObservable.prototype._onModelLoaded = function(model) {
this.model = model;
this.model.bind(this.event_name, this._onValueChange);
return this._onValueChange();
};
TriggeredObservable.prototype._onModelUnloaded = function() {
if (this._kb_localizer && this._kb_localizer.destroy) {
this._kb_localizer.destroy();
this._kb_localizer = null;
}
this.model.unbind(this.event_name, this._onValueChange);
return this.model = null;
};
TriggeredObservable.prototype._onValueChange = function() {
var current_value;
current_value = this._kb_value_observable();
if (current_value !== this.model) {
return this._kb_value_observable(this.model);
} else {
return this._kb_value_observable.valueHasMutated();
}
};
return TriggeredObservable;
})();
Knockback.triggeredObservable = function(model, event_name) {
return new Knockback.TriggeredObservable(model, event_name);
};
/*
knockback_view_model.js
(c) 2011 Kevin Malakoff.
Knockback.Observable is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/knockback/blob/master/LICENSE
*/
var AttributeConnector;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
return child;
};
if (!this.Knockback) {
throw new Error('Knockback: Dependency alert! knockback_core.js must be included before this file');
}
AttributeConnector = (function() {
function AttributeConnector(model, key, read_only) {
this.key = key;
this.read_only = read_only;
_.bindAll(this, 'destroy', 'setModel');
this._kb_observable = ko.observable();
this._kb_observable.subscription = this._kb_observable.subscribe(__bind(function(value) {
var set_info;
if (this.read_only) {
if (this.model) {
value = this.model.get(this.key);
if (this._kb_observable() === value) {
return;
}
this._kb_observable(value);
}
throw "Cannot write a value to a dependentObservable unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.";
} else if (this.model) {
set_info = {};
set_info[this.key] = value;
return this.model.set(set_info);
}
}, this));
this._kb_observable.destroy = this.destroy;
this._kb_observable.setModel = this.setModel;
if (model) {
this.setModel(model);
}
return kb.wrappedObservable(this);
}
AttributeConnector.prototype.destroy = function() {
this.model = null;
return this._kb_observable = null;
};
AttributeConnector.prototype.setModel = function(model) {
if (model) {
this.model = model;
return this._kb_observable(this.model.get(this.key));
} else {
return this.model = null;
}
};
return AttributeConnector;
})();
Knockback.ViewModel_RCBase = (function() {
function ViewModel_RCBase() {
this.ref_count = 1;
}
ViewModel_RCBase.prototype._destroy = function() {
return kb.vmReleaseObservables(this);
};
ViewModel_RCBase.prototype.retain = function() {
if (this.ref_count <= 0) {
throw new Error("ViewModel: ref_count is corrupt: " + this.ref_count);
}
this.ref_count++;
return this;
};
ViewModel_RCBase.prototype.release = function() {
if (this.ref_count <= 0) {
throw new Error("ViewModel: ref_count is corrupt: " + this.ref_count);
}
this.ref_count--;
if (!this.ref_count) {
this._destroy();
}
return this;
};
ViewModel_RCBase.prototype.refCount = function() {
return this.ref_count;
};
return ViewModel_RCBase;
})();
Knockback.ViewModel = (function() {
__extends(ViewModel, kb.ViewModel_RCBase);
function ViewModel(model, options, view_model) {
var key, missing, _i, _len;
if (options == null) {
options = {};
}
this._kb_vm = {};
this._kb_vm.model = model;
this._kb_vm.options = options;
this._kb_vm.view_model = view_model;
if (!this._kb_vm.model) {
throw new Error('ViewModel: model is missing');
}
_.bindAll(this, '_kb_vm_onModelChange', '_kb_vm_onModelLoaded', '_kb_vm_onModelUnloaded');
if (!this._kb_vm.view_model) {
this._kb_vm.view_model = this;
} else {
this._kb_vm.observables = [];
}
if (Backbone.ModelRef && (this._kb_vm.model instanceof Backbone.ModelRef)) {
this._kb_vm.model_ref = this._kb_vm.model;
this._kb_vm.model_ref.retain();
this._kb_vm.model_ref.bind('loaded', this._kb_vm_onModelLoaded);
this._kb_vm.model_ref.bind('unloaded', this._kb_vm_onModelUnloaded);
this._kb_vm.model = this._kb_vm.model_ref.getModel();
}
if (!this._kb_vm.model_ref || this._kb_vm.model_ref.isLoaded()) {
this._kb_vm_onModelLoaded(this._kb_vm.model);
}
if (!this._kb_vm.options.internals && !this._kb_vm.options.requires) {
return this;
}
missing = _.union((this._kb_vm.options.internals ? this._kb_vm.options.internals : []), (this._kb_vm.options.requires ? this._kb_vm.options.requires : []));
if (!this._kb_vm.model_ref || this._kb_vm.model_ref.isLoaded()) {
missing = _.difference(missing, _.keys(this._kb_vm.model.attributes));
}
for (_i = 0, _len = missing.length; _i < _len; _i++) {
key = missing[_i];
this._updateAttributeObservor(this._kb_vm.model, key);
}
}
ViewModel.prototype._destroy = function() {
var view_model;
if (this._kb_vm.model) {
this._kb_vm.model.unbind('change', this._kb_vm_onModelChange);
this._kb_vm.model = null;
}
view_model = this._kb_vm.view_model;
this._kb_vm.view_model = null;
kb.vmReleaseObservables(view_model, this._kb_vm.observables);
if (this._kb_vm.observables) {
return this._kb_vm.observables = null;
}
};
ViewModel.prototype._kb_vm_onModelLoaded = function(model) {
var key, _results;
this._kb_vm.model = model;
this._kb_vm.model.bind('change', this._kb_vm_onModelChange);
_results = [];
for (key in this._kb_vm.model.attributes) {
_results.push(this._updateAttributeObservor(this._kb_vm.model, key));
}
return _results;
};
ViewModel.prototype._kb_vm_onModelUnloaded = function(model) {
var key, _results;
this._kb_vm.model.unbind('change', this._kb_vm_onModelChange);
model = this._kb_vm.model;
this._kb_vm.model = null;
_results = [];
for (key in model.attributes) {
_results.push(this._updateAttributeObservor(this._kb_vm.model, key));
}
return _results;
};
ViewModel.prototype._kb_vm_onModelChange = function() {
var key, _results;
if (!this._kb_vm.model._changed) {
return;
}
_results = [];
for (key in this._kb_vm.model.attributes) {
_results.push((this._kb_vm.model.hasChanged(key) ? this._updateAttributeObservor(this._kb_vm.model, key) : void 0));
}
return _results;
};
ViewModel.prototype._updateAttributeObservor = function(model, key) {
var vm_key;
vm_key = this._kb_vm.options.internals && _.contains(this._kb_vm.options.internals, key) ? '_' + key : key;
if (this._kb_vm.view_model.hasOwnProperty(vm_key)) {
if (this._kb_vm.view_model[vm_key]) {
return this._kb_vm.view_model[vm_key].setModel(model);
}
} else {
if (this._kb_vm.observables) {
this._kb_vm.observables.push(vm_key);
}
return this._kb_vm.view_model[vm_key] = new AttributeConnector(model, key, this._kb_vm.options.read_only);
}
};
return ViewModel;
})();
Knockback.viewModel = function(model, options, view_model) {
return new Knockback.ViewModel(model, options, view_model);
};
\ No newline at end of file
// Knockout JavaScript library v2.0.0
// (c) Steven Sanderson - http://knockoutjs.com/
// License: MIT (http://www.opensource.org/licenses/mit-license.php)
(function(window,undefined){
function c(a){throw a;}var l=void 0,m=!0,o=null,p=!1,r=window.ko={};r.b=function(a,b){for(var d=a.split("."),e=window,f=0;f<d.length-1;f++)e=e[d[f]];e[d[d.length-1]]=b};r.l=function(a,b,d){a[b]=d};
r.a=new function(){function a(a,e){if("INPUT"!=a.tagName||!a.type)return p;if("click"!=e.toLowerCase())return p;var b=a.type.toLowerCase();return"checkbox"==b||"radio"==b}var b=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,d={},e={};d[/Firefox\/2/i.test(navigator.userAgent)?"KeyboardEvent":"UIEvents"]=["keyup","keydown","keypress"];d.MouseEvents="click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave".split(",");for(var f in d){var h=d[f];if(h.length)for(var g=0,i=h.length;g<i;g++)e[h[g]]=
f}var j=function(){for(var a=3,e=document.createElement("div"),b=e.getElementsByTagName("i");e.innerHTML="<\!--[if gt IE "+ ++a+"]><i></i><![endif]--\>",b[0];);return 4<a?a:l}();return{Ba:["authenticity_token",/^__RequestVerificationToken(_.*)?$/],n:function(a,e){for(var b=0,f=a.length;b<f;b++)e(a[b])},k:function(a,e){if("function"==typeof Array.prototype.indexOf)return Array.prototype.indexOf.call(a,e);for(var b=0,f=a.length;b<f;b++)if(a[b]===e)return b;return-1},Wa:function(a,e,b){for(var f=0,d=
a.length;f<d;f++)if(e.call(b,a[f]))return a[f];return o},ca:function(a,e){var b=r.a.k(a,e);0<=b&&a.splice(b,1)},ya:function(a){for(var a=a||[],e=[],b=0,f=a.length;b<f;b++)0>r.a.k(e,a[b])&&e.push(a[b]);return e},ba:function(a,e){for(var a=a||[],b=[],f=0,d=a.length;f<d;f++)b.push(e(a[f]));return b},aa:function(a,e){for(var a=a||[],b=[],f=0,d=a.length;f<d;f++)e(a[f])&&b.push(a[f]);return b},J:function(a,e){for(var b=0,f=e.length;b<f;b++)a.push(e[b]);return a},extend:function(a,e){for(var b in e)e.hasOwnProperty(b)&&
(a[b]=e[b]);return a},U:function(a){for(;a.firstChild;)r.removeNode(a.firstChild)},oa:function(a,e){r.a.U(a);e&&r.a.n(e,function(e){a.appendChild(e)})},Ja:function(a,e){var b=a.nodeType?[a]:a;if(0<b.length){for(var f=b[0],d=f.parentNode,h=0,g=e.length;h<g;h++)d.insertBefore(e[h],f);h=0;for(g=b.length;h<g;h++)r.removeNode(b[h])}},La:function(a,e){0<=navigator.userAgent.indexOf("MSIE 6")?a.setAttribute("selected",e):a.selected=e},z:function(a){return(a||"").replace(b,"")},Db:function(a,e){for(var b=
[],f=(a||"").split(e),d=0,h=f.length;d<h;d++){var g=r.a.z(f[d]);""!==g&&b.push(g)}return b},Cb:function(a,e){a=a||"";return e.length>a.length?p:a.substring(0,e.length)===e},hb:function(a){for(var e=Array.prototype.slice.call(arguments,1),b="return ("+a+")",f=0;f<e.length;f++)e[f]&&"object"==typeof e[f]&&(b="with(sc["+f+"]) { "+b+" } ");return(new Function("sc",b))(e)},fb:function(a,e){if(e.compareDocumentPosition)return 16==(e.compareDocumentPosition(a)&16);for(;a!=o;){if(a==e)return m;a=a.parentNode}return p},
ga:function(a){return r.a.fb(a,document)},s:function(e,b,f){if("undefined"!=typeof jQuery){if(a(e,b))var d=f,f=function(a,e){var b=this.checked;if(e)this.checked=e.Ya!==m;d.call(this,a);this.checked=b};jQuery(e).bind(b,f)}else"function"==typeof e.addEventListener?e.addEventListener(b,f,p):"undefined"!=typeof e.attachEvent?e.attachEvent("on"+b,function(a){f.call(e,a)}):c(Error("Browser doesn't support addEventListener or attachEvent"))},sa:function(b,f){(!b||!b.nodeType)&&c(Error("element must be a DOM node when calling triggerEvent"));
if("undefined"!=typeof jQuery){var d=[];a(b,f)&&d.push({Ya:b.checked});jQuery(b).trigger(f,d)}else if("function"==typeof document.createEvent)"function"==typeof b.dispatchEvent?(d=document.createEvent(e[f]||"HTMLEvents"),d.initEvent(f,m,m,window,0,0,0,0,0,p,p,p,p,0,b),b.dispatchEvent(d)):c(Error("The supplied element doesn't support dispatchEvent"));else if("undefined"!=typeof b.fireEvent){if("click"==f&&"INPUT"==b.tagName&&("checkbox"==b.type.toLowerCase()||"radio"==b.type.toLowerCase()))b.checked=
b.checked!==m;b.fireEvent("on"+f)}else c(Error("Browser doesn't support triggering events"))},d:function(a){return r.V(a)?a():a},eb:function(a,e){return 0<=r.a.k((a.className||"").split(/\s+/),e)},Qa:function(a,e,b){var f=r.a.eb(a,e);if(b&&!f)a.className=(a.className||"")+" "+e;else if(f&&!b){for(var b=(a.className||"").split(/\s+/),f="",d=0;d<b.length;d++)b[d]!=e&&(f+=b[d]+" ");a.className=r.a.z(f)}},outerHTML:function(a){if(j===l){var e=a.outerHTML;if("string"==typeof e)return e}e=window.document.createElement("div");
e.appendChild(a.cloneNode(m));return e.innerHTML},Ma:function(a,e){var b=r.a.d(e);if(b===o||b===l)b="";"innerText"in a?a.innerText=b:a.textContent=b;if(9<=j)a.innerHTML=a.innerHTML},yb:function(a,e){for(var a=r.a.d(a),e=r.a.d(e),b=[],f=a;f<=e;f++)b.push(f);return b},X:function(a){for(var e=[],b=0,f=a.length;b<f;b++)e.push(a[b]);return e},ob:6===j,pb:7===j,Ca:function(a,e){for(var b=r.a.X(a.getElementsByTagName("INPUT")).concat(r.a.X(a.getElementsByTagName("TEXTAREA"))),f="string"==typeof e?function(a){return a.name===
e}:function(a){return e.test(a.name)},d=[],h=b.length-1;0<=h;h--)f(b[h])&&d.push(b[h]);return d},vb:function(a){return"string"==typeof a&&(a=r.a.z(a))?window.JSON&&window.JSON.parse?window.JSON.parse(a):(new Function("return "+a))():o},qa:function(a){("undefined"==typeof JSON||"undefined"==typeof JSON.stringify)&&c(Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js"));
return JSON.stringify(r.a.d(a))},wb:function(a,e,b){var b=b||{},f=b.params||{},d=b.includeFields||this.Ba,h=a;if("object"==typeof a&&"FORM"==a.tagName)for(var h=a.action,g=d.length-1;0<=g;g--)for(var j=r.a.Ca(a,d[g]),i=j.length-1;0<=i;i--)f[j[i].name]=j[i].value;var e=r.a.d(e),u=document.createElement("FORM");u.style.display="none";u.action=h;u.method="post";for(var y in e)a=document.createElement("INPUT"),a.name=y,a.value=r.a.qa(r.a.d(e[y])),u.appendChild(a);for(y in f)a=document.createElement("INPUT"),
a.name=y,a.value=f[y],u.appendChild(a);document.body.appendChild(u);b.submitter?b.submitter(u):u.submit();setTimeout(function(){u.parentNode.removeChild(u)},0)}}};r.b("ko.utils",r.a);
r.a.n([["arrayForEach",r.a.n],["arrayFirst",r.a.Wa],["arrayFilter",r.a.aa],["arrayGetDistinctValues",r.a.ya],["arrayIndexOf",r.a.k],["arrayMap",r.a.ba],["arrayPushAll",r.a.J],["arrayRemoveItem",r.a.ca],["extend",r.a.extend],["fieldsIncludedWithJsonPost",r.a.Ba],["getFormFields",r.a.Ca],["postJson",r.a.wb],["parseJson",r.a.vb],["registerEventHandler",r.a.s],["stringifyJson",r.a.qa],["range",r.a.yb],["toggleDomNodeCssClass",r.a.Qa],["triggerEvent",r.a.sa],["unwrapObservable",r.a.d]],function(a){r.b("ko.utils."+
a[0],a[1])});Function.prototype.bind||(Function.prototype.bind=function(a){var b=this,d=Array.prototype.slice.call(arguments),a=d.shift();return function(){return b.apply(a,d.concat(Array.prototype.slice.call(arguments)))}});
r.a.e=new function(){var a=0,b="__ko__"+(new Date).getTime(),d={};return{get:function(a,b){var d=r.a.e.getAll(a,p);return d===l?l:d[b]},set:function(a,b,d){d===l&&r.a.e.getAll(a,p)===l||(r.a.e.getAll(a,m)[b]=d)},getAll:function(e,f){var h=e[b];if(!(h&&"null"!==h)){if(!f)return;h=e[b]="ko"+a++;d[h]={}}return d[h]},clear:function(a){var f=a[b];f&&(delete d[f],a[b]=o)}}};r.b("ko.utils.domData",r.a.e);r.b("ko.utils.domData.clear",r.a.e.clear);
r.a.A=new function(){function a(a,b){var h=r.a.e.get(a,d);h===l&&b&&(h=[],r.a.e.set(a,d,h));return h}function b(e){var b=a(e,p);if(b)for(var b=b.slice(0),d=0;d<b.length;d++)b[d](e);r.a.e.clear(e);"function"==typeof jQuery&&"function"==typeof jQuery.cleanData&&jQuery.cleanData([e])}var d="__ko_domNodeDisposal__"+(new Date).getTime();return{va:function(e,b){"function"!=typeof b&&c(Error("Callback must be a function"));a(e,m).push(b)},Ia:function(e,b){var h=a(e,p);h&&(r.a.ca(h,b),0==h.length&&r.a.e.set(e,
d,l))},F:function(a){if(!(1!=a.nodeType&&9!=a.nodeType)){b(a);var f=[];r.a.J(f,a.getElementsByTagName("*"));for(var a=0,d=f.length;a<d;a++)b(f[a])}},removeNode:function(a){r.F(a);a.parentNode&&a.parentNode.removeChild(a)}}};r.F=r.a.A.F;r.removeNode=r.a.A.removeNode;r.b("ko.cleanNode",r.F);r.b("ko.removeNode",r.removeNode);r.b("ko.utils.domNodeDisposal",r.a.A);r.b("ko.utils.domNodeDisposal.addDisposeCallback",r.a.A.va);r.b("ko.utils.domNodeDisposal.removeDisposeCallback",r.a.A.Ia);
r.a.ma=function(a){var b;if("undefined"!=typeof jQuery){if((b=jQuery.clean([a]))&&b[0]){for(a=b[0];a.parentNode&&11!==a.parentNode.nodeType;)a=a.parentNode;a.parentNode&&a.parentNode.removeChild(a)}}else{var d=r.a.z(a).toLowerCase();b=document.createElement("div");d=d.match(/^<(thead|tbody|tfoot)/)&&[1,"<table>","</table>"]||!d.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!d.indexOf("<td")||!d.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||[0,"",""];a="ignored<div>"+
d[1]+a+d[2]+"</div>";for("function"==typeof window.innerShiv?b.appendChild(window.innerShiv(a)):b.innerHTML=a;d[0]--;)b=b.lastChild;b=r.a.X(b.lastChild.childNodes)}return b};r.a.Z=function(a,b){r.a.U(a);if(b!==o&&b!==l)if("string"!=typeof b&&(b=b.toString()),"undefined"!=typeof jQuery)jQuery(a).html(b);else for(var d=r.a.ma(b),e=0;e<d.length;e++)a.appendChild(d[e])};r.b("ko.utils.parseHtmlFragment",r.a.ma);r.b("ko.utils.setHtml",r.a.Z);
r.r=function(){function a(){return(4294967296*(1+Math.random())|0).toString(16).substring(1)}function b(a,f){if(a)if(8==a.nodeType){var d=r.r.Ga(a.nodeValue);d!=o&&f.push({cb:a,tb:d})}else if(1==a.nodeType)for(var d=0,g=a.childNodes,i=g.length;d<i;d++)b(g[d],f)}var d={};return{ka:function(b){"function"!=typeof b&&c(Error("You can only pass a function to ko.memoization.memoize()"));var f=a()+a();d[f]=b;return"<\!--[ko_memo:"+f+"]--\>"},Ra:function(a,b){var h=d[a];h===l&&c(Error("Couldn't find any memo with ID "+
a+". Perhaps it's already been unmemoized."));try{return h.apply(o,b||[]),m}finally{delete d[a]}},Sa:function(a,f){var d=[];b(a,d);for(var g=0,i=d.length;g<i;g++){var j=d[g].cb,k=[j];f&&r.a.J(k,f);r.r.Ra(d[g].tb,k);j.nodeValue="";j.parentNode&&j.parentNode.removeChild(j)}},Ga:function(a){return(a=a.match(/^\[ko_memo\:(.*?)\]$/))?a[1]:o}}}();r.b("ko.memoization",r.r);r.b("ko.memoization.memoize",r.r.ka);r.b("ko.memoization.unmemoize",r.r.Ra);r.b("ko.memoization.parseMemoText",r.r.Ga);
r.b("ko.memoization.unmemoizeDomNodeAndDescendants",r.r.Sa);r.Aa={throttle:function(a,b){a.throttleEvaluation=b;var d=o;return r.i({read:a,write:function(e){clearTimeout(d);d=setTimeout(function(){a(e)},b)}})},notify:function(a,b){a.equalityComparer="always"==b?function(){return p}:r.w.fn.equalityComparer;return a}};r.b("ko.extenders",r.Aa);r.Oa=function(a,b){this.da=a;this.bb=b;r.l(this,"dispose",this.v)};r.Oa.prototype.v=function(){this.nb=m;this.bb()};
r.R=function(){this.u={};r.a.extend(this,r.R.fn);r.l(this,"subscribe",this.ra);r.l(this,"extend",this.extend);r.l(this,"getSubscriptionsCount",this.kb)};
r.R.fn={ra:function(a,b,d){var d=d||"change",a=b?a.bind(b):a,e=new r.Oa(a,function(){r.a.ca(this.u[d],e)}.bind(this));this.u[d]||(this.u[d]=[]);this.u[d].push(e);return e},notifySubscribers:function(a,b){b=b||"change";this.u[b]&&r.a.n(this.u[b].slice(0),function(b){b&&b.nb!==m&&b.da(a)})},kb:function(){var a=0,b;for(b in this.u)this.u.hasOwnProperty(b)&&(a+=this.u[b].length);return a},extend:function(a){var b=this;if(a)for(var d in a){var e=r.Aa[d];"function"==typeof e&&(b=e(b,a[d]))}return b}};
r.Ea=function(a){return"function"==typeof a.ra&&"function"==typeof a.notifySubscribers};r.b("ko.subscribable",r.R);r.b("ko.isSubscribable",r.Ea);r.T=function(){var a=[];return{Xa:function(b){a.push({da:b,za:[]})},end:function(){a.pop()},Ha:function(b){r.Ea(b)||c("Only subscribable things can act as dependencies");if(0<a.length){var d=a[a.length-1];0<=r.a.k(d.za,b)||(d.za.push(b),d.da(b))}}}}();var B={undefined:m,"boolean":m,number:m,string:m};
r.w=function(a){function b(){if(0<arguments.length){if(!b.equalityComparer||!b.equalityComparer(d,arguments[0]))b.H(),d=arguments[0],b.G();return this}r.T.Ha(b);return d}var d=a;r.R.call(b);b.G=function(){b.notifySubscribers(d)};b.H=function(){b.notifySubscribers(d,"beforeChange")};r.a.extend(b,r.w.fn);r.l(b,"valueHasMutated",b.G);r.l(b,"valueWillMutate",b.H);return b};r.w.fn={B:r.w,equalityComparer:function(a,b){return a===o||typeof a in B?a===b:p}};
r.V=function(a){return a===o||a===l||a.B===l?p:a.B===r.w?m:r.V(a.B)};r.P=function(a){return"function"==typeof a&&a.B===r.w?m:"function"==typeof a&&a.B===r.i&&a.lb?m:p};r.b("ko.observable",r.w);r.b("ko.isObservable",r.V);r.b("ko.isWriteableObservable",r.P);
r.Q=function(a){0==arguments.length&&(a=[]);a!==o&&a!==l&&!("length"in a)&&c(Error("The argument passed when initializing an observable array must be an array, or null, or undefined."));var b=new r.w(a);r.a.extend(b,r.Q.fn);r.l(b,"remove",b.remove);r.l(b,"removeAll",b.zb);r.l(b,"destroy",b.fa);r.l(b,"destroyAll",b.ab);r.l(b,"indexOf",b.indexOf);r.l(b,"replace",b.replace);return b};
r.Q.fn={remove:function(a){for(var b=this(),d=[],e="function"==typeof a?a:function(b){return b===a},f=0;f<b.length;f++){var h=b[f];e(h)&&(0===d.length&&this.H(),d.push(h),b.splice(f,1),f--)}d.length&&this.G();return d},zb:function(a){if(a===l){var b=this(),d=b.slice(0);this.H();b.splice(0,b.length);this.G();return d}return!a?[]:this.remove(function(b){return 0<=r.a.k(a,b)})},fa:function(a){var b=this(),d="function"==typeof a?a:function(b){return b===a};this.H();for(var e=b.length-1;0<=e;e--)d(b[e])&&
(b[e]._destroy=m);this.G()},ab:function(a){return a===l?this.fa(function(){return m}):!a?[]:this.fa(function(b){return 0<=r.a.k(a,b)})},indexOf:function(a){var b=this();return r.a.k(b,a)},replace:function(a,b){var d=this.indexOf(a);0<=d&&(this.H(),this()[d]=b,this.G())}};r.a.n("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){r.Q.fn[a]=function(){var b=this();this.H();b=b[a].apply(b,arguments);this.G();return b}});
r.a.n(["slice"],function(a){r.Q.fn[a]=function(){var b=this();return b[a].apply(b,arguments)}});r.b("ko.observableArray",r.Q);function C(a,b){a&&"object"==typeof a?b=a:(b=b||{},b.read=a||b.read);"function"!=typeof b.read&&c("Pass a function that returns the value of the dependentObservable");return b}
r.i=function(a,b,d){function e(){r.a.n(q,function(a){a.v()});q=[]}function f(){var a=g.throttleEvaluation;a&&0<=a?(clearTimeout(v),v=setTimeout(h,a)):h()}function h(){if(j&&"function"==typeof d.disposeWhen&&d.disposeWhen())g.v();else{try{e();r.T.Xa(function(a){q.push(a.ra(f))});var a=d.read.call(d.owner||b);g.notifySubscribers(i,"beforeChange");i=a}finally{r.T.end()}g.notifySubscribers(i);j=m}}function g(){if(0<arguments.length)"function"===typeof d.write?d.write.apply(d.owner||b,arguments):c("Cannot write a value to a dependentObservable unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
else return j||h(),r.T.Ha(g),i}var i,j=p,d=C(a,d),k="object"==typeof d.disposeWhenNodeIsRemoved?d.disposeWhenNodeIsRemoved:o,n=o;if(k){n=function(){g.v()};r.a.A.va(k,n);var t=d.disposeWhen;d.disposeWhen=function(){return!r.a.ga(k)||"function"==typeof t&&t()}}var q=[],v=o;g.jb=function(){return q.length};g.lb="function"===typeof d.write;g.v=function(){k&&r.a.A.Ia(k,n);e()};r.R.call(g);r.a.extend(g,r.i.fn);d.deferEvaluation!==m&&h();r.l(g,"dispose",g.v);r.l(g,"getDependenciesCount",g.jb);return g};
r.i.fn={B:r.i};r.i.B=r.w;r.b("ko.dependentObservable",r.i);r.b("ko.computed",r.i);
(function(){function a(e,f,h){h=h||new d;e=f(e);if(!("object"==typeof e&&e!==o&&e!==l&&!(e instanceof Date)))return e;var g=e instanceof Array?[]:{};h.save(e,g);b(e,function(b){var d=f(e[b]);switch(typeof d){case "boolean":case "number":case "string":case "function":g[b]=d;break;case "object":case "undefined":var k=h.get(d);g[b]=k!==l?k:a(d,f,h)}});return g}function b(a,b){if(a instanceof Array)for(var d=0;d<a.length;d++)b(d);else for(d in a)b(d)}function d(){var a=[],b=[];this.save=function(d,g){var i=
r.a.k(a,d);0<=i?b[i]=g:(a.push(d),b.push(g))};this.get=function(d){d=r.a.k(a,d);return 0<=d?b[d]:l}}r.Pa=function(b){0==arguments.length&&c(Error("When calling ko.toJS, pass the object you want to convert."));return a(b,function(a){for(var b=0;r.V(a)&&10>b;b++)a=a();return a})};r.toJSON=function(a){a=r.Pa(a);return r.a.qa(a)}})();r.b("ko.toJS",r.Pa);r.b("ko.toJSON",r.toJSON);
r.h={q:function(a){return"OPTION"==a.tagName?a.__ko__hasDomDataOptionValue__===m?r.a.e.get(a,r.c.options.la):a.getAttribute("value"):"SELECT"==a.tagName?0<=a.selectedIndex?r.h.q(a.options[a.selectedIndex]):l:a.value},S:function(a,b){if("OPTION"==a.tagName)switch(typeof b){case "string":r.a.e.set(a,r.c.options.la,l);"__ko__hasDomDataOptionValue__"in a&&delete a.__ko__hasDomDataOptionValue__;a.value=b;break;default:r.a.e.set(a,r.c.options.la,b),a.__ko__hasDomDataOptionValue__=m,a.value="number"===typeof b?
b:""}else if("SELECT"==a.tagName)for(var d=a.options.length-1;0<=d;d--){if(r.h.q(a.options[d])==b){a.selectedIndex=d;break}}else{if(b===o||b===l)b="";a.value=b}}};r.b("ko.selectExtensions",r.h);r.b("ko.selectExtensions.readValue",r.h.q);r.b("ko.selectExtensions.writeValue",r.h.S);
r.j=function(){function a(a,e){for(var d=o;a!=d;)d=a,a=a.replace(b,function(a,b){return e[b]});return a}var b=/\@ko_token_(\d+)\@/g,d=/^[\_$a-z][\_$a-z0-9]*(\[.*?\])*(\.[\_$a-z][\_$a-z0-9]*(\[.*?\])*)*$/i,e=["true","false"];return{D:[],Y:function(b){var e=r.a.z(b);if(3>e.length)return[];"{"===e.charAt(0)&&(e=e.substring(1,e.length-1));for(var b=[],d=o,i,j=0;j<e.length;j++){var k=e.charAt(j);if(d===o)switch(k){case '"':case "'":case "/":d=j,i=k}else if(k==i&&"\\"!==e.charAt(j-1)){k=e.substring(d,j+
1);b.push(k);var n="@ko_token_"+(b.length-1)+"@",e=e.substring(0,d)+n+e.substring(j+1),j=j-(k.length-n.length),d=o}}i=d=o;for(var t=0,q=o,j=0;j<e.length;j++){k=e.charAt(j);if(d===o)switch(k){case "{":d=j;q=k;i="}";break;case "(":d=j;q=k;i=")";break;case "[":d=j,q=k,i="]"}k===q?t++:k===i&&(t--,0===t&&(k=e.substring(d,j+1),b.push(k),n="@ko_token_"+(b.length-1)+"@",e=e.substring(0,d)+n+e.substring(j+1),j-=k.length-n.length,d=o))}i=[];e=e.split(",");d=0;for(j=e.length;d<j;d++)t=e[d],q=t.indexOf(":"),
0<q&&q<t.length-1?(k=t.substring(q+1),i.push({key:a(t.substring(0,q),b),value:a(k,b)})):i.push({unknown:a(t,b)});return i},ia:function(a){for(var b="string"===typeof a?r.j.Y(a):a,g=[],a=[],i,j=0;i=b[j];j++)if(0<g.length&&g.push(","),i.key){var k;a:{k=i.key;var n=r.a.z(k);switch(n.length&&n.charAt(0)){case "'":case '"':break a;default:k="'"+n+"'"}}i=i.value;g.push(k);g.push(":");g.push(i);n=r.a.z(i);if(0<=r.a.k(e,r.a.z(n).toLowerCase())?0:n.match(d)!==o)0<a.length&&a.push(", "),a.push(k+" : function(__ko_value) { "+
i+" = __ko_value; }")}else i.unknown&&g.push(i.unknown);b=g.join("");0<a.length&&(b=b+", '_ko_property_writers' : { "+a.join("")+" } ");return b},rb:function(a,b){for(var e=0;e<a.length;e++)if(r.a.z(a[e].key)==b)return m;return p}}}();r.b("ko.jsonExpressionRewriting",r.j);r.b("ko.jsonExpressionRewriting.bindingRewriteValidators",r.j.D);r.b("ko.jsonExpressionRewriting.parseObjectLiteral",r.j.Y);r.b("ko.jsonExpressionRewriting.insertPropertyAccessorsIntoJson",r.j.ia);
(function(){function a(a){return 8==a.nodeType&&(f?a.text:a.nodeValue).match(h)}function b(a){return 8==a.nodeType&&(f?a.text:a.nodeValue).match(g)}function d(e,d){for(var f=e,g=1,h=[];f=f.nextSibling;){if(b(f)&&(g--,0===g))return h;h.push(f);a(f)&&g++}d||c(Error("Cannot find closing comment tag to match: "+e.nodeValue));return o}function e(a,b){var e=d(a,b);return e?0<e.length?e[e.length-1].nextSibling:a.nextSibling:o}var f="<\!--test--\>"===document.createComment("test").text,h=f?/^<\!--\s*ko\s+(.*\:.*)\s*--\>$/:
/^\s*ko\s+(.*\:.*)\s*$/,g=f?/^<\!--\s*\/ko\s*--\>$/:/^\s*\/ko\s*$/,i={ul:m,ol:m};r.f={C:{},childNodes:function(b){return a(b)?d(b):b.childNodes},ha:function(b){if(a(b))for(var b=r.f.childNodes(b),e=0,d=b.length;e<d;e++)r.removeNode(b[e]);else r.a.U(b)},oa:function(b,e){if(a(b)){r.f.ha(b);for(var d=b.nextSibling,f=0,g=e.length;f<g;f++)d.parentNode.insertBefore(e[f],d)}else r.a.oa(b,e)},xb:function(b,e){a(b)?b.parentNode.insertBefore(e,b.nextSibling):b.firstChild?b.insertBefore(e,b.firstChild):b.appendChild(e)},
mb:function(b,e,d){a(b)?b.parentNode.insertBefore(e,d.nextSibling):d.nextSibling?b.insertBefore(e,d.nextSibling):b.appendChild(e)},nextSibling:function(d){return a(d)?e(d).nextSibling:d.nextSibling&&b(d.nextSibling)?l:d.nextSibling},ta:function(b){return(b=a(b))?b[1]:o},ib:function(a){if(r.f.ta(a)){var b;b=r.f.childNodes(a);for(var e=[],d=0,f=b.length;d<f;d++)r.a.A.F(b[d]),e.push(r.a.outerHTML(b[d]));b=String.prototype.concat.apply("",e);r.f.ha(a);(new r.m.I(a)).text(b)}},Fa:function(d){if(i[d.tagName.toLowerCase()]){var f=
d.firstChild;if(f){do if(1===f.nodeType){var g;g=f.firstChild;var h=o;if(g){do if(h)h.push(g);else if(a(g)){var q=e(g,m);q?g=q:h=[g]}else b(g)&&(h=[g]);while(g=g.nextSibling)}if(g=h){h=f.nextSibling;for(q=0;q<g.length;q++)h?d.insertBefore(g[q],h):d.appendChild(g[q])}}while(f=f.nextSibling)}}}}})();r.L=function(){};
r.a.extend(r.L.prototype,{nodeHasBindings:function(a){switch(a.nodeType){case 1:return a.getAttribute("data-bind")!=o;case 8:return r.f.ta(a)!=o;default:return p}},getBindings:function(a,b){var d=this.getBindingsString(a,b);return d?this.parseBindingsString(d,b):o},getBindingsString:function(a){switch(a.nodeType){case 1:return a.getAttribute("data-bind");case 8:return r.f.ta(a);default:return o}},parseBindingsString:function(a,b){try{var d=b.$data,e=" { "+r.j.ia(a)+" } ";return r.a.hb(e,d===o?window:
d,b)}catch(f){c(Error("Unable to parse bindings.\nMessage: "+f+";\nBindings value: "+a))}}});r.L.instance=new r.L;r.b("ko.bindingProvider",r.L);
(function(){function a(a,d){for(var h,g=d.childNodes[0];h=g;)g=r.f.nextSibling(h),b(a,h,p)}function b(b,f,h){var g=m,i=1==f.nodeType;i&&r.f.Fa(f);if(i&&h||r.L.instance.nodeHasBindings(f))g=d(f,o,b,h).Bb;i&&g&&a(b,f)}function d(a,b,d,g){function i(a){return function(){return n[a]}}function j(){return n}var k=0;r.f.ib(a);var n,t;new r.i(function(){var q=d&&d instanceof r.K?d:new r.K(r.a.d(d)),v=q.$data;g&&r.Na(a,q);if(n=("function"==typeof b?b():b)||r.L.instance.getBindings(a,q)){if(0===k){k=1;for(var s in n){var w=
r.c[s];w&&8===a.nodeType&&!r.f.C[s]&&c(Error("The binding '"+s+"' cannot be used with virtual elements"));if(w&&"function"==typeof w.init&&(w=(0,w.init)(a,i(s),j,v,q))&&w.controlsDescendantBindings)t!==l&&c(Error("Multiple bindings ("+t+" and "+s+") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.")),t=s}k=2}if(2===k)for(s in n)(w=r.c[s])&&"function"==typeof w.update&&(0,w.update)(a,i(s),j,v,q)}},o,{disposeWhenNodeIsRemoved:a});
return{Bb:t===l}}r.c={};r.K=function(a,b){this.$data=a;b?(this.$parent=b.$data,this.$parents=(b.$parents||[]).slice(0),this.$parents.unshift(this.$parent),this.$root=b.$root):(this.$parents=[],this.$root=a)};r.K.prototype.createChildContext=function(a){return new r.K(a,this)};r.Na=function(a,b){if(2==arguments.length)r.a.e.set(a,"__ko_bindingContext__",b);else return r.a.e.get(a,"__ko_bindingContext__")};r.xa=function(a,b,h){1===a.nodeType&&r.f.Fa(a);return d(a,b,h,m)};r.Ta=function(b,d){1===d.nodeType&&
a(b,d)};r.wa=function(a,d){d&&1!==d.nodeType&&8!==d.nodeType&&c(Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node"));d=d||window.document.body;b(a,d,m)};r.ea=function(a){switch(a.nodeType){case 1:case 8:var b=r.Na(a);if(b)return b;if(a.parentNode)return r.ea(a.parentNode)}};r.$a=function(a){return(a=r.ea(a))?a.$data:l};r.b("ko.bindingHandlers",r.c);r.b("ko.applyBindings",r.wa);r.b("ko.applyBindingsToDescendants",r.Ta);r.b("ko.applyBindingsToNode",
r.xa);r.b("ko.contextFor",r.ea);r.b("ko.dataFor",r.$a)})();r.a.n(["click"],function(a){r.c[a]={init:function(b,d,e,f){return r.c.event.init.call(this,b,function(){var b={};b[a]=d();return b},e,f)}}});
r.c.event={init:function(a,b,d,e){var f=b()||{},h;for(h in f)(function(){var f=h;"string"==typeof f&&r.a.s(a,f,function(a){var h,k=b()[f];if(k){var n=d();try{var t=r.a.X(arguments);t.unshift(e);h=k.apply(e,t)}finally{if(h!==m)a.preventDefault?a.preventDefault():a.returnValue=p}if(n[f+"Bubble"]===p)a.cancelBubble=m,a.stopPropagation&&a.stopPropagation()}})})()}};
r.c.submit={init:function(a,b,d,e){"function"!=typeof b()&&c(Error("The value for a submit binding must be a function"));r.a.s(a,"submit",function(d){var h,g=b();try{h=g.call(e,a)}finally{if(h!==m)d.preventDefault?d.preventDefault():d.returnValue=p}})}};r.c.visible={update:function(a,b){var d=r.a.d(b()),e="none"!=a.style.display;if(d&&!e)a.style.display="";else if(!d&&e)a.style.display="none"}};
r.c.enable={update:function(a,b){var d=r.a.d(b());if(d&&a.disabled)a.removeAttribute("disabled");else if(!d&&!a.disabled)a.disabled=m}};r.c.disable={update:function(a,b){r.c.enable.update(a,function(){return!r.a.d(b())})}};function D(a,b,d){d&&b!==r.h.q(a)&&r.h.S(a,b);b!==r.h.q(a)&&r.a.sa(a,"change")}
r.c.value={init:function(a,b,d){var e=["change"],f=d().valueUpdate;f&&("string"==typeof f&&(f=[f]),r.a.J(e,f),e=r.a.ya(e));r.a.n(e,function(e){var f=p;r.a.Cb(e,"after")&&(f=m,e=e.substring(5));var i=f?function(a){setTimeout(a,0)}:function(a){a()};r.a.s(a,e,function(){i(function(){var e=b(),f=r.h.q(a);r.P(e)?e(f):(e=d(),e._ko_property_writers&&e._ko_property_writers.value&&e._ko_property_writers.value(f))})})})},update:function(a,b){var d=r.a.d(b()),e=r.h.q(a),f=d!=e;0===d&&0!==e&&"0"!==e&&(f=m);f&&
(e=function(){r.h.S(a,d)},e(),"SELECT"==a.tagName&&setTimeout(e,0));"SELECT"==a.tagName&&0<a.length&&D(a,d,p)}};
r.c.options={update:function(a,b,d){"SELECT"!=a.tagName&&c(Error("options binding applies only to SELECT elements"));var e=0==a.length,f=r.a.ba(r.a.aa(a.childNodes,function(a){return a.tagName&&"OPTION"==a.tagName&&a.selected}),function(a){return r.h.q(a)||a.innerText||a.textContent}),h=a.scrollTop;a.scrollTop=0;for(var g=r.a.d(b());0<a.length;)r.F(a.options[0]),a.remove(0);if(g){d=d();"number"!=typeof g.length&&(g=[g]);if(d.optionsCaption){var i=document.createElement("OPTION");r.a.Z(i,d.optionsCaption);
r.h.S(i,l);a.appendChild(i)}for(var b=0,j=g.length;b<j;b++){var i=document.createElement("OPTION"),k="string"==typeof d.optionsValue?g[b][d.optionsValue]:g[b],k=r.a.d(k);r.h.S(i,k);var n=d.optionsText,k="function"==typeof n?n(g[b]):"string"==typeof n?g[b][n]:k;if(k===o||k===l)k="";r.a.Ma(i,k);a.appendChild(i)}g=a.getElementsByTagName("OPTION");b=i=0;for(j=g.length;b<j;b++)0<=r.a.k(f,r.h.q(g[b]))&&(r.a.La(g[b],m),i++);if(h)a.scrollTop=h;e&&"value"in d&&D(a,r.a.d(d.value),m)}}};r.c.options.la="__ko.optionValueDomData__";
r.c.selectedOptions={Da:function(a){for(var b=[],a=a.childNodes,d=0,e=a.length;d<e;d++){var f=a[d];"OPTION"==f.tagName&&f.selected&&b.push(r.h.q(f))}return b},init:function(a,b,d){r.a.s(a,"change",function(){var a=b();r.P(a)?a(r.c.selectedOptions.Da(this)):(a=d(),a._ko_property_writers&&a._ko_property_writers.value&&a._ko_property_writers.value(r.c.selectedOptions.Da(this)))})},update:function(a,b){"SELECT"!=a.tagName&&c(Error("values binding applies only to SELECT elements"));var d=r.a.d(b());if(d&&
"number"==typeof d.length)for(var e=a.childNodes,f=0,h=e.length;f<h;f++){var g=e[f];"OPTION"==g.tagName&&r.a.La(g,0<=r.a.k(d,r.h.q(g)))}}};r.c.text={update:function(a,b){r.a.Ma(a,b())}};r.c.html={init:function(){return{controlsDescendantBindings:m}},update:function(a,b){var d=r.a.d(b());r.a.Z(a,d)}};r.c.css={update:function(a,b){var d=r.a.d(b()||{}),e;for(e in d)if("string"==typeof e){var f=r.a.d(d[e]);r.a.Qa(a,e,f)}}};
r.c.style={update:function(a,b){var d=r.a.d(b()||{}),e;for(e in d)if("string"==typeof e){var f=r.a.d(d[e]);a.style[e]=f||""}}};r.c.uniqueName={init:function(a,b){if(b())a.name="ko_unique_"+ ++r.c.uniqueName.Za,(r.a.ob||r.a.pb)&&a.mergeAttributes(document.createElement("<input name='"+a.name+"'/>"),p)}};r.c.uniqueName.Za=0;
r.c.checked={init:function(a,b,d){r.a.s(a,"click",function(){var e;if("checkbox"==a.type)e=a.checked;else if("radio"==a.type&&a.checked)e=a.value;else return;var f=b();"checkbox"==a.type&&r.a.d(f)instanceof Array?(e=r.a.k(r.a.d(f),a.value),a.checked&&0>e?f.push(a.value):!a.checked&&0<=e&&f.splice(e,1)):r.P(f)?f()!==e&&f(e):(f=d(),f._ko_property_writers&&f._ko_property_writers.checked&&f._ko_property_writers.checked(e))});"radio"==a.type&&!a.name&&r.c.uniqueName.init(a,function(){return m})},update:function(a,
b){var d=r.a.d(b());if("checkbox"==a.type)a.checked=d instanceof Array?0<=r.a.k(d,a.value):d;else if("radio"==a.type)a.checked=a.value==d}};r.c.attr={update:function(a,b){var d=r.a.d(b())||{},e;for(e in d)if("string"==typeof e){var f=r.a.d(d[e]);f===p||f===o||f===l?a.removeAttribute(e):a.setAttribute(e,f.toString())}}};
r.c.hasfocus={init:function(a,b,d){function e(a){var e=b();a!=r.a.d(e)&&(r.P(e)?e(a):(e=d(),e._ko_property_writers&&e._ko_property_writers.hasfocus&&e._ko_property_writers.hasfocus(a)))}r.a.s(a,"focus",function(){e(m)});r.a.s(a,"focusin",function(){e(m)});r.a.s(a,"blur",function(){e(p)});r.a.s(a,"focusout",function(){e(p)})},update:function(a,b){var d=r.a.d(b());d?a.focus():a.blur();r.a.sa(a,d?"focusin":"focusout")}};
r.c["with"]={o:function(a){return function(){var b=a();return{"if":b,data:b,templateEngine:r.p.M}}},init:function(a,b){return r.c.template.init(a,r.c["with"].o(b))},update:function(a,b,d,e,f){return r.c.template.update(a,r.c["with"].o(b),d,e,f)}};r.j.D["with"]=p;r.f.C["with"]=m;r.c["if"]={o:function(a){return function(){return{"if":a(),templateEngine:r.p.M}}},init:function(a,b){return r.c.template.init(a,r.c["if"].o(b))},update:function(a,b,d,e,f){return r.c.template.update(a,r.c["if"].o(b),d,e,f)}};
r.j.D["if"]=p;r.f.C["if"]=m;r.c.ifnot={o:function(a){return function(){return{ifnot:a(),templateEngine:r.p.M}}},init:function(a,b){return r.c.template.init(a,r.c.ifnot.o(b))},update:function(a,b,d,e,f){return r.c.template.update(a,r.c.ifnot.o(b),d,e,f)}};r.j.D.ifnot=p;r.f.C.ifnot=m;
r.c.foreach={o:function(a){return function(){var b=r.a.d(a());return!b||"number"==typeof b.length?{foreach:b,templateEngine:r.p.M}:{foreach:b.data,includeDestroyed:b.includeDestroyed,afterAdd:b.afterAdd,beforeRemove:b.beforeRemove,afterRender:b.afterRender,templateEngine:r.p.M}}},init:function(a,b){return r.c.template.init(a,r.c.foreach.o(b))},update:function(a,b,d,e,f){return r.c.template.update(a,r.c.foreach.o(b),d,e,f)}};r.j.D.foreach=p;r.f.C.foreach=m;r.b("ko.allowedVirtualElementBindings",r.f.C);
r.t=function(){};r.t.prototype.renderTemplateSource=function(){c("Override renderTemplateSource")};r.t.prototype.createJavaScriptEvaluatorBlock=function(){c("Override createJavaScriptEvaluatorBlock")};r.t.prototype.makeTemplateSource=function(a){if("string"==typeof a){var b=document.getElementById(a);b||c(Error("Cannot find template with ID "+a));return new r.m.g(b)}if(1==a.nodeType||8==a.nodeType)return new r.m.I(a);c(Error("Unknown template type: "+a))};
r.t.prototype.renderTemplate=function(a,b,d){return this.renderTemplateSource(this.makeTemplateSource(a),b,d)};r.t.prototype.isTemplateRewritten=function(a){return this.allowTemplateRewriting===p?m:this.W&&this.W[a]?m:this.makeTemplateSource(a).data("isRewritten")};r.t.prototype.rewriteTemplate=function(a,b){var d=this.makeTemplateSource(a),e=b(d.text());d.text(e);d.data("isRewritten",m);if("string"==typeof a)this.W=this.W||{},this.W[a]=m};r.b("ko.templateEngine",r.t);
r.$=function(){function a(a,b,d){for(var a=r.j.Y(a),g=r.j.D,i=0;i<a.length;i++){var j=a[i].key;if(g.hasOwnProperty(j)){var k=g[j];"function"===typeof k?(j=k(a[i].value))&&c(Error(j)):k||c(Error("This template engine does not support the '"+j+"' binding within its templates"))}}a="ko.templateRewriting.applyMemoizedBindingsToNextSibling(function() { return (function() { return { "+r.j.ia(a)+" } })() })";return d.createJavaScriptEvaluatorBlock(a)+b}var b=/(<[a-z]+\d*(\s+(?!data-bind=)[a-z0-9\-]+(=(\"[^\"]*\"|\'[^\']*\'))?)*\s+)data-bind=(["'])([\s\S]*?)\5/gi,
d=/<\!--\s*ko\b\s*([\s\S]*?)\s*--\>/g;return{gb:function(a,b){b.isTemplateRewritten(a)||b.rewriteTemplate(a,function(a){return r.$.ub(a,b)})},ub:function(e,f){return e.replace(b,function(b,e,d,j,k,n,t){return a(t,e,f)}).replace(d,function(b,e){return a(e,"<\!-- ko --\>",f)})},Ua:function(a){return r.r.ka(function(b,d){b.nextSibling&&r.xa(b.nextSibling,a,d)})}}}();r.b("ko.templateRewriting",r.$);r.b("ko.templateRewriting.applyMemoizedBindingsToNextSibling",r.$.Ua);r.m={};r.m.g=function(a){this.g=a};
r.m.g.prototype.text=function(){if(0==arguments.length)return"script"==this.g.tagName.toLowerCase()?this.g.text:this.g.innerHTML;var a=arguments[0];"script"==this.g.tagName.toLowerCase()?this.g.text=a:r.a.Z(this.g,a)};r.m.g.prototype.data=function(a){if(1===arguments.length)return r.a.e.get(this.g,"templateSourceData_"+a);r.a.e.set(this.g,"templateSourceData_"+a,arguments[1])};r.m.I=function(a){this.g=a};r.m.I.prototype=new r.m.g;
r.m.I.prototype.text=function(){if(0==arguments.length)return r.a.e.get(this.g,"__ko_anon_template__");r.a.e.set(this.g,"__ko_anon_template__",arguments[0])};r.b("ko.templateSources",r.m);r.b("ko.templateSources.domElement",r.m.g);r.b("ko.templateSources.anonymousTemplate",r.m.I);
(function(){function a(a,b,d){for(var g=0;node=a[g];g++)node.parentNode===b&&(1===node.nodeType||8===node.nodeType)&&d(node)}function b(a,b,h,g,i){var i=i||{},j=i.templateEngine||d;r.$.gb(h,j);h=j.renderTemplate(h,g,i);("number"!=typeof h.length||0<h.length&&"number"!=typeof h[0].nodeType)&&c("Template engine must return an array of DOM nodes");j=p;switch(b){case "replaceChildren":r.f.oa(a,h);j=m;break;case "replaceNode":r.a.Ja(a,h);j=m;break;case "ignoreTargetNode":break;default:c(Error("Unknown renderMode: "+
b))}j&&(r.ua(h,g),i.afterRender&&i.afterRender(h,g.$data));return h}var d;r.pa=function(a){a!=l&&!(a instanceof r.t)&&c("templateEngine must inherit from ko.templateEngine");d=a};r.ua=function(b,d){var h=r.a.J([],b),g=0<b.length?b[0].parentNode:o;a(h,g,function(a){r.wa(d,a)});a(h,g,function(a){r.r.Sa(a,[d])})};r.na=function(a,f,h,g,i){h=h||{};(h.templateEngine||d)==l&&c("Set a template engine before calling renderTemplate");i=i||"replaceChildren";if(g){var j=g.nodeType?g:0<g.length?g[0]:o;return new r.i(function(){var d=
f&&f instanceof r.K?f:new r.K(r.a.d(f)),n="function"==typeof a?a(d.$data):a,d=b(g,i,n,d,h);"replaceNode"==i&&(g=d,j=g.nodeType?g:0<g.length?g[0]:o)},o,{disposeWhen:function(){return!j||!r.a.ga(j)},disposeWhenNodeIsRemoved:j&&"replaceNode"==i?j.parentNode:j})}return r.r.ka(function(b){r.na(a,f,h,b,"replaceNode")})};r.Ab=function(a,d,h,g,i){function j(a,b){var d=k(a);r.ua(b,d);h.afterRender&&h.afterRender(b,d.$data)}function k(a){return i.createChildContext(r.a.d(a))}return new r.i(function(){var i=
r.a.d(d)||[];"undefined"==typeof i.length&&(i=[i]);i=r.a.aa(i,function(a){return h.includeDestroyed||a===l||a===o||!r.a.d(a._destroy)});r.a.Ka(g,i,function(d){var f="function"==typeof a?a(d):a;return b(o,"ignoreTargetNode",f,k(d),h)},h,j)},o,{disposeWhenNodeIsRemoved:g})};r.c.template={init:function(a,b){var d=r.a.d(b());"string"!=typeof d&&!d.name&&1==a.nodeType&&((new r.m.I(a)).text(a.innerHTML),r.a.U(a));return{controlsDescendantBindings:m}},update:function(a,b,d,g,i){b=r.a.d(b());g=m;"string"==
typeof b?d=b:(d=b.name,"if"in b&&(g=g&&r.a.d(b["if"])),"ifnot"in b&&(g=g&&!r.a.d(b.ifnot)));var j=o;"object"===typeof b&&"foreach"in b?j=r.Ab(d||a,g&&b.foreach||[],b,a,i):g?(i="object"==typeof b&&"data"in b?i.createChildContext(r.a.d(b.data)):i,j=r.na(d||a,i,b,a)):r.f.ha(a);i=j;(b=r.a.e.get(a,"__ko__templateSubscriptionDomDataKey__"))&&"function"==typeof b.v&&b.v();r.a.e.set(a,"__ko__templateSubscriptionDomDataKey__",i)}};r.j.D.template=function(a){a=r.j.Y(a);return 1==a.length&&a[0].unknown?o:r.j.rb(a,
"name")?o:"This template engine does not support anonymous templates nested within its templates"};r.f.C.template=m})();r.b("ko.setTemplateEngine",r.pa);r.b("ko.renderTemplate",r.na);
r.a.N=function(a,b,d){if(d===l)return r.a.N(a,b,1)||r.a.N(a,b,10)||r.a.N(a,b,Number.MAX_VALUE);for(var a=a||[],b=b||[],e=a,f=b,h=[],g=0;g<=f.length;g++)h[g]=[];for(var g=0,i=Math.min(e.length,d);g<=i;g++)h[0][g]=g;g=1;for(i=Math.min(f.length,d);g<=i;g++)h[g][0]=g;for(var i=e.length,j,k=f.length,g=1;g<=i;g++){j=Math.max(1,g-d);for(var n=Math.min(k,g+d);j<=n;j++)h[j][g]=e[g-1]===f[j-1]?h[j-1][g-1]:Math.min(h[j-1][g]===l?Number.MAX_VALUE:h[j-1][g]+1,h[j][g-1]===l?Number.MAX_VALUE:h[j][g-1]+1)}d=a.length;
e=b.length;f=[];g=h[e][d];if(g===l)h=o;else{for(;0<d||0<e;){i=h[e][d];k=0<e?h[e-1][d]:g+1;n=0<d?h[e][d-1]:g+1;j=0<e&&0<d?h[e-1][d-1]:g+1;if(k===l||k<i-1)k=g+1;if(n===l||n<i-1)n=g+1;j<i-1&&(j=g+1);k<=n&&k<j?(f.push({status:"added",value:b[e-1]}),e--):(n<k&&n<j?f.push({status:"deleted",value:a[d-1]}):(f.push({status:"retained",value:a[d-1]}),e--),d--)}h=f.reverse()}return h};r.b("ko.utils.compareArrays",r.a.N);
(function(){function a(a){if(2<a.length){for(var b=a[0],f=a[a.length-1],h=[b];b!==f;){b=b.nextSibling;if(!b)return;h.push(b)}Array.prototype.splice.apply(a,[0,a.length].concat(h))}}function b(b,e,f,h){var g=[],b=r.i(function(){var b=e(f)||[];0<g.length&&(a(g),r.a.Ja(g,b),h&&h(f,b));g.splice(0,g.length);r.a.J(g,b)},o,{disposeWhenNodeIsRemoved:b,disposeWhen:function(){return 0==g.length||!r.a.ga(g[0])}});return{sb:g,i:b}}r.a.Ka=function(d,e,f,h,g){for(var e=e||[],h=h||{},i=r.a.e.get(d,"setDomNodeChildrenFromArrayMapping_lastMappingResult")===
l,j=r.a.e.get(d,"setDomNodeChildrenFromArrayMapping_lastMappingResult")||[],k=r.a.ba(j,function(a){return a.Va}),n=r.a.N(k,e),e=[],t=0,q=[],k=[],v=o,s=0,w=n.length;s<w;s++)switch(n[s].status){case "retained":var x=j[t];e.push(x);0<x.O.length&&(v=x.O[x.O.length-1]);t++;break;case "deleted":j[t].i.v();a(j[t].O);r.a.n(j[t].O,function(a){q.push({element:a,index:s,value:n[s].value});v=a});t++;break;case "added":var x=n[s].value,z=b(d,f,x,g),u=z.sb;e.push({Va:n[s].value,O:u,i:z.i});for(var z=0,y=u.length;z<
y;z++){var A=u[z];k.push({element:A,index:s,value:n[s].value});v==o?r.f.xb(d,A):r.f.mb(d,A,v);v=A}g&&g(x,u)}r.a.n(q,function(a){r.F(a.element)});f=p;if(!i){if(h.afterAdd)for(s=0;s<k.length;s++)h.afterAdd(k[s].element,k[s].index,k[s].value);if(h.beforeRemove){for(s=0;s<q.length;s++)h.beforeRemove(q[s].element,q[s].index,q[s].value);f=m}}f||r.a.n(q,function(a){r.removeNode(a.element)});r.a.e.set(d,"setDomNodeChildrenFromArrayMapping_lastMappingResult",e)}})();
r.b("ko.utils.setDomNodeChildrenFromArrayMapping",r.a.Ka);r.p=function(){this.allowTemplateRewriting=p};r.p.prototype=new r.t;r.p.prototype.renderTemplateSource=function(a){a=a.text();return r.a.ma(a)};r.p.M=new r.p;r.pa(r.p.M);r.b("ko.nativeTemplateEngine",r.p);
(function(){r.ja=function(){var a=this.qb=function(){if("undefined"==typeof jQuery||!jQuery.tmpl)return 0;try{if(0<=jQuery.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}();this.renderTemplateSource=function(d,e,f){f=f||{};2>a&&c(Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later."));var h=d.data("precompiled");h||(h=d.text()||"",h=jQuery.template(o,"{{ko_with $item.koBindingContext}}"+h+"{{/ko_with}}"),d.data("precompiled",h));
d=[e.$data];e=jQuery.extend({koBindingContext:e},f.templateOptions);e=jQuery.tmpl(h,d,e);e.appendTo(document.createElement("div"));jQuery.fragments={};return e};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+a+" })()) }}"};this.addTemplate=function(a,b){document.write("<script type='text/html' id='"+a+"'>"+b+"<\/script>")};if(0<a)jQuery.tmpl.tag.ko_code={open:"__.push($1 || '');"},jQuery.tmpl.tag.ko_with={open:"with($1) {",close:"} "}};r.ja.prototype=new r.t;
var a=new r.ja;0<a.qb&&r.pa(a);r.b("ko.jqueryTmplTemplateEngine",r.ja)})();
})(window);
/*
backbone-modelref.js 0.1.0
(c) 2011 Kevin Malakoff.
Backbone-ModelRef.js is freely distributable under the MIT license.
See the following for full license details:
https://github.com/kmalakoff/backbone-modelref/blob/master/LICENSE
Dependencies: Backbone.js and Underscore.js.
*/
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
return child;
};
if (!this.Backbone || !this.Backbone.Model) {
throw new Error('Backbone.ModelRef: Dependency alert! Backbone.js must be included before this file');
}
Backbone.ModelRef = (function() {
var MODEL_EVENTS_WHEN_LOADED, MODEL_EVENTS_WHEN_UNLOADED;
MODEL_EVENTS_WHEN_LOADED = ['reset', 'remove'];
MODEL_EVENTS_WHEN_UNLOADED = ['reset', 'add'];
function ModelRef(collection, model_id, cached_model) {
var event, _i, _j, _len, _len2;
this.collection = collection;
this.model_id = model_id;
this.cached_model = cached_model != null ? cached_model : null;
_.bindAll(this, '_checkForLoad', '_checkForUnload');
if (!this.collection) {
throw new Error("Backbone.ModelRef: collection is missing");
}
if (!(this.model_id || this.cached_model)) {
throw new Error("Backbone.ModelRef: model_id and cached_model missing");
}
if (this.collection.retain) {
this.collection.retain();
}
this.cached_model = this.cached_model || this.collection.get(this.model_id);
if (this.cached_model) {
for (_i = 0, _len = MODEL_EVENTS_WHEN_LOADED.length; _i < _len; _i++) {
event = MODEL_EVENTS_WHEN_LOADED[_i];
this.collection.bind(event, this._checkForUnload);
}
} else {
for (_j = 0, _len2 = MODEL_EVENTS_WHEN_UNLOADED.length; _j < _len2; _j++) {
event = MODEL_EVENTS_WHEN_UNLOADED[_j];
this.collection.bind(event, this._checkForLoad);
}
}
this.ref_count = 1;
}
ModelRef.prototype.retain = function() {
this.ref_count++;
return this;
};
ModelRef.prototype.release = function() {
var event, _i, _j, _len, _len2;
if (this.ref_count <= 0) {
throw new Error("Backbone.ModelRef.release(): ref count is corrupt");
}
this.ref_count--;
if (this.ref_count > 0) {
return;
}
if (this.cached_model) {
for (_i = 0, _len = MODEL_EVENTS_WHEN_LOADED.length; _i < _len; _i++) {
event = MODEL_EVENTS_WHEN_LOADED[_i];
this.collection.unbind(event, this._checkForUnload);
}
} else {
for (_j = 0, _len2 = MODEL_EVENTS_WHEN_UNLOADED.length; _j < _len2; _j++) {
event = MODEL_EVENTS_WHEN_UNLOADED[_j];
this.collection.unbind(event, this._checkForLoad);
}
}
if (this.collection.release) {
this.collection.release();
}
this.collection = null;
return this;
};
ModelRef.prototype.get = function(attribute_name) {
if (attribute_name !== 'id') {
throw new Error("Backbone.ModelRef.get(): only id is permitted");
}
if (this.cached_model && !this.cached_model.isNew()) {
this.model_id = this.cached_model.id;
}
return this.model_id;
};
ModelRef.prototype.getModel = function() {
if (this.cached_model && !this.cached_model.isNew()) {
this.model_id = this.cached_model.id;
}
if (this.cached_model) {
return this.cached_model;
}
return this.cached_model = this.collection.get(this.model_id);
};
ModelRef.prototype.isLoaded = function() {
var model;
model = this.getModel();
if (!model) {
return false;
}
if (model.isLoaded) {
return model.isLoaded();
} else {
return true;
}
};
ModelRef.prototype._checkForLoad = function() {
var event, model, _i, _j, _len, _len2;
model = this.collection.get(this.model_id);
if (!model) {
return;
}
if (this.cached_model) {
return;
}
for (_i = 0, _len = MODEL_EVENTS_WHEN_UNLOADED.length; _i < _len; _i++) {
event = MODEL_EVENTS_WHEN_UNLOADED[_i];
this.collection.unbind(event, this._checkForLoad);
}
for (_j = 0, _len2 = MODEL_EVENTS_WHEN_LOADED.length; _j < _len2; _j++) {
event = MODEL_EVENTS_WHEN_LOADED[_j];
this.collection.bind(event, this._checkForUnload);
}
this.cached_model = model;
return this.trigger('loaded', this.cached_model);
};
ModelRef.prototype._checkForUnload = function() {
var event, model, _i, _j, _len, _len2;
model = this.collection.get(this.model_id);
if (model) {
return;
}
if (!this.cached_model) {
return;
}
for (_i = 0, _len = MODEL_EVENTS_WHEN_LOADED.length; _i < _len; _i++) {
event = MODEL_EVENTS_WHEN_LOADED[_i];
this.collection.unbind(event, this._checkForUnload);
}
for (_j = 0, _len2 = MODEL_EVENTS_WHEN_UNLOADED.length; _j < _len2; _j++) {
event = MODEL_EVENTS_WHEN_UNLOADED[_j];
this.collection.bind(event, this._checkForLoad);
}
model = this.cached_model;
this.cached_model = null;
return this.trigger('unloaded', model);
};
return ModelRef;
})();
Backbone.ModelRef.VERSION = '0.1.0';
__extends(Backbone.ModelRef.prototype, Backbone.Events);
\ No newline at end of file
// Underscore.js 1.2.1
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore
(function() {
// Baseline setup
// --------------
// Establish the root object, `window` in the browser, or `global` on the server.
var root = this;
// Save the previous value of the `_` variable.
var previousUnderscore = root._;
// Establish the object that gets returned to break out of a loop iteration.
var breaker = {};
// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
// Create quick reference variables for speed access to core prototypes.
var slice = ArrayProto.slice,
unshift = ArrayProto.unshift,
toString = ObjProto.toString,
hasOwnProperty = ObjProto.hasOwnProperty;
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
var
nativeForEach = ArrayProto.forEach,
nativeMap = ArrayProto.map,
nativeReduce = ArrayProto.reduce,
nativeReduceRight = ArrayProto.reduceRight,
nativeFilter = ArrayProto.filter,
nativeEvery = ArrayProto.every,
nativeSome = ArrayProto.some,
nativeIndexOf = ArrayProto.indexOf,
nativeLastIndexOf = ArrayProto.lastIndexOf,
nativeIsArray = Array.isArray,
nativeKeys = Object.keys,
nativeBind = FuncProto.bind;
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) { return new wrapper(obj); };
// Export the Underscore object for **Node.js** and **"CommonJS"**, with
// backwards-compatibility for the old `require()` API. If we're not in
// CommonJS, add `_` to the global object.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else if (typeof define === 'function' && define.amd) {
// Register as a named module with AMD.
define('underscore', function() {
return _;
});
} else {
// Exported as a string, for Closure Compiler "advanced" mode.
root['_'] = _;
}
// Current version.
_.VERSION = '1.2.1';
// Collection Functions
// --------------------
// The cornerstone, an `each` implementation, aka `forEach`.
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
}
};
// Return the results of applying the iterator to each element.
// Delegates to **ECMAScript 5**'s native `map` if available.
_.map = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
each(obj, function(value, index, list) {
results[results.length] = iterator.call(context, value, index, list);
});
return results;
};
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
var initial = memo !== void 0;
if (obj == null) obj = [];
if (nativeReduce && obj.reduce === nativeReduce) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
each(obj, function(value, index, list) {
if (!initial) {
memo = value;
initial = true;
} else {
memo = iterator.call(context, memo, value, index, list);
}
});
if (!initial) throw new TypeError("Reduce of empty array with no initial value");
return memo;
};
// The right-associative version of reduce, also known as `foldr`.
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
if (obj == null) obj = [];
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if (context) iterator = _.bind(iterator, context);
return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
}
var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
return _.reduce(reversed, iterator, memo, context);
};
// Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, iterator, context) {
var result;
any(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) {
result = value;
return true;
}
});
return result;
};
// Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`.
_.filter = _.select = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
each(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
// Return all the elements for which a truth test fails.
_.reject = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
each(obj, function(value, index, list) {
if (!iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
// Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
_.every = _.all = function(obj, iterator, context) {
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
each(obj, function(value, index, list) {
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
});
return result;
};
// Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`.
var any = _.some = _.any = function(obj, iterator, context) {
iterator = iterator || _.identity;
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
each(obj, function(value, index, list) {
if (result |= iterator.call(context, value, index, list)) return breaker;
});
return !!result;
};
// Determine if a given value is included in the array or object using `===`.
// Aliased as `contains`.
_.include = _.contains = function(obj, target) {
var found = false;
if (obj == null) return found;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
found = any(obj, function(value) {
if (value === target) return true;
});
return found;
};
// Invoke a method (with arguments) on every item in a collection.
_.invoke = function(obj, method) {
var args = slice.call(arguments, 2);
return _.map(obj, function(value) {
return (method.call ? method || value : value[method]).apply(value, args);
});
};
// Convenience version of a common use case of `map`: fetching a property.
_.pluck = function(obj, key) {
return _.map(obj, function(value){ return value[key]; });
};
// Return the maximum element or (element-based computation).
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return -Infinity;
var result = {computed : -Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed >= result.computed && (result = {value : value, computed : computed});
});
return result.value;
};
// Return the minimum element (or element-based computation).
_.min = function(obj, iterator, context) {
if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return Infinity;
var result = {computed : Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed < result.computed && (result = {value : value, computed : computed});
});
return result.value;
};
// Shuffle an array.
_.shuffle = function(obj) {
var shuffled = [], rand;
each(obj, function(value, index, list) {
if (index == 0) {
shuffled[0] = value;
} else {
rand = Math.floor(Math.random() * (index + 1));
shuffled[index] = shuffled[rand];
shuffled[rand] = value;
}
});
return shuffled;
};
// Sort the object's values by a criterion produced by an iterator.
_.sortBy = function(obj, iterator, context) {
return _.pluck(_.map(obj, function(value, index, list) {
return {
value : value,
criteria : iterator.call(context, value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
}), 'value');
};
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = function(obj, val) {
var result = {};
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
each(obj, function(value, index) {
var key = iterator(value, index);
(result[key] || (result[key] = [])).push(value);
});
return result;
};
// Use a comparator function to figure out at what index an object should
// be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iterator) {
iterator || (iterator = _.identity);
var low = 0, high = array.length;
while (low < high) {
var mid = (low + high) >> 1;
iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
}
return low;
};
// Safely convert anything iterable into a real, live array.
_.toArray = function(iterable) {
if (!iterable) return [];
if (iterable.toArray) return iterable.toArray();
if (_.isArray(iterable)) return slice.call(iterable);
if (_.isArguments(iterable)) return slice.call(iterable);
return _.values(iterable);
};
// Return the number of elements in an object.
_.size = function(obj) {
return _.toArray(obj).length;
};
// Array Functions
// ---------------
// Get the first element of an array. Passing **n** will return the first N
// values in the array. Aliased as `head`. The **guard** check allows it to work
// with `_.map`.
_.first = _.head = function(array, n, guard) {
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
};
// Returns everything but the last entry of the array. Especcialy useful on
// the arguments object. Passing **n** will return all the values in
// the array, excluding the last N. The **guard** check allows it to work with
// `_.map`.
_.initial = function(array, n, guard) {
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
};
// Get the last element of an array. Passing **n** will return the last N
// values in the array. The **guard** check allows it to work with `_.map`.
_.last = function(array, n, guard) {
return (n != null) && !guard ? slice.call(array, array.length - n) : array[array.length - 1];
};
// Returns everything but the first entry of the array. Aliased as `tail`.
// Especially useful on the arguments object. Passing an **index** will return
// the rest of the values in the array from that index onward. The **guard**
// check allows it to work with `_.map`.
_.rest = _.tail = function(array, index, guard) {
return slice.call(array, (index == null) || guard ? 1 : index);
};
// Trim out all falsy values from an array.
_.compact = function(array) {
return _.filter(array, function(value){ return !!value; });
};
// Return a completely flattened version of an array.
_.flatten = function(array, shallow) {
return _.reduce(array, function(memo, value) {
if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
memo[memo.length] = value;
return memo;
}, []);
};
// Return a version of the array that does not contain the specified value(s).
_.without = function(array) {
return _.difference(array, slice.call(arguments, 1));
};
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
_.uniq = _.unique = function(array, isSorted, iterator) {
var initial = iterator ? _.map(array, iterator) : array;
var result = [];
_.reduce(initial, function(memo, el, i) {
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
memo[memo.length] = el;
result[result.length] = array[i];
}
return memo;
}, []);
return result;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
return _.uniq(_.flatten(arguments, true));
};
// Produce an array that contains every item shared between all the
// passed-in arrays. (Aliased as "intersect" for back-compat.)
_.intersection = _.intersect = function(array) {
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
return _.indexOf(other, item) >= 0;
});
});
};
// Take the difference between one array and another.
// Only the elements present in just the first array will remain.
_.difference = function(array, other) {
return _.filter(array, function(value){ return !_.include(other, value); });
};
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
var args = slice.call(arguments);
var length = _.max(_.pluck(args, 'length'));
var results = new Array(length);
for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
return results;
};
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
// we need this function. Return the position of the first occurrence of an
// item in an array, or -1 if the item is not included in the array.
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
var i, l;
if (isSorted) {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
return -1;
};
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_.lastIndexOf = function(array, item) {
if (array == null) return -1;
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
var i = array.length;
while (i--) if (array[i] === item) return i;
return -1;
};
// Generate an integer Array containing an arithmetic progression. A port of
// the native Python `range()` function. See
// [the Python documentation](http://docs.python.org/library/functions.html#range).
_.range = function(start, stop, step) {
if (arguments.length <= 1) {
stop = start || 0;
start = 0;
}
step = arguments[2] || 1;
var len = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
var range = new Array(len);
while(idx < len) {
range[idx++] = start;
start += step;
}
return range;
};
// Function (ahem) Functions
// ------------------
// Reusable constructor function for prototype setting.
var ctor = function(){};
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Binding with arguments is also known as `curry`.
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
// We check for `func.bind` first, to fail fast when `func` is undefined.
_.bind = function bind(func, context) {
var bound, args;
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError;
args = slice.call(arguments, 2);
return bound = function() {
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
ctor.prototype = func.prototype;
var self = new ctor;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
};
};
// Bind all of an object's methods to that object. Useful for ensuring that
// all callbacks defined on an object belong to it.
_.bindAll = function(obj) {
var funcs = slice.call(arguments, 1);
if (funcs.length == 0) funcs = _.functions(obj);
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
return obj;
};
// Memoize an expensive function by storing its results.
_.memoize = function(func, hasher) {
var memo = {};
hasher || (hasher = _.identity);
return function() {
var key = hasher.apply(this, arguments);
return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
};
};
// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
_.delay = function(func, wait) {
var args = slice.call(arguments, 2);
return setTimeout(function(){ return func.apply(func, args); }, wait);
};
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_.defer = function(func) {
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
};
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time.
_.throttle = function(func, wait) {
var timeout, context, args, throttling, finishThrottle;
finishThrottle = _.debounce(function(){ throttling = false; }, wait);
return function() {
context = this; args = arguments;
var throttler = function() {
timeout = null;
func.apply(context, args);
finishThrottle();
};
if (!timeout) timeout = setTimeout(throttler, wait);
if (!throttling) func.apply(context, args);
if (finishThrottle) finishThrottle();
throttling = true;
};
};
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds.
_.debounce = function(func, wait) {
var timeout;
return function() {
var context = this, args = arguments;
var throttler = function() {
timeout = null;
func.apply(context, args);
};
clearTimeout(timeout);
timeout = setTimeout(throttler, wait);
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = function(func) {
var ran = false, memo;
return function() {
if (ran) return memo;
ran = true;
return memo = func.apply(this, arguments);
};
};
// Returns the first function passed as an argument to the second,
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
_.wrap = function(func, wrapper) {
return function() {
var args = [func].concat(slice.call(arguments));
return wrapper.apply(this, args);
};
};
// Returns a function that is the composition of a list of functions, each
// consuming the return value of the function that follows.
_.compose = function() {
var funcs = slice.call(arguments);
return function() {
var args = slice.call(arguments);
for (var i = funcs.length - 1; i >= 0; i--) {
args = [funcs[i].apply(this, args)];
}
return args[0];
};
};
// Returns a function that will only be executed after being called N times.
_.after = function(times, func) {
return function() {
if (--times < 1) { return func.apply(this, arguments); }
};
};
// Object Functions
// ----------------
// Retrieve the names of an object's properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = nativeKeys || function(obj) {
if (obj !== Object(obj)) throw new TypeError('Invalid object');
var keys = [];
for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
return keys;
};
// Retrieve the values of an object's properties.
_.values = function(obj) {
return _.map(obj, _.identity);
};
// Return a sorted list of the function names available on the object.
// Aliased as `methods`
_.functions = _.methods = function(obj) {
var names = [];
for (var key in obj) {
if (_.isFunction(obj[key])) names.push(key);
}
return names.sort();
};
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
if (source[prop] !== void 0) obj[prop] = source[prop];
}
});
return obj;
};
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
if (obj[prop] == null) obj[prop] = source[prop];
}
});
return obj;
};
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
// Invokes interceptor with the obj, and then returns obj.
// The primary purpose of this method is to "tap into" a method chain, in
// order to perform operations on intermediate results within the chain.
_.tap = function(obj, interceptor) {
interceptor(obj);
return obj;
};
// Internal recursive comparison function.
function eq(a, b, stack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
if (a === b) return a !== 0 || 1 / a == 1 / b;
// A strict comparison is necessary because `null == undefined`.
if ((a == null) || (b == null)) return a === b;
// Unwrap any wrapped objects.
if (a._chain) a = a._wrapped;
if (b._chain) b = b._wrapped;
// Invoke a custom `isEqual` method if one is provided.
if (_.isFunction(a.isEqual)) return a.isEqual(b);
if (_.isFunction(b.isEqual)) return b.isEqual(a);
// Compare object types.
var typeA = typeof a;
if (typeA != typeof b) return false;
// Optimization; ensure that both values are truthy or falsy.
if (!a != !b) return false;
// `NaN` values are equal.
if (_.isNaN(a)) return _.isNaN(b);
// Compare string objects by value.
var isStringA = _.isString(a), isStringB = _.isString(b);
if (isStringA || isStringB) return isStringA && isStringB && String(a) == String(b);
// Compare number objects by value.
var isNumberA = _.isNumber(a), isNumberB = _.isNumber(b);
if (isNumberA || isNumberB) return isNumberA && isNumberB && +a == +b;
// Compare boolean objects by value. The value of `true` is 1; the value of `false` is 0.
var isBooleanA = _.isBoolean(a), isBooleanB = _.isBoolean(b);
if (isBooleanA || isBooleanB) return isBooleanA && isBooleanB && +a == +b;
// Compare dates by their millisecond values.
var isDateA = _.isDate(a), isDateB = _.isDate(b);
if (isDateA || isDateB) return isDateA && isDateB && a.getTime() == b.getTime();
// Compare RegExps by their source patterns and flags.
var isRegExpA = _.isRegExp(a), isRegExpB = _.isRegExp(b);
if (isRegExpA || isRegExpB) {
// Ensure commutative equality for RegExps.
return isRegExpA && isRegExpB &&
a.source == b.source &&
a.global == b.global &&
a.multiline == b.multiline &&
a.ignoreCase == b.ignoreCase;
}
// Ensure that both values are objects.
if (typeA != 'object') return false;
// Arrays or Arraylikes with different lengths are not equal.
if (a.length !== b.length) return false;
// Objects with different constructors are not equal.
if (a.constructor !== b.constructor) return false;
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
var length = stack.length;
while (length--) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if (stack[length] == a) return true;
}
// Add the first object to the stack of traversed objects.
stack.push(a);
var size = 0, result = true;
// Deep compare objects.
for (var key in a) {
if (hasOwnProperty.call(a, key)) {
// Count the expected number of properties.
size++;
// Deep compare each member.
if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
}
}
// Ensure that both objects contain the same number of properties.
if (result) {
for (key in b) {
if (hasOwnProperty.call(b, key) && !size--) break;
}
result = !size;
}
// Remove the first object from the stack of traversed objects.
stack.pop();
return result;
}
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
return eq(a, b, []);
};
// Is a given array, string, or object empty?
// An "empty" object has no enumerable own-properties.
_.isEmpty = function(obj) {
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
return true;
};
// Is a given value a DOM element?
_.isElement = function(obj) {
return !!(obj && obj.nodeType == 1);
};
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) == '[object Array]';
};
// Is a given variable an object?
_.isObject = function(obj) {
return obj === Object(obj);
};
// Is a given variable an arguments object?
if (toString.call(arguments) == '[object Arguments]') {
_.isArguments = function(obj) {
return toString.call(obj) == '[object Arguments]';
};
} else {
_.isArguments = function(obj) {
return !!(obj && hasOwnProperty.call(obj, 'callee'));
};
}
// Is a given value a function?
_.isFunction = function(obj) {
return toString.call(obj) == '[object Function]';
};
// Is a given value a string?
_.isString = function(obj) {
return toString.call(obj) == '[object String]';
};
// Is a given value a number?
_.isNumber = function(obj) {
return toString.call(obj) == '[object Number]';
};
// Is the given value `NaN`?
_.isNaN = function(obj) {
// `NaN` is the only value for which `===` is not reflexive.
return obj !== obj;
};
// Is a given value a boolean?
_.isBoolean = function(obj) {
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
};
// Is a given value a date?
_.isDate = function(obj) {
return toString.call(obj) == '[object Date]';
};
// Is the given value a regular expression?
_.isRegExp = function(obj) {
return toString.call(obj) == '[object RegExp]';
};
// Is a given value equal to null?
_.isNull = function(obj) {
return obj === null;
};
// Is a given variable undefined?
_.isUndefined = function(obj) {
return obj === void 0;
};
// Utility Functions
// -----------------
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
// previous owner. Returns a reference to the Underscore object.
_.noConflict = function() {
root._ = previousUnderscore;
return this;
};
// Keep the identity function around for default iterators.
_.identity = function(value) {
return value;
};
// Run a function **n** times.
_.times = function (n, iterator, context) {
for (var i = 0; i < n; i++) iterator.call(context, i);
};
// Escape a string for HTML interpolation.
_.escape = function(string) {
return (''+string).replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
};
// Add your own custom functions to the Underscore object, ensuring that
// they're correctly added to the OOP wrapper as well.
_.mixin = function(obj) {
each(_.functions(obj), function(name){
addToWrapper(name, _[name] = obj[name]);
});
};
// Generate a unique integer id (unique within the entire client session).
// Useful for temporary DOM ids.
var idCounter = 0;
_.uniqueId = function(prefix) {
var id = idCounter++;
return prefix ? prefix + id : id;
};
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(str, data) {
var c = _.templateSettings;
var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
'with(obj||{}){__p.push(\'' +
str.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
.replace(c.escape, function(match, code) {
return "',_.escape(" + code.replace(/\\'/g, "'") + "),'";
})
.replace(c.interpolate, function(match, code) {
return "'," + code.replace(/\\'/g, "'") + ",'";
})
.replace(c.evaluate || null, function(match, code) {
return "');" + code.replace(/\\'/g, "'")
.replace(/[\r\n\t]/g, ' ') + "__p.push('";
})
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
.replace(/\t/g, '\\t')
+ "');}return __p.join('');";
var func = new Function('obj', tmpl);
return data ? func(data) : func;
};
// The OOP Wrapper
// ---------------
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
var wrapper = function(obj) { this._wrapped = obj; };
// Expose `wrapper.prototype` as `_.prototype`
_.prototype = wrapper.prototype;
// Helper function to continue chaining intermediate results.
var result = function(obj, chain) {
return chain ? _(obj).chain() : obj;
};
// A method to easily add functions to the OOP wrapper.
var addToWrapper = function(name, func) {
wrapper.prototype[name] = function() {
var args = slice.call(arguments);
unshift.call(args, this._wrapped);
return result(func.apply(_, args), this._chain);
};
};
// Add all of the Underscore functions to the wrapper object.
_.mixin(_);
// Add all mutator Array functions to the wrapper.
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = ArrayProto[name];
wrapper.prototype[name] = function() {
method.apply(this._wrapped, arguments);
return result(this._wrapped, this._chain);
};
});
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
wrapper.prototype[name] = function() {
return result(method.apply(this._wrapped, arguments), this._chain);
};
});
// Start chaining a wrapped Underscore object.
wrapper.prototype.chain = function() {
this._chain = true;
return this;
};
// Extracts the result from a wrapped and chained object.
wrapper.prototype.value = function() {
return this._wrapped;
};
})();
<!DOCTYPE html>
<html>
<!-- Support Localization -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<head>
<title>Knockback Demo: Todos</title>
<!-- Demo Dependencies -->
<script src="../vendor/json2.js"></script>
<script src="../vendor/jquery-1.7.min.js"></script>
<script src="../vendor/jquery.tmpl.min.js"></script>
<script src="../vendor/globalize/globalize.js"></script>
<script src="../vendor/globalize/globalize.culture.fr-FR.js"></script>
<script src="../vendor/globalize/globalize.culture.it-IT.js"></script>
<script src="../vendor/mColorPicker.min.js"></script>
<script type="text/javascript">
$.fn.mColorPicker.init.showLogo = false;
$.fn.mColorPicker.init.replace = false;
</script>
<!-- Knockback Dependencies -->
<script src="dependencies/underscore.js"></script>
<script src="dependencies/backbone.js"></script>
<script src="dependencies/optional/backbone-modelref.js"></script>
<script src="dependencies/knockout-2.0.0.js"></script>
<script src="dependencies/knockback.js"></script>
<!-- Demo Dependencies -->
<script src="../vendor/backbone-localstorage.js"></script>
<!-- The Demo -->
<link href="../css/todos.css" media="all" rel="stylesheet" type="text/css"/>
<script src="todos_locale_manager.js"></script>
<script src="todos_extended.js"></script>
</head>
<body>
<!-- Todo App Interface -->
<div id="todoapp">
<!-- Header and Settings Section -->
<div id="todo-header">
<div class="title"><h1>Todos</h1></div>
<div id="color-settings" data-bind="template: {name: 'priority-setting-template', foreach: window.settings_view_model.priority_settings}"></div>
</div>
<!-- Create Todo Section -->
<div id="todo-create">
<div class="content">
<div id="create-todo">
<input id="new-todo" type="text" data-bind="value: create.input_text, placeholder: create.input_placeholder_text, event: {keyup: create.addTodo}"/>
<span class="ui-tooltip-top" style="display:none;" data-bind="text: create.input_tooltip_text"></span>
<div data-bind="template: {name: 'priority-swatch-picker-template', data: create}"></div>
</div>
</div>
</div>
<!-- Todos List Section -->
<div id="todo-list">
<div class="todo-list-sorting-wrapper-outer" data-bind="visible: todo_list.sort_visible">
<div class="todo-list-sorting-wrapper-inner">
<div id="todo-list-sorting" class="selection codestyle" data-bind="template: {name: 'option-template', foreach: todo_list.sorting_options, templateOptions: {selected_value: todo_list.selected_value} }"></div>
</div>
</div>
<ul class="todo-list" data-bind="template: {name: 'item-template', foreach: todo_list.todos}"></ul>
</div>
<!-- Stats Section -->
<div id="todo-stats">
<span class="todo-count" data-bind="text: stats.remaining_text"></span>
<span class="todo-clear"> <a href="#" data-bind="text: stats.clear_text, click: stats.onDestroyDone"></a></span>
</div>
<!-- Footer Section -->
<div id="todo-footer">
<ul id="instructions">
<li data-bind="text: footer.instructions_text"></li>
</ul>
<div id="todo-languages" class="selection codestyle" data-bind="template: {name: 'option-template', foreach: footer.language_options, templateOptions: {selected_value: footer.selected_value} }"></div>
</div>
</div>
<div id="credits">
Created by
<br />
<a href="http://jgn.me/">J&eacute;r&ocirc;me Gravel-Niquet</a>
<br />
<br />
Modified to use <a href="https://github.com/kmalakoff/knockback">Knockback.js</a> by
<br />
<a href="https://github.com/kmalakoff">Kevin Malakoff</a>
<br />
and
<br />
<a href="https://github.com/yuchi">Pier Paolo Ramon</a>
</div>
<!-- Templates -->
<script type="text/x-jquery-tmpl" id="item-template">
<li>
<div class="todo" data-bind="css: {done: done, done_enhanced: done, editing: edit_mode}">
<div class="display">
<input class="check" type="checkbox" data-bind="checked: done" />
<div data-bind="template: {name: 'priority-swatch-picker-template', data: $data}"></div>
<div class="todo-text" data-bind="text: text, dblclick: toggleEditMode"></div>
<div class="todo-done-text" data-bind="text: done_text"></div>
<div class="todo-destroy" data-bind="click: destroyTodo"></div>
</div>
<div class="edit">
<input class="todo-input" type="text" data-bind="value: text, event: {keyup: onEnterEndEdit}" />
</div>
</div>
</li>
</script>
<script type="text/x-jquery-tmpl" id="priority-setting-template">
<div class="priority-color-entry">
<div class="priority-text" data-bind="text: priority_text"></div>
<input data-bind="attr: {id: priority}, value: priority_color" class='priority-color-swatch colorpicker' data-text="hidden" data-hex="true"/>
</div>
</script>
<script type="text/x-jquery-tmpl" id="priority-swatch-picker-template">
<div class="priority-color-swatch todo create" data-bind="style: {background: priority_color}, click: onToggleTooltip">
<span class="priority-picker-tooltip ui-tooltip-top" data-bind="visible: tooltip_visible">
<div data-bind="template: {name: 'priority-picker-template', foreach: window.settings_view_model.priority_settings, templateOptions: {onSelectPriority: onSelectPriority} }"></div>
</span>
</div>
</script>
<script type="text/x-jquery-tmpl" id="priority-picker-template">
<div class="priority-color-entry">
<div class="priority-text" data-bind="text: priority_text"></div>
<div class='priority-color-swatch' data-bind="style: {background: priority_color}, click: $item.onSelectPriority"></div>
</div>
</script>
<script type="text/x-jquery-tmpl" id="option-template">
<div class="option"><input type="radio" data-bind="attr: {id: id, name: option_group}, value: id, checked: $item.selected_value"><label data-bind="attr: {for: id}, text: label"></label></div>
</script>
</body>
</html>
###
knockback-todos.js
(c) 2011 Kevin Malakoff.
Knockback-Todos is freely distributable under the MIT license.
See the following for full license details:
https:#github.com/kmalakoff/knockback-todos/blob/master/LICENSE
###
$(document).ready(->
###################################
# Knockback-powered enhancements - BEGIN
###################################
###################################
# Configure
# set the language
kb.locale_manager.setLocale('en')
kb.locale_change_observable = kb.triggeredObservable(kb.locale_manager, 'change') # use to register a localization dependency
# add a doubleclick and placeholder handlers to KO
ko.bindingHandlers.dblclick =
init: (element, value_accessor, all_bindings_accessor, view_model) ->
$(element).dblclick(ko.utils.unwrapObservable(value_accessor()))
ko.bindingHandlers.placeholder =
update: (element, value_accessor, all_bindings_accessor, view_model) ->
$(element).attr('placeholder', ko.utils.unwrapObservable(value_accessor()))
# ko1.2.1 compatibility with 1.3
if _.isUndefined(ko.templateSources)
_ko_native_apply_bindings = ko.applyBindings
ko.applyBindings = (view_model, element) ->
view_model['$data'] = view_model
_ko_native_apply_bindings(view_model, element)
###################################
# Model: http://en.wikipedia.org/wiki/Model_view_controller
# ORM: http://en.wikipedia.org/wiki/Object-relational_mapping
###################################
# Settings
class PrioritySetting extends Backbone.Model
class PrioritiesSettingList extends Backbone.Collection
model: PrioritySetting
localStorage: new Store("kb_priorities") # Save all of the todo items under the `"kb_priorities"` namespace.
priorities = new PrioritiesSettingList()
###################################
# MVVM: http://en.wikipedia.org/wiki/Model_View_ViewModel
###################################
# Localization
LanguageOptionViewModel = (locale) ->
@id = locale
@label = kb.locale_manager.localeToLabel(locale)
@option_group = 'lang'
@
# Settings
PrioritySettingsViewModel = (model) ->
@priority = model.get('id')
@priority_text = kb.observable(kb.locale_manager, {key: @priority})
@priority_color = kb.observable(model, {key: 'color'})
@
SettingsViewModel = (priority_settings) ->
@priority_settings = ko.observableArray(_.map(priority_settings, (model)-> return new PrioritySettingsViewModel(model)))
@getColorByPriority = (priority) ->
@createColorsDependency()
(return view_model.priority_color() if view_model.priority == priority) for view_model in @priority_settings()
return ''
@createColorsDependency = => view_model.priority_color() for view_model in @priority_settings()
@default_priority = ko.observable('medium')
@default_priority_color = ko.dependentObservable(=> return @getColorByPriority(@default_priority()))
@priorityToRank = (priority) ->
switch priority
when 'high' then return 0
when 'medium' then return 1
when 'low' then return 2
@
# Content
SortingOptionViewModel = (string_id) ->
@id = string_id
@label = kb.observable(kb.locale_manager, {key: string_id})
@option_group = 'list_sort'
@
###################################
# Knockback-powered enhancements - END
###################################
###################################
# Model: http://en.wikipedia.org/wiki/Model_view_controller
# ORM: http://en.wikipedia.org/wiki/Object-relational_mapping
###################################
# Todos
class Todo extends Backbone.Model
defaults: -> return {created_at: new Date()}
set: (attrs) ->
# note: this is to convert between Dates as JSON strings and Date objects. To automate this, take a look at Backbone.Articulation: https://github.com/kmalakoff/backbone-articulation
attrs['done_at'] = new Date(attrs['done_at']) if attrs and attrs.hasOwnProperty('done_at') and _.isString(attrs['done_at'])
attrs['created_at'] = new Date(attrs['created_at']) if attrs and attrs.hasOwnProperty('created_at') and _.isString(attrs['created_at'])
super
done: (done) ->
return !!@get('done_at') if arguments.length == 0
@save({done_at: if done then new Date() else null})
class TodoList extends Backbone.Collection
model: Todo
localStorage: new Store("kb_todos") # Save all of the todo items under the `"kb_todos"` namespace.
doneCount: -> @models.reduce(((prev,cur)-> return prev + if !!cur.get('done_at') then 1 else 0), 0)
remainingCount: -> @models.length - @doneCount()
allDone: -> return @filter((todo) -> return !!todo.get('done_at'))
todos = new TodoList()
todos.fetch()
###################################
# MVVM: http://en.wikipedia.org/wiki/Model_View_ViewModel
###################################
CreateTodoViewModel = ->
@input_text = ko.observable('')
@input_placeholder_text = kb.observable(kb.locale_manager, {key: 'placeholder_create'})
@input_tooltip_text = kb.observable(kb.locale_manager, {key: 'tooltip_create'})
@addTodo = (view_model, event) ->
text = @create.input_text()
return true if (!text || event.keyCode != 13)
todos.create({text: text, priority: window.settings_view_model.default_priority()})
@create.input_text('')
@priority_color = ko.dependentObservable(-> return window.settings_view_model.default_priority_color())
@tooltip_visible = ko.observable(false)
tooltip_visible = @tooltip_visible # closured for onSelectPriority
@onSelectPriority = (view_model, event) ->
event.stopPropagation()
tooltip_visible(false)
window.settings_view_model.default_priority(ko.utils.unwrapObservable(@priority))
@onToggleTooltip = => @tooltip_visible(!@tooltip_visible())
@
# Content
TodoViewModel = (model) ->
@text = kb.observable(model, {key: 'text', write: ((text) -> model.save({text: text}))}, this)
@edit_mode = ko.observable(false)
@toggleEditMode = => @edit_mode(!@edit_mode()) if not @done()
@onEnterEndEdit = (view_model, event) => @edit_mode(false) if (event.keyCode == 13)
@created_at = model.get('created_at')
@done = kb.observable(model, {key: 'done_at', read: (-> return model.done()), write: ((done) -> model.done(done)) }, this)
@done_at = kb.observable(model, {key: 'done_at', localizer: LongDateLocalizer})
@done_text = ko.dependentObservable(=>
done_at = @done_at() # ensure there is a dependency
return if !!done_at then return "#{kb.locale_manager.get('label_completed')}: #{done_at}" else ''
)
@priority_color = kb.observable(model, {key: 'priority', read: -> return window.settings_view_model.getColorByPriority(model.get('priority'))})
@tooltip_visible = ko.observable(false)
tooltip_visible = @tooltip_visible # closured for onSelectPriority
@onSelectPriority = (view_model, event) ->
event.stopPropagation()
tooltip_visible(false)
model.save({priority: ko.utils.unwrapObservable(@priority)})
@onToggleTooltip = => @tooltip_visible(!@tooltip_visible())
@destroyTodo = => model.destroy()
@
TodoListViewModel = (todos) ->
@todos = ko.observableArray([])
@sort_mode = ko.observable('label_text') # used to create a dependency
@sorting_options = [new SortingOptionViewModel('label_text'), new SortingOptionViewModel('label_created'), new SortingOptionViewModel('label_priority')]
@selected_value = ko.dependentObservable(
read: => return @sort_mode()
write: (new_mode) =>
@sort_mode(new_mode)
# update the collection observable's sorting function
switch new_mode
when 'label_text' then @collection_observable.sortAttribute('text')
when 'label_created' then @collection_observable.sortedIndex((models, model)-> return _.sortedIndex(models, model, (test) -> test.get('created_at').valueOf()))
when 'label_priority' then @collection_observable.sortedIndex((models, model)-> return _.sortedIndex(models, model, (test) -> window.settings_view_model.priorityToRank(test.get('priority'))))
owner: this
)
@collection_observable = kb.collectionObservable(todos, @todos, {view_model: TodoViewModel, sort_attribute: 'text'})
@sort_visible = ko.dependentObservable(=> @collection_observable().length)
@
FooterViewModel = (locales) ->
@instructions_text = kb.observable(kb.locale_manager, {key: 'instructions'})
@current_language = ko.observable(kb.locale_manager.getLocale()) # used to create a dependency
@language_options = ko.observableArray(_.map(locales, (locale) -> return new LanguageOptionViewModel(locale)))
@selected_value = ko.dependentObservable(
read: => return @current_language()
write: (new_locale) => kb.locale_manager.setLocale(new_locale); @current_language(new_locale)
owner: this
)
@
###################################
# Knockback-powered enhancements - BEGIN
###################################
# Stats Footer
StatsViewModel = (todos) ->
@co = kb.collectionObservable(todos)
@remaining_text_key = ko.dependentObservable(=> return if (@co.collection().remainingCount()==0) then null else (if (todos.remainingCount() == 1) then 'remaining_template_s' else 'remaining_template_pl'))
@remaining_text = kb.observable(kb.locale_manager, {key: @remaining_text_key, args: => @co.collection().remainingCount()})
@clear_text_key = ko.dependentObservable(=> return if (@co.collection().doneCount()==0) then null else (if (todos.doneCount() == 1) then 'remaining_template_s' else 'remaining_template_pl'))
@clear_text = kb.observable(kb.locale_manager, {key: @clear_text_key, args: => @co.collection().doneCount()})
@onDestroyDone = => model.destroy() for model in todos.allDone()
@
# set up and bind the application view model
window.settings_view_model = new SettingsViewModel([
new Backbone.ModelRef(priorities, 'high'),
new Backbone.ModelRef(priorities, 'medium'),
new Backbone.ModelRef(priorities, 'low')
])
app_view_model =
create: new CreateTodoViewModel()
todo_list: new TodoListViewModel(todos)
footer: new FooterViewModel(kb.locale_manager.getLocales())
stats: new StatsViewModel(todos)
ko.applyBindings(app_view_model, $('#todoapp')[0])
# Destroy when finished with the view models
# kb.vmRelease(window.settings_view_model)
# kb.vmRelease(app_view_model)
###################################
# Load the prioties late to show the dynamic nature of Knockback with Backbone.ModelRef
_.delay((->
priorities.fetch(
success: (collection) ->
collection.create({id:'high', color:'#bf30ff'}) if not collection.get('high')
collection.create({id:'medium', color:'#98acff'}) if not collection.get('medium')
collection.create({id:'low', color:'#38ff6a'}) if not collection.get('low')
)
# set up color pickers
$('.colorpicker').mColorPicker({imageFolder: '../css/images/'})
$('.colorpicker').bind('colorpicked', ->
model = priorities.get($(this).attr('id'))
model.save({color: $(this).val()}) if model
)
), 1000)
###################################
# Knockback-powered enhancements - END
###################################
)
\ No newline at end of file
/*
knockback-todos.js
(c) 2011 Kevin Malakoff.
Knockback-Todos is freely distributable under the MIT license.
See the following for full license details:
https:#github.com/kmalakoff/knockback-todos/blob/master/LICENSE
*/
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
return child;
}, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
$(document).ready(function() {
var CreateTodoViewModel, FooterViewModel, LanguageOptionViewModel, PrioritiesSettingList, PrioritySetting, PrioritySettingsViewModel, SettingsViewModel, SortingOptionViewModel, StatsViewModel, Todo, TodoList, TodoListViewModel, TodoViewModel, app_view_model, priorities, todos, _ko_native_apply_bindings;
kb.locale_manager.setLocale('en');
kb.locale_change_observable = kb.triggeredObservable(kb.locale_manager, 'change');
ko.bindingHandlers.dblclick = {
init: function(element, value_accessor, all_bindings_accessor, view_model) {
return $(element).dblclick(ko.utils.unwrapObservable(value_accessor()));
}
};
ko.bindingHandlers.placeholder = {
update: function(element, value_accessor, all_bindings_accessor, view_model) {
return $(element).attr('placeholder', ko.utils.unwrapObservable(value_accessor()));
}
};
if (_.isUndefined(ko.templateSources)) {
_ko_native_apply_bindings = ko.applyBindings;
ko.applyBindings = function(view_model, element) {
view_model['$data'] = view_model;
return _ko_native_apply_bindings(view_model, element);
};
}
PrioritySetting = (function() {
__extends(PrioritySetting, Backbone.Model);
function PrioritySetting() {
PrioritySetting.__super__.constructor.apply(this, arguments);
}
return PrioritySetting;
})();
PrioritiesSettingList = (function() {
__extends(PrioritiesSettingList, Backbone.Collection);
function PrioritiesSettingList() {
PrioritiesSettingList.__super__.constructor.apply(this, arguments);
}
PrioritiesSettingList.prototype.model = PrioritySetting;
PrioritiesSettingList.prototype.localStorage = new Store("kb_priorities");
return PrioritiesSettingList;
})();
priorities = new PrioritiesSettingList();
LanguageOptionViewModel = function(locale) {
this.id = locale;
this.label = kb.locale_manager.localeToLabel(locale);
this.option_group = 'lang';
return this;
};
PrioritySettingsViewModel = function(model) {
this.priority = model.get('id');
this.priority_text = kb.observable(kb.locale_manager, {
key: this.priority
});
this.priority_color = kb.observable(model, {
key: 'color'
});
return this;
};
SettingsViewModel = function(priority_settings) {
this.priority_settings = ko.observableArray(_.map(priority_settings, function(model) {
return new PrioritySettingsViewModel(model);
}));
this.getColorByPriority = function(priority) {
var view_model, _i, _len, _ref;
this.createColorsDependency();
_ref = this.priority_settings();
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
view_model = _ref[_i];
if (view_model.priority === priority) {
return view_model.priority_color();
}
}
return '';
};
this.createColorsDependency = __bind(function() {
var view_model, _i, _len, _ref, _results;
_ref = this.priority_settings();
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
view_model = _ref[_i];
_results.push(view_model.priority_color());
}
return _results;
}, this);
this.default_priority = ko.observable('medium');
this.default_priority_color = ko.dependentObservable(__bind(function() {
return this.getColorByPriority(this.default_priority());
}, this));
this.priorityToRank = function(priority) {
switch (priority) {
case 'high':
return 0;
case 'medium':
return 1;
case 'low':
return 2;
}
};
return this;
};
SortingOptionViewModel = function(string_id) {
this.id = string_id;
this.label = kb.observable(kb.locale_manager, {
key: string_id
});
this.option_group = 'list_sort';
return this;
};
Todo = (function() {
__extends(Todo, Backbone.Model);
function Todo() {
Todo.__super__.constructor.apply(this, arguments);
}
Todo.prototype.defaults = function() {
return {
created_at: new Date()
};
};
Todo.prototype.set = function(attrs) {
if (attrs && attrs.hasOwnProperty('done_at') && _.isString(attrs['done_at'])) {
attrs['done_at'] = new Date(attrs['done_at']);
}
if (attrs && attrs.hasOwnProperty('created_at') && _.isString(attrs['created_at'])) {
attrs['created_at'] = new Date(attrs['created_at']);
}
return Todo.__super__.set.apply(this, arguments);
};
Todo.prototype.done = function(done) {
if (arguments.length === 0) {
return !!this.get('done_at');
}
return this.save({
done_at: done ? new Date() : null
});
};
return Todo;
})();
TodoList = (function() {
__extends(TodoList, Backbone.Collection);
function TodoList() {
TodoList.__super__.constructor.apply(this, arguments);
}
TodoList.prototype.model = Todo;
TodoList.prototype.localStorage = new Store("kb_todos");
TodoList.prototype.doneCount = function() {
return this.models.reduce((function(prev, cur) {
return prev + (!!cur.get('done_at') ? 1 : 0);
}), 0);
};
TodoList.prototype.remainingCount = function() {
return this.models.length - this.doneCount();
};
TodoList.prototype.allDone = function() {
return this.filter(function(todo) {
return !!todo.get('done_at');
});
};
return TodoList;
})();
todos = new TodoList();
todos.fetch();
CreateTodoViewModel = function() {
var tooltip_visible;
this.input_text = ko.observable('');
this.input_placeholder_text = kb.observable(kb.locale_manager, {
key: 'placeholder_create'
});
this.input_tooltip_text = kb.observable(kb.locale_manager, {
key: 'tooltip_create'
});
this.addTodo = function(view_model, event) {
var text;
text = this.create.input_text();
if (!text || event.keyCode !== 13) {
return true;
}
todos.create({
text: text,
priority: window.settings_view_model.default_priority()
});
return this.create.input_text('');
};
this.priority_color = ko.dependentObservable(function() {
return window.settings_view_model.default_priority_color();
});
this.tooltip_visible = ko.observable(false);
tooltip_visible = this.tooltip_visible;
this.onSelectPriority = function(view_model, event) {
event.stopPropagation();
tooltip_visible(false);
return window.settings_view_model.default_priority(ko.utils.unwrapObservable(this.priority));
};
this.onToggleTooltip = __bind(function() {
return this.tooltip_visible(!this.tooltip_visible());
}, this);
return this;
};
TodoViewModel = function(model) {
var tooltip_visible;
this.text = kb.observable(model, {
key: 'text',
write: (function(text) {
return model.save({
text: text
});
})
}, this);
this.edit_mode = ko.observable(false);
this.toggleEditMode = __bind(function() {
if (!this.done()) {
return this.edit_mode(!this.edit_mode());
}
}, this);
this.onEnterEndEdit = __bind(function(view_model, event) {
if (event.keyCode === 13) {
return this.edit_mode(false);
}
}, this);
this.created_at = model.get('created_at');
this.done = kb.observable(model, {
key: 'done_at',
read: (function() {
return model.done();
}),
write: (function(done) {
return model.done(done);
})
}, this);
this.done_at = kb.observable(model, {
key: 'done_at',
localizer: LongDateLocalizer
});
this.done_text = ko.dependentObservable(__bind(function() {
var done_at;
done_at = this.done_at();
if (!!done_at) {
return "" + (kb.locale_manager.get('label_completed')) + ": " + done_at;
} else {
return '';
}
}, this));
this.priority_color = kb.observable(model, {
key: 'priority',
read: function() {
return window.settings_view_model.getColorByPriority(model.get('priority'));
}
});
this.tooltip_visible = ko.observable(false);
tooltip_visible = this.tooltip_visible;
this.onSelectPriority = function(view_model, event) {
event.stopPropagation();
tooltip_visible(false);
return model.save({
priority: ko.utils.unwrapObservable(this.priority)
});
};
this.onToggleTooltip = __bind(function() {
return this.tooltip_visible(!this.tooltip_visible());
}, this);
this.destroyTodo = __bind(function() {
return model.destroy();
}, this);
return this;
};
TodoListViewModel = function(todos) {
this.todos = ko.observableArray([]);
this.sort_mode = ko.observable('label_text');
this.sorting_options = [new SortingOptionViewModel('label_text'), new SortingOptionViewModel('label_created'), new SortingOptionViewModel('label_priority')];
this.selected_value = ko.dependentObservable({
read: __bind(function() {
return this.sort_mode();
}, this),
write: __bind(function(new_mode) {
this.sort_mode(new_mode);
switch (new_mode) {
case 'label_text':
return this.collection_observable.sortAttribute('text');
case 'label_created':
return this.collection_observable.sortedIndex(function(models, model) {
return _.sortedIndex(models, model, function(test) {
return test.get('created_at').valueOf();
});
});
case 'label_priority':
return this.collection_observable.sortedIndex(function(models, model) {
return _.sortedIndex(models, model, function(test) {
return window.settings_view_model.priorityToRank(test.get('priority'));
});
});
}
}, this),
owner: this
});
this.collection_observable = kb.collectionObservable(todos, this.todos, {
view_model: TodoViewModel,
sort_attribute: 'text'
});
this.sort_visible = ko.dependentObservable(__bind(function() {
return this.collection_observable().length;
}, this));
return this;
};
FooterViewModel = function(locales) {
this.instructions_text = kb.observable(kb.locale_manager, {
key: 'instructions'
});
this.current_language = ko.observable(kb.locale_manager.getLocale());
this.language_options = ko.observableArray(_.map(locales, function(locale) {
return new LanguageOptionViewModel(locale);
}));
this.selected_value = ko.dependentObservable({
read: __bind(function() {
return this.current_language();
}, this),
write: __bind(function(new_locale) {
kb.locale_manager.setLocale(new_locale);
return this.current_language(new_locale);
}, this),
owner: this
});
return this;
};
StatsViewModel = function(todos) {
this.co = kb.collectionObservable(todos);
this.remaining_text_key = ko.dependentObservable(__bind(function() {
if (this.co.collection().remainingCount() === 0) {
return null;
} else {
if (todos.remainingCount() === 1) {
return 'remaining_template_s';
} else {
return 'remaining_template_pl';
}
}
}, this));
this.remaining_text = kb.observable(kb.locale_manager, {
key: this.remaining_text_key,
args: __bind(function() {
return this.co.collection().remainingCount();
}, this)
});
this.clear_text_key = ko.dependentObservable(__bind(function() {
if (this.co.collection().doneCount() === 0) {
return null;
} else {
if (todos.doneCount() === 1) {
return 'remaining_template_s';
} else {
return 'remaining_template_pl';
}
}
}, this));
this.clear_text = kb.observable(kb.locale_manager, {
key: this.clear_text_key,
args: __bind(function() {
return this.co.collection().doneCount();
}, this)
});
this.onDestroyDone = __bind(function() {
var model, _i, _len, _ref, _results;
_ref = todos.allDone();
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
model = _ref[_i];
_results.push(model.destroy());
}
return _results;
}, this);
return this;
};
window.settings_view_model = new SettingsViewModel([new Backbone.ModelRef(priorities, 'high'), new Backbone.ModelRef(priorities, 'medium'), new Backbone.ModelRef(priorities, 'low')]);
app_view_model = {
create: new CreateTodoViewModel(),
todo_list: new TodoListViewModel(todos),
footer: new FooterViewModel(kb.locale_manager.getLocales()),
stats: new StatsViewModel(todos)
};
ko.applyBindings(app_view_model, $('#todoapp')[0]);
return _.delay((function() {
priorities.fetch({
success: function(collection) {
if (!collection.get('high')) {
collection.create({
id: 'high',
color: '#bf30ff'
});
}
if (!collection.get('medium')) {
collection.create({
id: 'medium',
color: '#98acff'
});
}
if (!collection.get('low')) {
return collection.create({
id: 'low',
color: '#38ff6a'
});
}
}
});
$('.colorpicker').mColorPicker({
imageFolder: '../css/images/'
});
return $('.colorpicker').bind('colorpicked', function() {
var model;
model = priorities.get($(this).attr('id'));
if (model) {
return model.save({
color: $(this).val()
});
}
});
}), 1000);
});
\ No newline at end of file
###
knockback-todos.js
(c) 2011 Kevin Malakoff.
Knockback-Todos is freely distributable under the MIT license.
See the following for full license details:
https:#github.com/kmalakoff/knockback-todos/blob/master/LICENSE
###
# Localization
class LocaleManager
constructor: (locale_identifier, @translations_by_locale) ->
@setLocale(locale_identifier) if locale_identifier
get: (string_id, parameters) ->
return '' if not string_id
culture_map = @translations_by_locale[@locale_identifier] if @locale_identifier
return '' if not culture_map
string = if culture_map.hasOwnProperty(string_id) then culture_map[string_id] else ''
return string if arguments.length == 1
return Knockback.toFormattedString.apply(null, [string].concat(Array.prototype.slice.call(arguments, 1)))
getLocale: -> return @locale_identifier
setLocale: (locale_identifier) ->
@locale_identifier = locale_identifier
Globalize.culture = Globalize.findClosestCulture(locale_identifier)
return if !window.Backbone
@trigger('change', this)
culture_map = @translations_by_locale[@locale_identifier]
return if not culture_map
@trigger("change:#{key}", value) for key, value of culture_map
getLocales: ->
locales = []
locales.push(string_id) for string_id, value of @translations_by_locale
return locales
localeToLabel: (locale) ->
locale_parts = locale.split('-')
return locale_parts[locale_parts.length-1].toUpperCase()
localizeDate: (date) -> Globalize.format(date, Globalize.cultures[@locale_identifier].calendars.standard.patterns.f, @locale_identifier)
#######################################
# Mix in Backbone.Events so callers can subscribe
#######################################
LocaleManager.prototype extends Backbone.Events if !!window.Backbone
#######################################
# Set up strings
#######################################
kb ||(kb={})
kb.locale_manager = new LocaleManager(null, {
'en':
placeholder_create: 'What needs to be done?'
tooltip_create: 'Press Enter to save this task'
label_text: 'Name'
label_created: 'Created'
label_priority: 'Priority'
label_completed: 'Completed'
instructions: 'Double-click to edit a todo.'
high: 'high'
medium: 'medium'
low: 'low'
remaining_template_s: '{0} item remaining'
remaining_template_pl:'{0} items remaining'
clear_template_s: 'Clear {0} completed item'
clear_template_pl: 'Clear {0} completed items'
'fr-FR':
placeholder_create: 'Que faire?'
tooltip_create: 'Appuyez sur Enter pour enregistrer cette tâche'
label_text: 'Nom'
label_created: 'Création'
label_priority: 'Priorité'
label_completed: 'Complété'
instructions: 'Double-cliquez pour modifier un todo.'
high: 'haute'
medium: 'moyen'
low: 'bas'
remaining_template_s: '{0} point restant'
remaining_template_pl:'{0} éléments restants'
clear_template_s: 'Retirer {0} point terminée'
clear_template_pl: 'Retirer les {0} éléments terminés'
'it-IT':
placeholder_create: 'Cosa fare?'
tooltip_create: 'Premere Enter per salvare questo compito'
label_text: 'Nome'
label_created: 'Creato'
label_priority: 'Priorità'
label_completed: 'Completato'
instructions: 'Fare doppio clic per modificare una delle cose da fare.'
high: 'alto'
medium: 'medio'
low: 'basso'
remaining_template_s: '{0} elemento restante'
remaining_template_pl:'{0} elementi rimanenti'
clear_template_s: 'Rimuovere {0} elemento completato'
clear_template_pl: 'Rimuovere {0} elementi completato'
})
#######################################
# Date localizer
#######################################
if !!window.Backbone
class LongDateLocalizer extends kb.LocalizedObservable
constructor: -> return super
read: (value) ->
return Globalize.format(value, Globalize.cultures[kb.locale_manager.getLocale()].calendars.standard.patterns.f, kb.locale_manager.getLocale())
write: (localized_string, value, observable) ->
new_value = Globalize.parseDate(localized_string, Globalize.cultures[kb.locale_manager.getLocale()].calendars.standard.patterns.d, kb.locale_manager.getLocale())
value.setTime(new_value.valueOf())
/*
knockback-todos.js
(c) 2011 Kevin Malakoff.
Knockback-Todos is freely distributable under the MIT license.
See the following for full license details:
https:#github.com/kmalakoff/knockback-todos/blob/master/LICENSE
*/
var LocaleManager, LongDateLocalizer, kb;
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
return child;
};
LocaleManager = (function() {
function LocaleManager(locale_identifier, translations_by_locale) {
this.translations_by_locale = translations_by_locale;
if (locale_identifier) {
this.setLocale(locale_identifier);
}
}
LocaleManager.prototype.get = function(string_id, parameters) {
var culture_map, string;
if (!string_id) {
return '';
}
if (this.locale_identifier) {
culture_map = this.translations_by_locale[this.locale_identifier];
}
if (!culture_map) {
return '';
}
string = culture_map.hasOwnProperty(string_id) ? culture_map[string_id] : '';
if (arguments.length === 1) {
return string;
}
return Knockback.toFormattedString.apply(null, [string].concat(Array.prototype.slice.call(arguments, 1)));
};
LocaleManager.prototype.getLocale = function() {
return this.locale_identifier;
};
LocaleManager.prototype.setLocale = function(locale_identifier) {
var culture_map, key, value, _results;
this.locale_identifier = locale_identifier;
Globalize.culture = Globalize.findClosestCulture(locale_identifier);
if (!window.Backbone) {
return;
}
this.trigger('change', this);
culture_map = this.translations_by_locale[this.locale_identifier];
if (!culture_map) {
return;
}
_results = [];
for (key in culture_map) {
value = culture_map[key];
_results.push(this.trigger("change:" + key, value));
}
return _results;
};
LocaleManager.prototype.getLocales = function() {
var locales, string_id, value, _ref;
locales = [];
_ref = this.translations_by_locale;
for (string_id in _ref) {
value = _ref[string_id];
locales.push(string_id);
}
return locales;
};
LocaleManager.prototype.localeToLabel = function(locale) {
var locale_parts;
locale_parts = locale.split('-');
return locale_parts[locale_parts.length - 1].toUpperCase();
};
LocaleManager.prototype.localizeDate = function(date) {
return Globalize.format(date, Globalize.cultures[this.locale_identifier].calendars.standard.patterns.f, this.locale_identifier);
};
return LocaleManager;
})();
if (!!window.Backbone) {
__extends(LocaleManager.prototype, Backbone.Events);
}
kb || (kb = {});
kb.locale_manager = new LocaleManager(null, {
'en': {
placeholder_create: 'What needs to be done?',
tooltip_create: 'Press Enter to save this task',
label_text: 'Name',
label_created: 'Created',
label_priority: 'Priority',
label_completed: 'Completed',
instructions: 'Double-click to edit a todo.',
high: 'high',
medium: 'medium',
low: 'low',
remaining_template_s: '{0} item remaining',
remaining_template_pl: '{0} items remaining',
clear_template_s: 'Clear {0} completed item',
clear_template_pl: 'Clear {0} completed items'
},
'fr-FR': {
placeholder_create: 'Que faire?',
tooltip_create: 'Appuyez sur Enter pour enregistrer cette tâche',
label_text: 'Nom',
label_created: 'Création',
label_priority: 'Priorité',
label_completed: 'Complété',
instructions: 'Double-cliquez pour modifier un todo.',
high: 'haute',
medium: 'moyen',
low: 'bas',
remaining_template_s: '{0} point restant',
remaining_template_pl: '{0} éléments restants',
clear_template_s: 'Retirer {0} point terminée',
clear_template_pl: 'Retirer les {0} éléments terminés'
},
'it-IT': {
placeholder_create: 'Cosa fare?',
tooltip_create: 'Premere Enter per salvare questo compito',
label_text: 'Nome',
label_created: 'Creato',
label_priority: 'Priorità',
label_completed: 'Completato',
instructions: 'Fare doppio clic per modificare una delle cose da fare.',
high: 'alto',
medium: 'medio',
low: 'basso',
remaining_template_s: '{0} elemento restante',
remaining_template_pl: '{0} elementi rimanenti',
clear_template_s: 'Rimuovere {0} elemento completato',
clear_template_pl: 'Rimuovere {0} elementi completato'
}
});
if (!!window.Backbone) {
LongDateLocalizer = (function() {
__extends(LongDateLocalizer, kb.LocalizedObservable);
function LongDateLocalizer() {
return LongDateLocalizer.__super__.constructor.apply(this, arguments);
}
LongDateLocalizer.prototype.read = function(value) {
return Globalize.format(value, Globalize.cultures[kb.locale_manager.getLocale()].calendars.standard.patterns.f, kb.locale_manager.getLocale());
};
LongDateLocalizer.prototype.write = function(localized_string, value, observable) {
var new_value;
new_value = Globalize.parseDate(localized_string, Globalize.cultures[kb.locale_manager.getLocale()].calendars.standard.patterns.d, kb.locale_manager.getLocale());
return value.setTime(new_value.valueOf());
};
return LongDateLocalizer;
})();
}
\ No newline at end of file
// A simple module to replace `Backbone.sync` with *localStorage*-based
// persistence. Models are given GUIDS, and saved into a JSON object. Simple
// as that.
// Generate four random hex digits.
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
};
// Generate a pseudo-GUID by concatenating random hexadecimal.
function guid() {
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
};
// Our Store is represented by a single JS object in *localStorage*. Create it
// with a meaningful name, like the name you'd give a table.
var Store = function(name) {
this.name = name;
var store = localStorage.getItem(this.name);
this.data = (store && JSON.parse(store)) || {};
};
_.extend(Store.prototype, {
// Save the current state of the **Store** to *localStorage*.
save: function() {
localStorage.setItem(this.name, JSON.stringify(this.data));
},
// Add a model, giving it a (hopefully)-unique GUID, if it doesn't already
// have an id of it's own.
create: function(model) {
if (!model.id) model.id = model.attributes.id = guid();
this.data[model.id] = model;
this.save();
return model;
},
// Update a model by replacing its copy in `this.data`.
update: function(model) {
this.data[model.id] = model;
this.save();
return model;
},
// Retrieve a model from `this.data` by id.
find: function(model) {
return this.data[model.id];
},
// Return the array of all models currently in storage.
findAll: function() {
return _.values(this.data);
},
// Delete a model from `this.data`, returning it.
destroy: function(model) {
delete this.data[model.id];
this.save();
return model;
}
});
// Override `Backbone.sync` to use delegate to the model or collection's
// *localStorage* property, which should be an instance of `Store`.
Backbone.sync = function(method, model, options) {
var resp;
var store = model.localStorage || model.collection.localStorage;
switch (method) {
case "read": resp = model.id ? store.find(model) : store.findAll(); break;
case "create": resp = store.create(model); break;
case "update": resp = store.update(model); break;
case "delete": resp = store.destroy(model); break;
}
if (resp) {
options.success(resp);
} else {
options.error("Record not found");
}
};
\ No newline at end of file
/*
* Globalize Culture fr-FR
*
* http://github.com/jquery/globalize
*
* Copyright Software Freedom Conservancy, Inc.
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* This file was generated by the Globalize Culture Generator
* Translation: bugs found in this file need to be fixed in the generator
*/
(function( window, undefined ) {
var Globalize;
if ( typeof require !== "undefined"
&& typeof exports !== "undefined"
&& typeof module !== "undefined" ) {
// Assume CommonJS
Globalize = require( "globalize" );
} else {
// Global variable
Globalize = window.Globalize;
}
Globalize.addCultureInfo( "fr-FR", "default", {
name: "fr-FR",
englishName: "French (France)",
nativeName: "français (France)",
language: "fr",
numberFormat: {
",": " ",
".": ",",
NaN: "Non Numérique",
negativeInfinity: "-Infini",
positiveInfinity: "+Infini",
percent: {
",": " ",
".": ","
},
currency: {
pattern: ["-n $","n $"],
",": " ",
".": ",",
symbol: ""
}
},
calendars: {
standard: {
firstDay: 1,
days: {
names: ["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],
namesAbbr: ["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],
namesShort: ["di","lu","ma","me","je","ve","sa"]
},
months: {
names: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""],
namesAbbr: ["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""]
},
AM: null,
PM: null,
eras: [{"name":"ap. J.-C.","start":null,"offset":0}],
patterns: {
d: "dd/MM/yyyy",
D: "dddd d MMMM yyyy",
t: "HH:mm",
T: "HH:mm:ss",
f: "dddd d MMMM yyyy HH:mm",
F: "dddd d MMMM yyyy HH:mm:ss",
M: "d MMMM",
Y: "MMMM yyyy"
}
}
}
});
}( this ));
/*
* Globalize Culture it-IT
*
* http://github.com/jquery/globalize
*
* Copyright Software Freedom Conservancy, Inc.
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* This file was generated by the Globalize Culture Generator
* Translation: bugs found in this file need to be fixed in the generator
*/
(function( window, undefined ) {
var Globalize;
if ( typeof require !== "undefined"
&& typeof exports !== "undefined"
&& typeof module !== "undefined" ) {
// Assume CommonJS
Globalize = require( "globalize" );
} else {
// Global variable
Globalize = window.Globalize;
}
Globalize.addCultureInfo( "it-IT", "default", {
name: "it-IT",
englishName: "Italian (Italy)",
nativeName: "italiano (Italia)",
language: "it",
numberFormat: {
",": ".",
".": ",",
NaN: "Non un numero reale",
negativeInfinity: "-Infinito",
positiveInfinity: "+Infinito",
percent: {
pattern: ["-n%","n%"],
",": ".",
".": ","
},
currency: {
pattern: ["-$ n","$ n"],
",": ".",
".": ",",
symbol: ""
}
},
calendars: {
standard: {
firstDay: 1,
days: {
names: ["domenica","lunedì","martedì","mercoledì","giovedì","venerdì","sabato"],
namesAbbr: ["dom","lun","mar","mer","gio","ven","sab"],
namesShort: ["do","lu","ma","me","gi","ve","sa"]
},
months: {
names: ["gennaio","febbraio","marzo","aprile","maggio","giugno","luglio","agosto","settembre","ottobre","novembre","dicembre",""],
namesAbbr: ["gen","feb","mar","apr","mag","giu","lug","ago","set","ott","nov","dic",""]
},
AM: null,
PM: null,
eras: [{"name":"d.C.","start":null,"offset":0}],
patterns: {
d: "dd/MM/yyyy",
D: "dddd d MMMM yyyy",
t: "HH:mm",
T: "HH:mm:ss",
f: "dddd d MMMM yyyy HH:mm",
F: "dddd d MMMM yyyy HH:mm:ss",
M: "dd MMMM",
Y: "MMMM yyyy"
}
}
}
});
}( this ));
/*!
* Globalize
*
* http://github.com/jquery/globalize
*
* Copyright Software Freedom Conservancy, Inc.
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
(function( window, undefined ) {
var Globalize,
// private variables
regexHex,
regexInfinity,
regexParseFloat,
regexTrim,
// private JavaScript utility functions
arrayIndexOf,
endsWith,
extend,
isArray,
isFunction,
isObject,
startsWith,
trim,
truncate,
zeroPad,
// private Globalization utility functions
appendPreOrPostMatch,
expandFormat,
formatDate,
formatNumber,
getTokenRegExp,
getEra,
getEraYear,
parseExact,
parseNegativePattern;
// Global variable (Globalize) or CommonJS module (globalize)
Globalize = function( cultureSelector ) {
return new Globalize.prototype.init( cultureSelector );
};
if ( typeof require !== "undefined"
&& typeof exports !== "undefined"
&& typeof module !== "undefined" ) {
// Assume CommonJS
module.exports = Globalize;
} else {
// Export as global variable
window.Globalize = Globalize;
}
Globalize.cultures = {};
Globalize.prototype = {
constructor: Globalize,
init: function( cultureSelector ) {
this.cultures = Globalize.cultures;
this.cultureSelector = cultureSelector;
return this;
}
};
Globalize.prototype.init.prototype = Globalize.prototype;
// 1. When defining a culture, all fields are required except the ones stated as optional.
// 2. Each culture should have a ".calendars" object with at least one calendar named "standard"
// which serves as the default calendar in use by that culture.
// 3. Each culture should have a ".calendar" object which is the current calendar being used,
// it may be dynamically changed at any time to one of the calendars in ".calendars".
Globalize.cultures[ "default" ] = {
// A unique name for the culture in the form <language code>-<country/region code>
name: "en",
// the name of the culture in the english language
englishName: "English",
// the name of the culture in its own language
nativeName: "English",
// whether the culture uses right-to-left text
isRTL: false,
// "language" is used for so-called "specific" cultures.
// For example, the culture "es-CL" means "Spanish, in Chili".
// It represents the Spanish-speaking culture as it is in Chili,
// which might have different formatting rules or even translations
// than Spanish in Spain. A "neutral" culture is one that is not
// specific to a region. For example, the culture "es" is the generic
// Spanish culture, which may be a more generalized version of the language
// that may or may not be what a specific culture expects.
// For a specific culture like "es-CL", the "language" field refers to the
// neutral, generic culture information for the language it is using.
// This is not always a simple matter of the string before the dash.
// For example, the "zh-Hans" culture is netural (Simplified Chinese).
// And the "zh-SG" culture is Simplified Chinese in Singapore, whose lanugage
// field is "zh-CHS", not "zh".
// This field should be used to navigate from a specific culture to it's
// more general, neutral culture. If a culture is already as general as it
// can get, the language may refer to itself.
language: "en",
// numberFormat defines general number formatting rules, like the digits in
// each grouping, the group separator, and how negative numbers are displayed.
numberFormat: {
// [negativePattern]
// Note, numberFormat.pattern has no "positivePattern" unlike percent and currency,
// but is still defined as an array for consistency with them.
// negativePattern: one of "(n)|-n|- n|n-|n -"
pattern: [ "-n" ],
// number of decimal places normally shown
decimals: 2,
// string that separates number groups, as in 1,000,000
",": ",",
// string that separates a number from the fractional portion, as in 1.99
".": ".",
// array of numbers indicating the size of each number group.
// TODO: more detailed description and example
groupSizes: [ 3 ],
// symbol used for positive numbers
"+": "+",
// symbol used for negative numbers
"-": "-",
// symbol used for NaN (Not-A-Number)
NaN: "NaN",
// symbol used for Negative Infinity
negativeInfinity: "-Infinity",
// symbol used for Positive Infinity
positiveInfinity: "Infinity",
percent: {
// [negativePattern, positivePattern]
// negativePattern: one of "-n %|-n%|-%n|%-n|%n-|n-%|n%-|-% n|n %-|% n-|% -n|n- %"
// positivePattern: one of "n %|n%|%n|% n"
pattern: [ "-n %", "n %" ],
// number of decimal places normally shown
decimals: 2,
// array of numbers indicating the size of each number group.
// TODO: more detailed description and example
groupSizes: [ 3 ],
// string that separates number groups, as in 1,000,000
",": ",",
// string that separates a number from the fractional portion, as in 1.99
".": ".",
// symbol used to represent a percentage
symbol: "%"
},
currency: {
// [negativePattern, positivePattern]
// negativePattern: one of "($n)|-$n|$-n|$n-|(n$)|-n$|n-$|n$-|-n $|-$ n|n $-|$ n-|$ -n|n- $|($ n)|(n $)"
// positivePattern: one of "$n|n$|$ n|n $"
pattern: [ "($n)", "$n" ],
// number of decimal places normally shown
decimals: 2,
// array of numbers indicating the size of each number group.
// TODO: more detailed description and example
groupSizes: [ 3 ],
// string that separates number groups, as in 1,000,000
",": ",",
// string that separates a number from the fractional portion, as in 1.99
".": ".",
// symbol used to represent currency
symbol: "$"
}
},
// calendars defines all the possible calendars used by this culture.
// There should be at least one defined with name "standard", and is the default
// calendar used by the culture.
// A calendar contains information about how dates are formatted, information about
// the calendar's eras, a standard set of the date formats,
// translations for day and month names, and if the calendar is not based on the Gregorian
// calendar, conversion functions to and from the Gregorian calendar.
calendars: {
standard: {
// name that identifies the type of calendar this is
name: "Gregorian_USEnglish",
// separator of parts of a date (e.g. "/" in 11/05/1955)
"/": "/",
// separator of parts of a time (e.g. ":" in 05:44 PM)
":": ":",
// the first day of the week (0 = Sunday, 1 = Monday, etc)
firstDay: 0,
days: {
// full day names
names: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
// abbreviated day names
namesAbbr: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
// shortest day names
namesShort: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ]
},
months: {
// full month names (13 months for lunar calendards -- 13th month should be "" if not lunar)
names: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" ],
// abbreviated month names
namesAbbr: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" ]
},
// AM and PM designators in one of these forms:
// The usual view, and the upper and lower case versions
// [ standard, lowercase, uppercase ]
// The culture does not use AM or PM (likely all standard date formats use 24 hour time)
// null
AM: [ "AM", "am", "AM" ],
PM: [ "PM", "pm", "PM" ],
eras: [
// eras in reverse chronological order.
// name: the name of the era in this culture (e.g. A.D., C.E.)
// start: when the era starts in ticks (gregorian, gmt), null if it is the earliest supported era.
// offset: offset in years from gregorian calendar
{
"name": "A.D.",
"start": null,
"offset": 0
}
],
// when a two digit year is given, it will never be parsed as a four digit
// year greater than this year (in the appropriate era for the culture)
// Set it as a full year (e.g. 2029) or use an offset format starting from
// the current year: "+19" would correspond to 2029 if the current year 2010.
twoDigitYearMax: 2029,
// set of predefined date and time patterns used by the culture
// these represent the format someone in this culture would expect
// to see given the portions of the date that are shown.
patterns: {
// short date pattern
d: "M/d/yyyy",
// long date pattern
D: "dddd, MMMM dd, yyyy",
// short time pattern
t: "h:mm tt",
// long time pattern
T: "h:mm:ss tt",
// long date, short time pattern
f: "dddd, MMMM dd, yyyy h:mm tt",
// long date, long time pattern
F: "dddd, MMMM dd, yyyy h:mm:ss tt",
// month/day pattern
M: "MMMM dd",
// month/year pattern
Y: "yyyy MMMM",
// S is a sortable format that does not vary by culture
S: "yyyy\u0027-\u0027MM\u0027-\u0027dd\u0027T\u0027HH\u0027:\u0027mm\u0027:\u0027ss"
}
// optional fields for each calendar:
/*
monthsGenitive:
Same as months but used when the day preceeds the month.
Omit if the culture has no genitive distinction in month names.
For an explaination of genitive months, see http://blogs.msdn.com/michkap/archive/2004/12/25/332259.aspx
convert:
Allows for the support of non-gregorian based calendars. This convert object is used to
to convert a date to and from a gregorian calendar date to handle parsing and formatting.
The two functions:
fromGregorian( date )
Given the date as a parameter, return an array with parts [ year, month, day ]
corresponding to the non-gregorian based year, month, and day for the calendar.
toGregorian( year, month, day )
Given the non-gregorian year, month, and day, return a new Date() object
set to the corresponding date in the gregorian calendar.
*/
}
},
// For localized strings
messages: {}
};
Globalize.cultures[ "default" ].calendar = Globalize.cultures[ "default" ].calendars.standard;
Globalize.cultures[ "en" ] = Globalize.cultures[ "default" ];
Globalize.cultureSelector = "en";
//
// private variables
//
regexHex = /^0x[a-f0-9]+$/i;
regexInfinity = /^[+-]?infinity$/i;
regexParseFloat = /^[+-]?\d*\.?\d*(e[+-]?\d+)?$/;
regexTrim = /^\s+|\s+$/g;
//
// private JavaScript utility functions
//
arrayIndexOf = function( array, item ) {
if ( array.indexOf ) {
return array.indexOf( item );
}
for ( var i = 0, length = array.length; i < length; i++ ) {
if ( array[i] === item ) {
return i;
}
}
return -1;
};
endsWith = function( value, pattern ) {
return value.substr( value.length - pattern.length ) === pattern;
};
extend = function( deep ) {
var options, name, src, copy, copyIsArray, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
// Handle a deep copy situation
if ( typeof target === "boolean" ) {
deep = target;
target = arguments[1] || {};
// skip the boolean and the target
i = 2;
}
// Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && !isFunction(target) ) {
target = {};
}
for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
// Prevent never-ending loop
if ( target === copy ) {
continue;
}
// Recurse if we're merging plain objects or arrays
if ( deep && copy && ( isObject(copy) || (copyIsArray = isArray(copy)) ) ) {
if ( copyIsArray ) {
copyIsArray = false;
clone = src && isArray(src) ? src : [];
} else {
clone = src && isObject(src) ? src : {};
}
// Never move original objects, clone them
target[ name ] = extend( deep, clone, copy );
// Don't bring in undefined values
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
}
// Return the modified object
return target;
};
isArray = Array.isArray || function( obj ) {
return Object.prototype.toString.call( obj ) === "[object Array]";
};
isFunction = function( obj ) {
return Object.prototype.toString.call( obj ) === "[object Function]";
};
isObject = function( obj ) {
return Object.prototype.toString.call( obj ) === "[object Object]";
};
startsWith = function( value, pattern ) {
return value.indexOf( pattern ) === 0;
};
trim = function( value ) {
return ( value + "" ).replace( regexTrim, "" );
};
truncate = function( value ) {
return isNaN( value ) ? NaN : value | 0;
};
zeroPad = function( str, count, left ) {
var l;
for ( l = str.length; l < count; l += 1 ) {
str = ( left ? ("0" + str) : (str + "0") );
}
return str;
};
//
// private Globalization utility functions
//
appendPreOrPostMatch = function( preMatch, strings ) {
// appends pre- and post- token match strings while removing escaped characters.
// Returns a single quote count which is used to determine if the token occurs
// in a string literal.
var quoteCount = 0,
escaped = false;
for ( var i = 0, il = preMatch.length; i < il; i++ ) {
var c = preMatch.charAt( i );
switch ( c ) {
case "\'":
if ( escaped ) {
strings.push( "\'" );
}
else {
quoteCount++;
}
escaped = false;
break;
case "\\":
if ( escaped ) {
strings.push( "\\" );
}
escaped = !escaped;
break;
default:
strings.push( c );
escaped = false;
break;
}
}
return quoteCount;
};
expandFormat = function( cal, format ) {
// expands unspecified or single character date formats into the full pattern.
format = format || "F";
var pattern,
patterns = cal.patterns,
len = format.length;
if ( len === 1 ) {
pattern = patterns[ format ];
if ( !pattern ) {
throw "Invalid date format string \'" + format + "\'.";
}
format = pattern;
}
else if ( len === 2 && format.charAt(0) === "%" ) {
// %X escape format -- intended as a custom format string that is only one character, not a built-in format.
format = format.charAt( 1 );
}
return format;
};
formatDate = function( value, format, culture ) {
var cal = culture.calendar,
convert = cal.convert;
if ( !format || !format.length || format === "i" ) {
var ret;
if ( culture && culture.name.length ) {
if ( convert ) {
// non-gregorian calendar, so we cannot use built-in toLocaleString()
ret = formatDate( value, cal.patterns.F, culture );
}
else {
var eraDate = new Date( value.getTime() ),
era = getEra( value, cal.eras );
eraDate.setFullYear( getEraYear(value, cal, era) );
ret = eraDate.toLocaleString();
}
}
else {
ret = value.toString();
}
return ret;
}
var eras = cal.eras,
sortable = format === "s";
format = expandFormat( cal, format );
// Start with an empty string
ret = [];
var hour,
zeros = [ "0", "00", "000" ],
foundDay,
checkedDay,
dayPartRegExp = /([^d]|^)(d|dd)([^d]|$)/g,
quoteCount = 0,
tokenRegExp = getTokenRegExp(),
converted;
function padZeros( num, c ) {
var r, s = num + "";
if ( c > 1 && s.length < c ) {
r = ( zeros[c - 2] + s);
return r.substr( r.length - c, c );
}
else {
r = s;
}
return r;
}
function hasDay() {
if ( foundDay || checkedDay ) {
return foundDay;
}
foundDay = dayPartRegExp.test( format );
checkedDay = true;
return foundDay;
}
function getPart( date, part ) {
if ( converted ) {
return converted[ part ];
}
switch ( part ) {
case 0: return date.getFullYear();
case 1: return date.getMonth();
case 2: return date.getDate();
}
}
if ( !sortable && convert ) {
converted = convert.fromGregorian( value );
}
for ( ; ; ) {
// Save the current index
var index = tokenRegExp.lastIndex,
// Look for the next pattern
ar = tokenRegExp.exec( format );
// Append the text before the pattern (or the end of the string if not found)
var preMatch = format.slice( index, ar ? ar.index : format.length );
quoteCount += appendPreOrPostMatch( preMatch, ret );
if ( !ar ) {
break;
}
// do not replace any matches that occur inside a string literal.
if ( quoteCount % 2 ) {
ret.push( ar[0] );
continue;
}
var current = ar[ 0 ],
clength = current.length;
switch ( current ) {
case "ddd":
//Day of the week, as a three-letter abbreviation
case "dddd":
// Day of the week, using the full name
var names = ( clength === 3 ) ? cal.days.namesAbbr : cal.days.names;
ret.push( names[value.getDay()] );
break;
case "d":
// Day of month, without leading zero for single-digit days
case "dd":
// Day of month, with leading zero for single-digit days
foundDay = true;
ret.push(
padZeros( getPart(value, 2), clength )
);
break;
case "MMM":
// Month, as a three-letter abbreviation
case "MMMM":
// Month, using the full name
var part = getPart( value, 1 );
ret.push(
( cal.monthsGenitive && hasDay() )
?
cal.monthsGenitive[ clength === 3 ? "namesAbbr" : "names" ][ part ]
:
cal.months[ clength === 3 ? "namesAbbr" : "names" ][ part ]
);
break;
case "M":
// Month, as digits, with no leading zero for single-digit months
case "MM":
// Month, as digits, with leading zero for single-digit months
ret.push(
padZeros( getPart(value, 1) + 1, clength )
);
break;
case "y":
// Year, as two digits, but with no leading zero for years less than 10
case "yy":
// Year, as two digits, with leading zero for years less than 10
case "yyyy":
// Year represented by four full digits
part = converted ? converted[ 0 ] : getEraYear( value, cal, getEra(value, eras), sortable );
if ( clength < 4 ) {
part = part % 100;
}
ret.push(
padZeros( part, clength )
);
break;
case "h":
// Hours with no leading zero for single-digit hours, using 12-hour clock
case "hh":
// Hours with leading zero for single-digit hours, using 12-hour clock
hour = value.getHours() % 12;
if ( hour === 0 ) hour = 12;
ret.push(
padZeros( hour, clength )
);
break;
case "H":
// Hours with no leading zero for single-digit hours, using 24-hour clock
case "HH":
// Hours with leading zero for single-digit hours, using 24-hour clock
ret.push(
padZeros( value.getHours(), clength )
);
break;
case "m":
// Minutes with no leading zero for single-digit minutes
case "mm":
// Minutes with leading zero for single-digit minutes
ret.push(
padZeros( value.getMinutes(), clength )
);
break;
case "s":
// Seconds with no leading zero for single-digit seconds
case "ss":
// Seconds with leading zero for single-digit seconds
ret.push(
padZeros( value.getSeconds(), clength )
);
break;
case "t":
// One character am/pm indicator ("a" or "p")
case "tt":
// Multicharacter am/pm indicator
part = value.getHours() < 12 ? ( cal.AM ? cal.AM[0] : " " ) : ( cal.PM ? cal.PM[0] : " " );
ret.push( clength === 1 ? part.charAt(0) : part );
break;
case "f":
// Deciseconds
case "ff":
// Centiseconds
case "fff":
// Milliseconds
ret.push(
padZeros( value.getMilliseconds(), 3 ).substr( 0, clength )
);
break;
case "z":
// Time zone offset, no leading zero
case "zz":
// Time zone offset with leading zero
hour = value.getTimezoneOffset() / 60;
ret.push(
( hour <= 0 ? "+" : "-" ) + padZeros( Math.floor(Math.abs(hour)), clength )
);
break;
case "zzz":
// Time zone offset with leading zero
hour = value.getTimezoneOffset() / 60;
ret.push(
( hour <= 0 ? "+" : "-" ) + padZeros( Math.floor(Math.abs(hour)), 2 )
// Hard coded ":" separator, rather than using cal.TimeSeparator
// Repeated here for consistency, plus ":" was already assumed in date parsing.
+ ":" + padZeros( Math.abs(value.getTimezoneOffset() % 60), 2 )
);
break;
case "g":
case "gg":
if ( cal.eras ) {
ret.push(
cal.eras[ getEra(value, eras) ].name
);
}
break;
case "/":
ret.push( cal["/"] );
break;
default:
throw "Invalid date format pattern \'" + current + "\'.";
break;
}
}
return ret.join( "" );
};
// formatNumber
(function() {
var expandNumber;
expandNumber = function( number, precision, formatInfo ) {
var groupSizes = formatInfo.groupSizes,
curSize = groupSizes[ 0 ],
curGroupIndex = 1,
factor = Math.pow( 10, precision ),
rounded = Math.round( number * factor ) / factor;
if ( !isFinite(rounded) ) {
rounded = number;
}
number = rounded;
var numberString = number+"",
right = "",
split = numberString.split( /e/i ),
exponent = split.length > 1 ? parseInt( split[1], 10 ) : 0;
numberString = split[ 0 ];
split = numberString.split( "." );
numberString = split[ 0 ];
right = split.length > 1 ? split[ 1 ] : "";
var l;
if ( exponent > 0 ) {
right = zeroPad( right, exponent, false );
numberString += right.slice( 0, exponent );
right = right.substr( exponent );
}
else if ( exponent < 0 ) {
exponent = -exponent;
numberString = zeroPad( numberString, exponent + 1 );
right = numberString.slice( -exponent, numberString.length ) + right;
numberString = numberString.slice( 0, -exponent );
}
if ( precision > 0 ) {
right = formatInfo[ "." ] +
( (right.length > precision) ? right.slice(0, precision) : zeroPad(right, precision) );
}
else {
right = "";
}
var stringIndex = numberString.length - 1,
sep = formatInfo[ "," ],
ret = "";
while ( stringIndex >= 0 ) {
if ( curSize === 0 || curSize > stringIndex ) {
return numberString.slice( 0, stringIndex + 1 ) + ( ret.length ? (sep + ret + right) : right );
}
ret = numberString.slice( stringIndex - curSize + 1, stringIndex + 1 ) + ( ret.length ? (sep + ret) : "" );
stringIndex -= curSize;
if ( curGroupIndex < groupSizes.length ) {
curSize = groupSizes[ curGroupIndex ];
curGroupIndex++;
}
}
return numberString.slice( 0, stringIndex + 1 ) + sep + ret + right;
};
formatNumber = function( value, format, culture ) {
if ( !isFinite(value) ) {
if ( value === Infinity ) {
return culture.numberFormat.positiveInfinity;
}
if ( value === -Infinity ) {
return culture.numberFormat.negativeInfinity;
}
return culture.numberFormat.NaN;
}
if ( !format || format === "i" ) {
return culture.name.length ? value.toLocaleString() : value.toString();
}
format = format || "D";
var nf = culture.numberFormat,
number = Math.abs( value ),
precision = -1,
pattern;
if ( format.length > 1 ) precision = parseInt( format.slice(1), 10 );
var current = format.charAt( 0 ).toUpperCase(),
formatInfo;
switch ( current ) {
case "D":
pattern = "n";
number = truncate( number );
if ( precision !== -1 ) {
number = zeroPad( "" + number, precision, true );
}
if ( value < 0 ) number = "-" + number;
break;
case "N":
formatInfo = nf;
// fall through
case "C":
formatInfo = formatInfo || nf.currency;
// fall through
case "P":
formatInfo = formatInfo || nf.percent;
pattern = value < 0 ? formatInfo.pattern[ 0 ] : ( formatInfo.pattern[1] || "n" );
if ( precision === -1 ) precision = formatInfo.decimals;
number = expandNumber( number * (current === "P" ? 100 : 1), precision, formatInfo );
break;
default:
throw "Bad number format specifier: " + current;
}
var patternParts = /n|\$|-|%/g,
ret = "";
for ( ; ; ) {
var index = patternParts.lastIndex,
ar = patternParts.exec( pattern );
ret += pattern.slice( index, ar ? ar.index : pattern.length );
if ( !ar ) {
break;
}
switch ( ar[0] ) {
case "n":
ret += number;
break;
case "$":
ret += nf.currency.symbol;
break;
case "-":
// don't make 0 negative
if ( /[1-9]/.test(number) ) {
ret += nf[ "-" ];
}
break;
case "%":
ret += nf.percent.symbol;
break;
}
}
return ret;
};
}());
getTokenRegExp = function() {
// regular expression for matching date and time tokens in format strings.
return /\/|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z|gg|g/g;
};
getEra = function( date, eras ) {
if ( !eras ) return 0;
var start, ticks = date.getTime();
for ( var i = 0, l = eras.length; i < l; i++ ) {
start = eras[ i ].start;
if ( start === null || ticks >= start ) {
return i;
}
}
return 0;
};
getEraYear = function( date, cal, era, sortable ) {
var year = date.getFullYear();
if ( !sortable && cal.eras ) {
// convert normal gregorian year to era-shifted gregorian
// year by subtracting the era offset
year -= cal.eras[ era ].offset;
}
return year;
};
// parseExact
(function() {
var expandYear,
getDayIndex,
getMonthIndex,
getParseRegExp,
outOfRange,
toUpper,
toUpperArray;
expandYear = function( cal, year ) {
// expands 2-digit year into 4 digits.
if ( year < 100 ) {
var now = new Date(),
era = getEra( now ),
curr = getEraYear( now, cal, era ),
twoDigitYearMax = cal.twoDigitYearMax;
twoDigitYearMax = typeof twoDigitYearMax === "string" ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax;
year += curr - ( curr % 100 );
if ( year > twoDigitYearMax ) {
year -= 100;
}
}
return year;
};
getDayIndex = function ( cal, value, abbr ) {
var ret,
days = cal.days,
upperDays = cal._upperDays;
if ( !upperDays ) {
cal._upperDays = upperDays = [
toUpperArray( days.names ),
toUpperArray( days.namesAbbr ),
toUpperArray( days.namesShort )
];
}
value = toUpper( value );
if ( abbr ) {
ret = arrayIndexOf( upperDays[1], value );
if ( ret === -1 ) {
ret = arrayIndexOf( upperDays[2], value );
}
}
else {
ret = arrayIndexOf( upperDays[0], value );
}
return ret;
};
getMonthIndex = function( cal, value, abbr ) {
var months = cal.months,
monthsGen = cal.monthsGenitive || cal.months,
upperMonths = cal._upperMonths,
upperMonthsGen = cal._upperMonthsGen;
if ( !upperMonths ) {
cal._upperMonths = upperMonths = [
toUpperArray( months.names ),
toUpperArray( months.namesAbbr )
];
cal._upperMonthsGen = upperMonthsGen = [
toUpperArray( monthsGen.names ),
toUpperArray( monthsGen.namesAbbr )
];
}
value = toUpper( value );
var i = arrayIndexOf( abbr ? upperMonths[1] : upperMonths[0], value );
if ( i < 0 ) {
i = arrayIndexOf( abbr ? upperMonthsGen[1] : upperMonthsGen[0], value );
}
return i;
};
getParseRegExp = function( cal, format ) {
// converts a format string into a regular expression with groups that
// can be used to extract date fields from a date string.
// check for a cached parse regex.
var re = cal._parseRegExp;
if ( !re ) {
cal._parseRegExp = re = {};
}
else {
var reFormat = re[ format ];
if ( reFormat ) {
return reFormat;
}
}
// expand single digit formats, then escape regular expression characters.
var expFormat = expandFormat( cal, format ).replace( /([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g, "\\\\$1" ),
regexp = [ "^" ],
groups = [],
index = 0,
quoteCount = 0,
tokenRegExp = getTokenRegExp(),
match;
// iterate through each date token found.
while ( (match = tokenRegExp.exec(expFormat)) !== null ) {
var preMatch = expFormat.slice( index, match.index );
index = tokenRegExp.lastIndex;
// don't replace any matches that occur inside a string literal.
quoteCount += appendPreOrPostMatch( preMatch, regexp );
if ( quoteCount % 2 ) {
regexp.push( match[0] );
continue;
}
// add a regex group for the token.
var m = match[ 0 ],
len = m.length,
add;
switch ( m ) {
case "dddd": case "ddd":
case "MMMM": case "MMM":
case "gg": case "g":
add = "(\\D+)";
break;
case "tt": case "t":
add = "(\\D*)";
break;
case "yyyy":
case "fff":
case "ff":
case "f":
add = "(\\d{" + len + "})";
break;
case "dd": case "d":
case "MM": case "M":
case "yy": case "y":
case "HH": case "H":
case "hh": case "h":
case "mm": case "m":
case "ss": case "s":
add = "(\\d\\d?)";
break;
case "zzz":
add = "([+-]?\\d\\d?:\\d{2})";
break;
case "zz": case "z":
add = "([+-]?\\d\\d?)";
break;
case "/":
add = "(\\" + cal[ "/" ] + ")";
break;
default:
throw "Invalid date format pattern \'" + m + "\'.";
break;
}
if ( add ) {
regexp.push( add );
}
groups.push( match[0] );
}
appendPreOrPostMatch( expFormat.slice(index), regexp );
regexp.push( "$" );
// allow whitespace to differ when matching formats.
var regexpStr = regexp.join( "" ).replace( /\s+/g, "\\s+" ),
parseRegExp = { "regExp": regexpStr, "groups": groups };
// cache the regex for this format.
return re[ format ] = parseRegExp;
};
outOfRange = function( value, low, high ) {
return value < low || value > high;
};
toUpper = function( value ) {
// "he-IL" has non-breaking space in weekday names.
return value.split( "\u00A0" ).join( " " ).toUpperCase();
};
toUpperArray = function( arr ) {
var results = [];
for ( var i = 0, l = arr.length; i < l; i++ ) {
results[ i ] = toUpper( arr[i] );
}
return results;
};
parseExact = function( value, format, culture ) {
// try to parse the date string by matching against the format string
// while using the specified culture for date field names.
value = trim( value );
var cal = culture.calendar,
// convert date formats into regular expressions with groupings.
// use the regexp to determine the input format and extract the date fields.
parseInfo = getParseRegExp( cal, format ),
match = new RegExp( parseInfo.regExp ).exec( value );
if ( match === null ) {
return null;
}
// found a date format that matches the input.
var groups = parseInfo.groups,
era = null, year = null, month = null, date = null, weekDay = null,
hour = 0, hourOffset, min = 0, sec = 0, msec = 0, tzMinOffset = null,
pmHour = false;
// iterate the format groups to extract and set the date fields.
for ( var j = 0, jl = groups.length; j < jl; j++ ) {
var matchGroup = match[ j + 1 ];
if ( matchGroup ) {
var current = groups[ j ],
clength = current.length,
matchInt = parseInt( matchGroup, 10 );
switch ( current ) {
case "dd": case "d":
// Day of month.
date = matchInt;
// check that date is generally in valid range, also checking overflow below.
if ( outOfRange(date, 1, 31) ) return null;
break;
case "MMM": case "MMMM":
month = getMonthIndex( cal, matchGroup, clength === 3 );
if ( outOfRange(month, 0, 11) ) return null;
break;
case "M": case "MM":
// Month.
month = matchInt - 1;
if ( outOfRange(month, 0, 11) ) return null;
break;
case "y": case "yy":
case "yyyy":
year = clength < 4 ? expandYear( cal, matchInt ) : matchInt;
if ( outOfRange(year, 0, 9999) ) return null;
break;
case "h": case "hh":
// Hours (12-hour clock).
hour = matchInt;
if ( hour === 12 ) hour = 0;
if ( outOfRange(hour, 0, 11) ) return null;
break;
case "H": case "HH":
// Hours (24-hour clock).
hour = matchInt;
if ( outOfRange(hour, 0, 23) ) return null;
break;
case "m": case "mm":
// Minutes.
min = matchInt;
if ( outOfRange(min, 0, 59) ) return null;
break;
case "s": case "ss":
// Seconds.
sec = matchInt;
if ( outOfRange(sec, 0, 59) ) return null;
break;
case "tt": case "t":
// AM/PM designator.
// see if it is standard, upper, or lower case PM. If not, ensure it is at least one of
// the AM tokens. If not, fail the parse for this format.
pmHour = cal.PM && ( matchGroup === cal.PM[0] || matchGroup === cal.PM[1] || matchGroup === cal.PM[2] );
if (
!pmHour && (
!cal.AM || ( matchGroup !== cal.AM[0] && matchGroup !== cal.AM[1] && matchGroup !== cal.AM[2] )
)
) return null;
break;
case "f":
// Deciseconds.
case "ff":
// Centiseconds.
case "fff":
// Milliseconds.
msec = matchInt * Math.pow( 10, 3 - clength );
if ( outOfRange(msec, 0, 999) ) return null;
break;
case "ddd":
// Day of week.
case "dddd":
// Day of week.
weekDay = getDayIndex( cal, matchGroup, clength === 3 );
if ( outOfRange(weekDay, 0, 6) ) return null;
break;
case "zzz":
// Time zone offset in +/- hours:min.
var offsets = matchGroup.split( /:/ );
if ( offsets.length !== 2 ) return null;
hourOffset = parseInt( offsets[0], 10 );
if ( outOfRange(hourOffset, -12, 13) ) return null;
var minOffset = parseInt( offsets[1], 10 );
if ( outOfRange(minOffset, 0, 59) ) return null;
tzMinOffset = ( hourOffset * 60 ) + ( startsWith(matchGroup, "-") ? -minOffset : minOffset );
break;
case "z": case "zz":
// Time zone offset in +/- hours.
hourOffset = matchInt;
if ( outOfRange(hourOffset, -12, 13) ) return null;
tzMinOffset = hourOffset * 60;
break;
case "g": case "gg":
var eraName = matchGroup;
if ( !eraName || !cal.eras ) return null;
eraName = trim( eraName.toLowerCase() );
for ( var i = 0, l = cal.eras.length; i < l; i++ ) {
if ( eraName === cal.eras[i].name.toLowerCase() ) {
era = i;
break;
}
}
// could not find an era with that name
if ( era === null ) return null;
break;
}
}
}
var result = new Date(), defaultYear, convert = cal.convert;
defaultYear = convert ? convert.fromGregorian( result )[ 0 ] : result.getFullYear();
if ( year === null ) {
year = defaultYear;
}
else if ( cal.eras ) {
// year must be shifted to normal gregorian year
// but not if year was not specified, its already normal gregorian
// per the main if clause above.
year += cal.eras[( era || 0 )].offset;
}
// set default day and month to 1 and January, so if unspecified, these are the defaults
// instead of the current day/month.
if ( month === null ) {
month = 0;
}
if ( date === null ) {
date = 1;
}
// now have year, month, and date, but in the culture's calendar.
// convert to gregorian if necessary
if ( convert ) {
result = convert.toGregorian( year, month, date );
// conversion failed, must be an invalid match
if ( result === null ) return null;
}
else {
// have to set year, month and date together to avoid overflow based on current date.
result.setFullYear( year, month, date );
// check to see if date overflowed for specified month (only checked 1-31 above).
if ( result.getDate() !== date ) return null;
// invalid day of week.
if ( weekDay !== null && result.getDay() !== weekDay ) {
return null;
}
}
// if pm designator token was found make sure the hours fit the 24-hour clock.
if ( pmHour && hour < 12 ) {
hour += 12;
}
result.setHours( hour, min, sec, msec );
if ( tzMinOffset !== null ) {
// adjust timezone to utc before applying local offset.
var adjustedMin = result.getMinutes() - ( tzMinOffset + result.getTimezoneOffset() );
// Safari limits hours and minutes to the range of -127 to 127. We need to use setHours
// to ensure both these fields will not exceed this range. adjustedMin will range
// somewhere between -1440 and 1500, so we only need to split this into hours.
result.setHours( result.getHours() + parseInt(adjustedMin / 60, 10), adjustedMin % 60 );
}
return result;
};
}());
parseNegativePattern = function( value, nf, negativePattern ) {
var neg = nf[ "-" ],
pos = nf[ "+" ],
ret;
switch ( negativePattern ) {
case "n -":
neg = " " + neg;
pos = " " + pos;
// fall through
case "n-":
if ( endsWith(value, neg) ) {
ret = [ "-", value.substr(0, value.length - neg.length) ];
}
else if ( endsWith(value, pos) ) {
ret = [ "+", value.substr(0, value.length - pos.length) ];
}
break;
case "- n":
neg += " ";
pos += " ";
// fall through
case "-n":
if ( startsWith(value, neg) ) {
ret = [ "-", value.substr(neg.length) ];
}
else if ( startsWith(value, pos) ) {
ret = [ "+", value.substr(pos.length) ];
}
break;
case "(n)":
if ( startsWith(value, "(") && endsWith(value, ")") ) {
ret = [ "-", value.substr(1, value.length - 2) ];
}
break;
}
return ret || [ "", value ];
};
//
// public instance functions
//
Globalize.prototype.findClosestCulture = function( cultureSelector ) {
return Globalize.findClosestCulture.call( this, cultureSelector );
};
Globalize.prototype.format = function( value, format, cultureSelector ) {
return Globalize.format.call( this, value, format, cultureSelector );
};
Globalize.prototype.localize = function( key, cultureSelector ) {
return Globalize.localize.call( this, key, cultureSelector );
};
Globalize.prototype.parseInt = function( value, radix, cultureSelector ) {
return Globalize.parseInt.call( this, value, radix, cultureSelector );
};
Globalize.prototype.parseFloat = function( value, radix, cultureSelector ) {
return Globalize.parseFloat.call( this, value, radix, cultureSelector );
};
Globalize.prototype.culture = function( cultureSelector ) {
return Globalize.culture.call( this, cultureSelector );
};
//
// public singleton functions
//
Globalize.addCultureInfo = function( cultureName, baseCultureName, info ) {
var base = {},
isNew = false;
if ( typeof cultureName !== "string" ) {
// cultureName argument is optional string. If not specified, assume info is first
// and only argument. Specified info deep-extends current culture.
info = cultureName;
cultureName = this.culture().name;
base = this.cultures[ cultureName ];
} else if ( typeof baseCultureName !== "string" ) {
// baseCultureName argument is optional string. If not specified, assume info is second
// argument. Specified info deep-extends specified culture.
// If specified culture does not exist, create by deep-extending default
info = baseCultureName;
isNew = ( this.cultures[ cultureName ] == null );
base = this.cultures[ cultureName ] || this.cultures[ "default" ];
} else {
// cultureName and baseCultureName specified. Assume a new culture is being created
// by deep-extending an specified base culture
isNew = true;
base = this.cultures[ baseCultureName ];
}
this.cultures[ cultureName ] = extend(true, {},
base,
info
);
// Make the standard calendar the current culture if it's a new culture
if ( isNew ) {
this.cultures[ cultureName ].calendar = this.cultures[ cultureName ].calendars.standard;
}
};
Globalize.findClosestCulture = function( name ) {
var match;
if ( !name ) {
return this.findClosestCulture( this.cultureSelector ) || this.cultures[ "default" ];
}
if ( typeof name === "string" ) {
name = name.split( "," );
}
if ( isArray(name) ) {
var lang,
cultures = this.cultures,
list = name,
i, l = list.length,
prioritized = [];
for ( i = 0; i < l; i++ ) {
name = trim( list[i] );
var pri, parts = name.split( ";" );
lang = trim( parts[0] );
if ( parts.length === 1 ) {
pri = 1;
}
else {
name = trim( parts[1] );
if ( name.indexOf("q=") === 0 ) {
name = name.substr( 2 );
pri = parseFloat( name );
pri = isNaN( pri ) ? 0 : pri;
}
else {
pri = 1;
}
}
prioritized.push({ lang: lang, pri: pri });
}
prioritized.sort(function( a, b ) {
return a.pri < b.pri ? 1 : -1;
});
// exact match
for ( i = 0; i < l; i++ ) {
lang = prioritized[ i ].lang;
match = cultures[ lang ];
if ( match ) {
return match;
}
}
// neutral language match
for ( i = 0; i < l; i++ ) {
lang = prioritized[ i ].lang;
do {
var index = lang.lastIndexOf( "-" );
if ( index === -1 ) {
break;
}
// strip off the last part. e.g. en-US => en
lang = lang.substr( 0, index );
match = cultures[ lang ];
if ( match ) {
return match;
}
}
while ( 1 );
}
// last resort: match first culture using that language
for ( i = 0; i < l; i++ ) {
lang = prioritized[ i ].lang;
for ( var cultureKey in cultures ) {
var culture = cultures[ cultureKey ];
if ( culture.language == lang ) {
return culture;
}
}
}
}
else if ( typeof name === "object" ) {
return name;
}
return match || null;
};
Globalize.format = function( value, format, cultureSelector ) {
culture = this.findClosestCulture( cultureSelector );
if ( value instanceof Date ) {
value = formatDate( value, format, culture );
}
else if ( typeof value === "number" ) {
value = formatNumber( value, format, culture );
}
return value;
};
Globalize.localize = function( key, cultureSelector ) {
return this.findClosestCulture( cultureSelector ).messages[ key ] ||
this.cultures[ "default" ].messages[ key ];
};
Globalize.parseDate = function( value, formats, culture ) {
culture = this.findClosestCulture( culture );
var date, prop, patterns;
if ( formats ) {
if ( typeof formats === "string" ) {
formats = [ formats ];
}
if ( formats.length ) {
for ( var i = 0, l = formats.length; i < l; i++ ) {
var format = formats[ i ];
if ( format ) {
date = parseExact( value, format, culture );
if ( date ) {
break;
}
}
}
}
} else {
patterns = culture.calendar.patterns;
for ( prop in patterns ) {
date = parseExact( value, patterns[prop], culture );
if ( date ) {
break;
}
}
}
return date || null;
};
Globalize.parseInt = function( value, radix, cultureSelector ) {
return truncate( Globalize.parseFloat(value, radix, cultureSelector) );
};
Globalize.parseFloat = function( value, radix, cultureSelector ) {
// radix argument is optional
if ( typeof radix !== "number" ) {
cultureSelector = radix;
radix = 10;
}
var culture = this.findClosestCulture( cultureSelector );
var ret = NaN,
nf = culture.numberFormat;
if ( value.indexOf(culture.numberFormat.currency.symbol) > -1 ) {
// remove currency symbol
value = value.replace( culture.numberFormat.currency.symbol, "" );
// replace decimal seperator
value = value.replace( culture.numberFormat.currency["."], culture.numberFormat["."] );
}
// trim leading and trailing whitespace
value = trim( value );
// allow infinity or hexidecimal
if ( regexInfinity.test(value) ) {
ret = parseFloat( value );
}
else if ( !radix && regexHex.test(value) ) {
ret = parseInt( value, 16 );
}
else {
// determine sign and number
var signInfo = parseNegativePattern( value, nf, nf.pattern[0] ),
sign = signInfo[ 0 ],
num = signInfo[ 1 ];
// #44 - try parsing as "(n)"
if ( sign === "" && nf.pattern[0] !== "(n)" ) {
signInfo = parseNegativePattern( value, nf, "(n)" );
sign = signInfo[ 0 ];
num = signInfo[ 1 ];
}
// try parsing as "-n"
if ( sign === "" && nf.pattern[0] !== "-n" ) {
signInfo = parseNegativePattern( value, nf, "-n" );
sign = signInfo[ 0 ];
num = signInfo[ 1 ];
}
sign = sign || "+";
// determine exponent and number
var exponent,
intAndFraction,
exponentPos = num.indexOf( "e" );
if ( exponentPos < 0 ) exponentPos = num.indexOf( "E" );
if ( exponentPos < 0 ) {
intAndFraction = num;
exponent = null;
}
else {
intAndFraction = num.substr( 0, exponentPos );
exponent = num.substr( exponentPos + 1 );
}
// determine decimal position
var integer,
fraction,
decSep = nf[ "." ],
decimalPos = intAndFraction.indexOf( decSep );
if ( decimalPos < 0 ) {
integer = intAndFraction;
fraction = null;
}
else {
integer = intAndFraction.substr( 0, decimalPos );
fraction = intAndFraction.substr( decimalPos + decSep.length );
}
// handle groups (e.g. 1,000,000)
var groupSep = nf[ "," ];
integer = integer.split( groupSep ).join( "" );
var altGroupSep = groupSep.replace( /\u00A0/g, " " );
if ( groupSep !== altGroupSep ) {
integer = integer.split( altGroupSep ).join( "" );
}
// build a natively parsable number string
var p = sign + integer;
if ( fraction !== null ) {
p += "." + fraction;
}
if ( exponent !== null ) {
// exponent itself may have a number patternd
var expSignInfo = parseNegativePattern( exponent, nf, "-n" );
p += "e" + ( expSignInfo[0] || "+" ) + expSignInfo[ 1 ];
}
if ( regexParseFloat.test(p) ) {
ret = parseFloat( p );
}
}
return ret;
};
Globalize.culture = function( cultureSelector ) {
// setter
if ( typeof cultureSelector !== "undefined" ) {
this.cultureSelector = cultureSelector;
}
// getter
return this.findClosestCulture( cultureSelector ) || this.culture[ "default" ];
};
}( this ));
/*! jQuery v1.7 jquery.com | jquery.org/license */
(function(a,b){function cA(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cx(a){if(!cm[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cn||(cn=c.createElement("iframe"),cn.frameBorder=cn.width=cn.height=0),b.appendChild(cn);if(!co||!cn.createElement)co=(cn.contentWindow||cn.contentDocument).document,co.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),co.close();d=co.createElement(a),co.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cn)}cm[a]=e}return cm[a]}function cw(a,b){var c={};f.each(cs.concat.apply([],cs.slice(0,b)),function(){c[this]=a});return c}function cv(){ct=b}function cu(){setTimeout(cv,0);return ct=f.now()}function cl(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ck(){try{return new a.XMLHttpRequest}catch(b){}}function ce(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cd(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function cc(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bG.test(a)?d(a,e):cc(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)cc(a+"["+e+"]",b[e],c,d);else d(a,b)}function cb(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function ca(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bV,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=ca(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=ca(a,c,d,e,"*",g));return l}function b_(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bR),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bE(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bz:bA;if(d>0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bB(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function br(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bi,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bq(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bp(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bp)}function bp(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bo(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bn(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bm(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bl(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function X(a){var b=Y.split(" "),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function W(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(R.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(){return!0}function M(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function K(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(K,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.add(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;B.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return a!=null&&m.test(a)&&!isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:H?function(a){return a==null?"":H.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?F.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(I)return I.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=G.call(arguments,2),g=function(){return a.apply(c,f.concat(G.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=s.exec(a)||t.exec(a)||u.exec(a)||a.indexOf("compatible")<0&&v.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){J["[object "+b+"]"]=b.toLowerCase()}),A=e.uaMatch(z),A.browser&&(e.browser[A.browser]=!0,e.browser.version=A.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?C=function(){c.removeEventListener("DOMContentLoaded",C,!1),e.ready()}:c.attachEvent&&(C=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",C),e.ready())}),typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return e});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){return i.done.apply(i,arguments).fail.apply(i,arguments)},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var a=c.createElement("div"),b=c.documentElement,d,e,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;a.setAttribute("className","t"),a.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/><nav></nav>",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,unknownElems:!!a.getElementsByTagName("nav").length,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",enctype:!!c.createElement("form").enctype,submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.lastChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-999px",top:"-999px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;f(function(){var a,b,d,e,g,h,i=1,j="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",l="visibility:hidden;border:0;",n="style='"+j+"border:5px solid #000;padding:0;'",p="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>";m=c.getElementsByTagName("body")[0];!m||(a=c.createElement("div"),a.style.cssText=l+"width:0;height:0;position:static;top:0;margin-top:"+i+"px",m.insertBefore(a,m.firstChild),o=c.createElement("div"),o.style.cssText=j+l,o.innerHTML=p,a.appendChild(o),b=o.firstChild,d=b.firstChild,g=b.nextSibling.firstChild.firstChild,h={doesNotAddBorder:d.offsetTop!==5,doesAddBorderForTableAndCells:g.offsetTop===5},d.style.position="fixed",d.style.top="20px",h.fixedPosition=d.offsetTop===20||d.offsetTop===15,d.style.position=d.style.top="",b.style.overflow="hidden",b.style.position="relative",h.subtractsBorderForOverflowNotVisible=d.offsetTop===-5,h.doesNotIncludeMarginInBodyOffset=m.offsetTop!==i,m.removeChild(a),o=a=null,f.extend(k,h))}),o.innerHTML="",n.removeChild(o),o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[f.expando]:a[f.expando]&&f.expando,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[f.expando]=n=++f.uuid:n=f.expando),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[f.expando]:f.expando;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)?b=b:b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" "));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[f.expando]:a.removeAttribute?a.removeAttribute(f.expando):a[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];if(!arguments.length){if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}return b}e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!a||j===3||j===8||j===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g},removeAttr:function(a,b){var c,d,e,g,h=0;if(a.nodeType===1){d=(b||"").split(p),g=d.length;for(;h<g;h++)e=d[h].toLowerCase(),c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1)}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return b;h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/\.(.*)$/,A=/^(?:textarea|input|select)$/i,B=/\./g,C=/ /g,D=/[^\w\s.|`]/g,E=/^([^\.]*)?(?:\.(.+))?$/,F=/\bhover(\.\S+)?/,G=/^key/,H=/^(?:mouse|contextmenu)|click/,I=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,J=function(a){var b=I.exec(a);b&&
(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},K=function(a,b){return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||a.id===b[2])&&(!b[3]||b[3].test(a.className))},L=function(a){return f.event.special.hover?a:a.replace(F,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=L(c).split(" ");for(k=0;k<c.length;k++){l=E.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,namespace:n.join(".")},p),g&&(o.quick=J(g),!o.quick&&f.expr.match.POS.test(g)&&(o.isPositional=!0)),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d){var e=f.hasData(a)&&f._data(a),g,h,i,j,k,l,m,n,o,p,q;if(!!e&&!!(m=e.events)){b=L(b||"").split(" ");for(g=0;g<b.length;g++){h=E.exec(b[g])||[],i=h[1],j=h[2];if(!i){j=j?"."+j:"";for(l in m)f.event.remove(a,l+j,c,d);return}n=f.event.special[i]||{},i=(d?n.delegateType:n.bindType)||i,p=m[i]||[],k=p.length,j=j?new RegExp("(^|\\.)"+j.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;if(c||j||d||n.remove)for(l=0;l<p.length;l++){q=p[l];if(!c||c.guid===q.guid)if(!j||j.test(q.namespace))if(!d||d===q.selector||d==="**"&&q.selector)p.splice(l--,1),q.selector&&p.delegateCount--,n.remove&&n.remove.call(a,q)}else p.length=0;p.length===0&&k!==p.length&&((!n.teardown||n.teardown.call(a,j)===!1)&&f.removeEvent(a,i,e.handle),delete m[i])}f.isEmptyObject(m)&&(o=e.handle,o&&(o.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"",(g||!e)&&c.preventDefault();if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,n=null;for(m=e.parentNode;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length;l++){m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d);if(c.isPropagationStopped())break}c.type=h,c.isDefaultPrevented()||(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=(f.event.special[c.type]||{}).handle,j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click"))for(m=c.target;m!=this;m=m.parentNode||this){o={},q=[];for(k=0;k<e;k++)r=d[k],s=r.selector,t=o[s],r.isPositional?t=(t||(o[s]=f(s))).index(m)>=0:t===b&&(t=o[s]=r.quick?K(m,r.quick):f(m).is(s)),t&&q.push(r);q.length&&j.push({elem:m,matches:q})}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){p=j[k],c.currentTarget=p.elem;for(l=0;l<p.matches.length&&!c.isImmediatePropagationStopped();l++){r=p.matches[l];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=(i||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement wheelDelta".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},focus:{delegateType:"focusin",noBubble:!0},blur:{delegateType:"focusout",noBubble:!0},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?N:M):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=N;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=N;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=N,this.stopPropagation()},isDefaultPrevented:M,isPropagationStopped:M,isImmediatePropagationStopped:M},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]=f.event.special[b]={delegateType:b,bindType:b,handle:function(a){var b=this,c=a.relatedTarget,d=a.handleObj,e=d.selector,g,h;if(!c||d.origType===a.type||c!==b&&!f.contains(b,c))g=a.type,a.type=d.origType,h=d.handler.apply(this,arguments),a.type=g;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(A.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;A.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return A.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=M;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=M);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),G.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),H.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw"Syntax error, unrecognized expression: "+a};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var O=/Until$/,P=/^(?:parents|prevUntil|prevAll)/,Q=/,/,R=/^.[^:#\[\.,]*$/,S=Array.prototype.slice,T=f.expr.match.POS,U={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(W(this,a,!1),"not",a)},filter:function(a){return this.pushStack(W(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?T.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=T.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var Y="abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",Z=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,_=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,ba=/<([\w:]+)/,bb=/<tbody/i,bc=/<|&#?\w+;/,bd=/<(?:script|style)/i,be=/<(?:script|object|embed|option|style)/i,bf=new RegExp("<(?:"+Y.replace(" ","|")+")","i"),bg=/checked\s*(?:[^=]|=\s*.checked.)/i,bh=/\/(java|ecma)script/i,bi=/^\s*<!(?:\[CDATA\[|\-\-)/,bj={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bk=X(c);bj.optgroup=bj.option,bj.tbody=bj.tfoot=bj.colgroup=bj.caption=bj.thead,bj.th=bj.td,f.support.htmlSerialize||(bj._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after"
,arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Z,""):null;if(typeof a=="string"&&!bd.test(a)&&(f.support.leadingWhitespace||!$.test(a))&&!bj[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(_,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bg.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bl(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,br)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!be.test(j)&&(f.support.checkClone||!bg.test(j))&&!f.support.unknownElems&&bf.test(j)&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bn(a,d),e=bo(a),g=bo(d);for(h=0;e[h];++h)g[h]&&bn(e[h],g[h])}if(b){bm(a,d);if(c){e=bo(a),g=bo(d);for(h=0;e[h];++h)bm(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!bc.test(k))k=b.createTextNode(k);else{k=k.replace(_,"<$1></$2>");var l=(ba.exec(k)||["",""])[1].toLowerCase(),m=bj[l]||bj._default,n=m[0],o=b.createElement("div");b===c?bk.appendChild(o):X(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=bb.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&$.test(k)&&o.insertBefore(b.createTextNode($.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bq(k[i]);else bq(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||bh.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bs=/alpha\([^)]*\)/i,bt=/opacity=([^)]*)/,bu=/([A-Z]|^ms)/g,bv=/^-?\d+(?:px)?$/i,bw=/^-?\d/,bx=/^([\-+])=([\-+.\de]+)/,by={position:"absolute",visibility:"hidden",display:"block"},bz=["Left","Right"],bA=["Top","Bottom"],bB,bC,bD;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bB(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bx.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bB)return bB(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bE(a,b,d);f.swap(a,by,function(){e=bE(a,b,d)});return e}},set:function(a,b){if(!bv.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bt.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bs,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bs.test(g)?g.replace(bs,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bB(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bC=function(a,c){var d,e,g;c=c.replace(bu,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bD=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bv.test(f)&&bw.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bB=bC||bD,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bF=/%20/g,bG=/\[\]$/,bH=/\r?\n/g,bI=/#.*$/,bJ=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bK=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bL=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bM=/^(?:GET|HEAD)$/,bN=/^\/\//,bO=/\?/,bP=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bQ=/^(?:select|textarea)/i,bR=/\s+/,bS=/([?&])_=[^&]*/,bT=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bU=f.fn.load,bV={},bW={},bX,bY,bZ=["*/"]+["*"];try{bX=e.href}catch(b$){bX=c.createElement("a"),bX.href="",bX=bX.href}bY=bT.exec(bX.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bU)return bU.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bP,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bQ.test(this.nodeName)||bK.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bH,"\r\n")}}):{name:b.name,value:c.replace(bH,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?cb(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),cb(a,b);return a},ajaxSettings:{url:bX,isLocal:bL.test(bY[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bZ},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:b_(bV),ajaxTransport:b_(bW),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cd(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=ce(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bJ.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bI,"").replace(bN,bY[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bR),d.crossDomain==null&&(r=bT.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bY[1]&&r[2]==bY[2]&&(r[3]||(r[1]==="http:"?80:443))==(bY[3]||(bY[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),ca(bV,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bM.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bO.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bS,"$1_="+x);d.url=y+(y===d.url?(bO.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bZ+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=ca(bW,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){s<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)cc(g,a[g],c,e);return d.join("&").replace(bF,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cf=f.now(),cg=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cf++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cg.test(b.url)||e&&cg.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cg,l),b.url===j&&(e&&(k=k.replace(cg,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ch=a.ActiveXObject?function(){for(var a in cj)cj[a](0,1)}:!1,ci=0,cj;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ck()||cl()}:ck,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ch&&delete cj[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++ci,ch&&(cj||(cj={},f(a).unload(ch)),cj[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cm={},cn,co,cp=/^(?:toggle|show|hide)$/,cq=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cr,cs=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],ct;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cw("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cx(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cw("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cw("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cx(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cp.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=cq.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cw("show",1),slideUp:cw("hide",1),slideToggle:cw("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=ct||cu(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cr&&(cr=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=ct||cu(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cr),cr=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now))}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cy=/^t(?:able|d|h)$/i,cz=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cA(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cy.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cz.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cz.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cA(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cA(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window);
\ No newline at end of file
/*
* jQuery Templates Plugin 1.0.0pre
* http://github.com/jquery/jquery-tmpl
* Requires jQuery 1.4.2
*
* Copyright Software Freedom Conservancy, Inc.
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
(function(a){var r=a.fn.domManip,d="_tmplitem",q=/^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,b={},f={},e,p={key:0,data:{}},i=0,c=0,l=[];function g(g,d,h,e){var c={data:e||(e===0||e===false)?e:d?d.data:{},_wrap:d?d._wrap:null,tmpl:null,parent:d||null,nodes:[],calls:u,nest:w,wrap:x,html:v,update:t};g&&a.extend(c,g,{nodes:[],parent:d});if(h){c.tmpl=h;c._ctnt=c._ctnt||c.tmpl(a,c);c.key=++i;(l.length?f:b)[i]=c}return c}a.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(f,d){a.fn[f]=function(n){var g=[],i=a(n),k,h,m,l,j=this.length===1&&this[0].parentNode;e=b||{};if(j&&j.nodeType===11&&j.childNodes.length===1&&i.length===1){i[d](this[0]);g=this}else{for(h=0,m=i.length;h<m;h++){c=h;k=(h>0?this.clone(true):this).get();a(i[h])[d](k);g=g.concat(k)}c=0;g=this.pushStack(g,f,i.selector)}l=e;e=null;a.tmpl.complete(l);return g}});a.fn.extend({tmpl:function(d,c,b){return a.tmpl(this[0],d,c,b)},tmplItem:function(){return a.tmplItem(this[0])},template:function(b){return a.template(b,this[0])},domManip:function(d,m,k){if(d[0]&&a.isArray(d[0])){var g=a.makeArray(arguments),h=d[0],j=h.length,i=0,f;while(i<j&&!(f=a.data(h[i++],"tmplItem")));if(f&&c)g[2]=function(b){a.tmpl.afterManip(this,b,k)};r.apply(this,g)}else r.apply(this,arguments);c=0;!e&&a.tmpl.complete(b);return this}});a.extend({tmpl:function(d,h,e,c){var i,k=!c;if(k){c=p;d=a.template[d]||a.template(null,d);f={}}else if(!d){d=c.tmpl;b[c.key]=c;c.nodes=[];c.wrapped&&n(c,c.wrapped);return a(j(c,null,c.tmpl(a,c)))}if(!d)return[];if(typeof h==="function")h=h.call(c||{});e&&e.wrapped&&n(e,e.wrapped);i=a.isArray(h)?a.map(h,function(a){return a?g(e,c,d,a):null}):[g(e,c,d,h)];return k?a(j(c,null,i)):i},tmplItem:function(b){var c;if(b instanceof a)b=b[0];while(b&&b.nodeType===1&&!(c=a.data(b,"tmplItem"))&&(b=b.parentNode));return c||p},template:function(c,b){if(b){if(typeof b==="string")b=o(b);else if(b instanceof a)b=b[0]||{};if(b.nodeType)b=a.data(b,"tmpl")||a.data(b,"tmpl",o(b.innerHTML));return typeof c==="string"?(a.template[c]=b):b}return c?typeof c!=="string"?a.template(null,c):a.template[c]||a.template(null,q.test(c)?c:a(c)):null},encode:function(a){return(""+a).split("<").join("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;")}});a.extend(a.tmpl,{tag:{tmpl:{_default:{$2:"null"},open:"if($notnull_1){__=__.concat($item.nest($1,$2));}"},wrap:{_default:{$2:"null"},open:"$item.calls(__,$1,$2);__=[];",close:"call=$item.calls();__=call._.concat($item.wrap(call,__));"},each:{_default:{$2:"$index, $value"},open:"if($notnull_1){$.each($1a,function($2){with(this){",close:"}});}"},"if":{open:"if(($notnull_1) && $1a){",close:"}"},"else":{_default:{$1:"true"},open:"}else if(($notnull_1) && $1a){"},html:{open:"if($notnull_1){__.push($1a);}"},"=":{_default:{$1:"$data"},open:"if($notnull_1){__.push($.encode($1a));}"},"!":{open:""}},complete:function(){b={}},afterManip:function(f,b,d){var e=b.nodeType===11?a.makeArray(b.childNodes):b.nodeType===1?[b]:[];d.call(f,b);m(e);c++}});function j(e,g,f){var b,c=f?a.map(f,function(a){return typeof a==="string"?e.key?a.replace(/(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g,"$1 "+d+'="'+e.key+'" $2'):a:j(a,e,a._ctnt)}):e;if(g)return c;c=c.join("");c.replace(/^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/,function(f,c,e,d){b=a(e).get();m(b);if(c)b=k(c).concat(b);if(d)b=b.concat(k(d))});return b?b:k(c)}function k(c){var b=document.createElement("div");b.innerHTML=c;return a.makeArray(b.childNodes)}function o(b){return new Function("jQuery","$item","var $=jQuery,call,__=[],$data=$item.data;with($data){__.push('"+a.trim(b).replace(/([\\'])/g,"\\$1").replace(/[\r\t\n]/g," ").replace(/\$\{([^\}]*)\}/g,"{{= $1}}").replace(/\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,function(m,l,k,g,b,c,d){var j=a.tmpl.tag[k],i,e,f;if(!j)throw"Unknown template tag: "+k;i=j._default||[];if(c&&!/\w$/.test(b)){b+=c;c=""}if(b){b=h(b);d=d?","+h(d)+")":c?")":"";e=c?b.indexOf(".")>-1?b+h(c):"("+b+").call($item"+d:b;f=c?e:"(typeof("+b+")==='function'?("+b+").call($item):("+b+"))"}else f=e=i.$1||"null";g=h(g);return"');"+j[l?"close":"open"].split("$notnull_1").join(b?"typeof("+b+")!=='undefined' && ("+b+")!=null":"true").split("$1a").join(f).split("$1").join(e).split("$2").join(g||i.$2||"")+"__.push('"})+"');}return __;")}function n(c,b){c._wrap=j(c,true,a.isArray(b)?b:[q.test(b)?b:a(b).html()]).join("")}function h(a){return a?a.replace(/\\'/g,"'").replace(/\\\\/g,"\\"):null}function s(b){var a=document.createElement("div");a.appendChild(b.cloneNode(true));return a.innerHTML}function m(o){var n="_"+c,k,j,l={},e,p,h;for(e=0,p=o.length;e<p;e++){if((k=o[e]).nodeType!==1)continue;j=k.getElementsByTagName("*");for(h=j.length-1;h>=0;h--)m(j[h]);m(k)}function m(j){var p,h=j,k,e,m;if(m=j.getAttribute(d)){while(h.parentNode&&(h=h.parentNode).nodeType===1&&!(p=h.getAttribute(d)));if(p!==m){h=h.parentNode?h.nodeType===11?0:h.getAttribute(d)||0:0;if(!(e=b[m])){e=f[m];e=g(e,b[h]||f[h]);e.key=++i;b[i]=e}c&&o(m)}j.removeAttribute(d)}else if(c&&(e=a.data(j,"tmplItem"))){o(e.key);b[e.key]=e;h=a.data(j.parentNode,"tmplItem");h=h?h.key:0}if(e){k=e;while(k&&k.key!=h){k.nodes.push(j);k=k.parent}delete e._ctnt;delete e._wrap;a.data(j,"tmplItem",e)}function o(a){a=a+n;e=l[a]=l[a]||g(e,b[e.parent.key+n]||e.parent)}}}function u(a,d,c,b){if(!a)return l.pop();l.push({_:a,tmpl:d,item:this,data:c,options:b})}function w(d,c,b){return a.tmpl(a.template(d),c,b,this)}function x(b,d){var c=b.options||{};c.wrapped=d;return a.tmpl(a.template(b.tmpl),b.data,c,b.item)}function v(d,c){var b=this._wrap;return a.map(a(a.isArray(b)?b.join(""):b).filter(d||"*"),function(a){return c?a.innerText||a.textContent:a.outerHTML||s(a)})}function t(){var b=this.nodes;a.tmpl(null,null,null,this).insertBefore(b[0]);a(b).remove()}})(jQuery);
\ No newline at end of file
/*
http://www.JSON.org/json2.js
2009-09-29
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
This file creates a global JSON object containing two methods: stringify
and parse.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or '&nbsp;'),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the value
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(---current time---)"]'
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
*/
/*jslint evil: true, strict: false */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
*/
// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
if (!this.JSON) {
this.JSON = {};
}
(function () {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function (key) {
return isFinite(this.valueOf()) ?
this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z' : null;
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function (key) {
return this.valueOf();
};
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ?
'"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c :
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' :
'"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' :
gap ? '[\n' + gap +
partial.join(',\n' + gap) + '\n' +
mind + ']' :
'[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
k = rep[i];
if (typeof k === 'string') {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' :
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
mind + '}' : '{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
};
}
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function' ?
walk({'': j}, '') : j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
};
}
}());
\ No newline at end of file
/*
mColorPicker
Version: 1.0 r36
Copyright (c) 2010 Meta100 LLC.
http://www.meta100.com/
Licensed under the MIT license
http://www.opensource.org/licenses/mit-license.php
*/
(function($){var $o;$.fn.mColorPicker=function(a){$o=$.extend($.fn.mColorPicker.defaults,a);if($o.swatches.length<10)$o.swatches=$.fn.mColorPicker.defaults.swatches;$("div#mColorPicker").length<1&&$.fn.mColorPicker.drawPicker();$("#css_disabled_color_picker").length<1&&$("head").prepend('<style id="css_disabled_color_picker" type="text/css">.mColorPicker[disabled] + span, .mColorPicker[disabled="disabled"] + span, .mColorPicker[disabled="true"] + span {filter:alpha(opacity=50);-moz-opacity:0.5;-webkit-opacity:0.5;-khtml-opacity: 0.5;opacity: 0.5;}</style>');this.each(function(){$.fn.mColorPicker.drawPickerTriggers($(this))});return this};$.fn.mColorPicker.currentColor=false;$.fn.mColorPicker.currentValue=false;$.fn.mColorPicker.color=false;$.fn.mColorPicker.init={replace:"[type=color]",index:0,enhancedSwatches:true,allowTransparency:true,checkRedraw:"DOMUpdated",liveEvents:false,showLogo:true};$.fn.mColorPicker.defaults={imageFolder:"images/",swatches:"#ffffff,#ffff00,#00ff00,#00ffff,#0000ff,#ff00ff,#ff0000,#4c2b11,#3b3b3b,#000000".split(",")};$.fn.mColorPicker.liveEvents=function(){$.fn.mColorPicker.init.liveEvents=true;$.fn.mColorPicker.init.checkRedraw&&$.fn.mColorPicker.init.replace&&$(document).bind($.fn.mColorPicker.init.checkRedraw+".mColorPicker",function(){$('input[data-mcolorpicker!="true"]').filter(function(){return $.fn.mColorPicker.init.replace=="[type=color]"?this.getAttribute("type")=="color":$(this).is($.fn.mColorPicker.init.replace)}).mColorPicker()})};$.fn.mColorPicker.drawPickerTriggers=function(a){if(a[0].nodeName.toLowerCase()!="input")return false;var b=a.attr("id")||"color_"+$.fn.mColorPicker.init.index++,d=false;a.attr("id",b);if(a.attr("text")=="hidden"||a.attr("data-text")=="hidden")d=true;var c=a.val(),e=a.width()>0?a.width():parseInt(a.css("width"),10),h=a.height()?a.height():parseInt(a.css("height"),10),j=a.css("float"),f=c=="transparent"?"url('"+$o.imageFolder+"/grid.gif')":"",g="";$("body").append('<span id="color_work_area"></span>');$("span#color_work_area").append(a.clone(true));g=$("span#color_work_area").html().replace(/type="color"/gi,"").replace(/input /gi,d?'input type="hidden"':'input type="text"');$("span#color_work_area").html("").remove();a.after(d?'<span style="cursor:pointer;border:1px solid black;float:'+j+";width:"+e+"px;height:"+h+'px;" id="icp_'+b+'">&nbsp;</span>':"").after(g).remove();$("#"+b).val(c);d?$("#icp_"+b).css({"background-color":c,"background-image":f,display:"inline-block"}).attr("class",($("#"+b).attr("class")||"")+" mColorPickerTrigger"):$("#"+b).css({"background-color":c,"background-image":f}).css({color:$.fn.mColorPicker.textColor($("#"+b).css("background-color"))}).after('<span style="cursor:pointer;" id="icp_'+b+'" class="mColorPickerTrigger"><img src="'+$o.imageFolder+'color.png" style="border:0;margin:0 0 0 3px" align="absmiddle"></span>').addClass("mColorPickerInput");$("#icp_"+b).attr("data-mcolorpicker","true");$("#"+b).addClass("mColorPicker");return $("#"+b)};$.fn.mColorPicker.drawPicker=function(){$(document.createElement("div")).attr("id","mColorPicker").css("display","none").html('<div id="mColorPickerWrapper"><div id="mColorPickerImg" class="mColor"></div><div id="mColorPickerImgGray" class="mColor"></div><div id="mColorPickerSwatches"><div class="mClear"></div></div><div id="mColorPickerFooter"><input type="text" size="8" id="mColorPickerInput"/></div></div>').appendTo("body");$(document.createElement("div")).attr("id","mColorPickerBg").css({display:"none"}).appendTo("body");for(n=9;n>-1;n--)$(document.createElement("div")).attr({id:"cell"+n,"class":"mPastColor"+(n>0?" mNoLeftBorder":"")}).html("&nbsp;").prependTo("#mColorPickerSwatches");$("#mColorPicker").css({border:"1px solid #ccc",color:"#fff","z-index":999998,width:"194px",height:"184px","font-size":"12px","font-family":"times"});$(".mPastColor").css({height:"18px",width:"18px",border:"1px solid #000","float":"left"});$("#colorPreview").css({height:"50px"});$(".mNoLeftBorder").css({"border-left":0});$(".mClear").css({clear:"both"});$("#mColorPickerWrapper").css({position:"relative",border:"solid 1px gray","z-index":999999});$("#mColorPickerImg").css({height:"128px",width:"192px",border:0,cursor:"crosshair","background-image":"url('"+$o.imageFolder+"colorpicker.png')"});$("#mColorPickerImgGray").css({height:"8px",width:"192px",border:0,cursor:"crosshair","background-image":"url('"+$o.imageFolder+"graybar.jpg')"});$("#mColorPickerInput").css({border:"solid 1px gray","font-size":"10pt",margin:"3px",width:"80px"});$("#mColorPickerImgGrid").css({border:0,height:"20px",width:"20px","vertical-align":"text-bottom"});$("#mColorPickerSwatches").css({"border-right":"1px solid #000"});$("#mColorPickerFooter").css({"background-image":"url('"+$o.imageFolder+"grid.gif')",position:"relative",height:"26px"});$.fn.mColorPicker.init.allowTransparency&&$("#mColorPickerFooter").prepend('<span id="mColorPickerTransparent" class="mColor" style="font-size:16px;color:#000;padding-right:30px;padding-top:3px;cursor:pointer;overflow:hidden;float:right;">transparent</span>');$.fn.mColorPicker.init.showLogo&&$("#mColorPickerFooter").prepend('<a href="http://meta100.com/" title="Meta100 - Designing Fun" alt="Meta100 - Designing Fun" style="float:right;" target="_blank"><img src="'+$o.imageFolder+'meta100.png" title="Meta100 - Designing Fun" alt="Meta100 - Designing Fun" style="border:0;border-left:1px solid #aaa;right:0;position:absolute;"/></a>');$("#mColorPickerBg").click($.fn.mColorPicker.closePicker);var a=$.fn.mColorPicker.getCookie("swatches"),b=0;typeof a=="string"&&(a=a.split("||"));if(a==null||$.fn.mColorPicker.init.enhancedSwatches||a.length<10)a=$o.swatches;$(".mPastColor").each(function(){$(this).css("background-color",a[b++].toLowerCase())})};$.fn.mColorPicker.closePicker=function(){$(".mColor, .mPastColor, #mColorPickerInput, #mColorPickerWrapper").unbind();$("#mColorPickerBg").hide();$("#mColorPicker").fadeOut()};$.fn.mColorPicker.colorShow=function(a){var b=$("#icp_"+a);pos=b.offset();$i=$("#"+a);hex=$i.attr("data-hex")||$i.attr("hex");pickerTop=pos.top+b.outerHeight();pickerLeft=pos.left;$d=$(document);$m=$("#mColorPicker");if($i.attr("disabled"))return false;pickerTop+$m.height()>$d.height()&&(pickerTop=pos.top-$m.height());pickerLeft+$m.width()>$d.width()&&(pickerLeft=pos.left-$m.width()+b.outerWidth());$m.css({top:pickerTop+"px",left:pickerLeft+"px",position:"absolute"}).fadeIn("fast");$("#mColorPickerBg").css({"z-index":999990,background:"black",opacity:0.01,position:"absolute",top:0,left:0,width:parseInt($d.width(),10)+"px",height:parseInt($d.height(),10)+"px"}).show();var d=$i.val();$("#colorPreview span").text(d);$("#colorPreview").css("background",d);$("#color").val(d);$.fn.mColorPicker.currentColor=$("#"+a).attr("data-text")?b.css("background-color"):$i.css("background-color");if(hex=="true")$.fn.mColorPicker.currentColor=$.fn.mColorPicker.RGBtoHex($.fn.mColorPicker.currentColor);$("#mColorPickerInput").val($.fn.mColorPicker.currentColor);$(".mColor, .mPastColor").bind("mousemove",function(b){var d=$(this).offset();$.fn.mColorPicker.color=$(this).css("background-color");if($(this).hasClass("mPastColor")&&hex=="true")$.fn.mColorPicker.color=$.fn.mColorPicker.RGBtoHex($.fn.mColorPicker.color);else if($(this).hasClass("mPastColor")&&hex!="true")$.fn.mColorPicker.color=$.fn.mColorPicker.hexToRGB($.fn.mColorPicker.color);else if($(this).attr("id")=="mColorPickerTransparent")$.fn.mColorPicker.color="transparent";else if(!$(this).hasClass("mPastColor"))$.fn.mColorPicker.color=$.fn.mColorPicker.whichColor(b.pageX-d.left,b.pageY-d.top+($(this).attr("id")=="mColorPickerImgGray"?128:0),hex);$.fn.mColorPicker.setInputColor(a,$.fn.mColorPicker.color)}).click(function(){$.fn.mColorPicker.colorPicked(a)});$("#mColorPickerInput").bind("keyup",function(b){try{$.fn.mColorPicker.color=$("#mColorPickerInput").val(),$.fn.mColorPicker.setInputColor(a,$.fn.mColorPicker.color),b.which==13&&$.fn.mColorPicker.colorPicked(a)}catch(d){}}).bind("blur",function(){$.fn.mColorPicker.setInputColor(a,$.fn.mColorPicker.currentColor)});$("#mColorPickerWrapper").bind("mouseleave",function(){$.fn.mColorPicker.setInputColor(a,$.fn.mColorPicker.currentColor)})};$.fn.mColorPicker.setInputColor=function(a,b){var d=b=="transparent"?"url('"+$o.imageFolder+"grid.gif')":"",c=$.fn.mColorPicker.textColor(b);($("#"+a).attr("data-text")||$("#"+a).attr("text"))&&$("#icp_"+a).css({"background-color":b,"background-image":d});$("#"+a).val(b).css({"background-color":b,"background-image":d,color:c}).trigger("change");$("#mColorPickerInput").val(b)};$.fn.mColorPicker.textColor=function(a){if(typeof a=="undefined"||a=="transparent")return"black";a=$.fn.mColorPicker.RGBtoHex(a);return parseInt(a.substr(1,2),16)+parseInt(a.substr(3,2),16)+parseInt(a.substr(5,2),16)<400?"white":"black"};$.fn.mColorPicker.setCookie=function(a,b,d){a=a+"="+escape(b);b=new Date;b.setDate(b.getDate()+d);a+="; expires="+b.toGMTString();document.cookie=a};$.fn.mColorPicker.getCookie=function(a){return(a=document.cookie.match("(^|;) ?"+a+"=([^;]*)(;|$)"))?unescape(a[2]):null};$.fn.mColorPicker.colorPicked=function(a){$.fn.mColorPicker.closePicker();$.fn.mColorPicker.init.enhancedSwatches&&$.fn.mColorPicker.addToSwatch();$("#"+a).trigger("colorpicked")};$.fn.mColorPicker.addToSwatch=function(a){var b=[];i=0;if(typeof a=="string")$.fn.mColorPicker.color=a.toLowerCase();$.fn.mColorPicker.currentValue=$.fn.mColorPicker.currentColor=$.fn.mColorPicker.color;$.fn.mColorPicker.color!="transparent"&&(b[0]=$.fn.mColorPicker.color.toLowerCase());$(".mPastColor").each(function(){$.fn.mColorPicker.color=$(this).css("background-color").toLowerCase();if($.fn.mColorPicker.color!=b[0]&&$.fn.mColorPicker.RGBtoHex($.fn.mColorPicker.color)!=b[0]&&$.fn.mColorPicker.hexToRGB($.fn.mColorPicker.color)!=b[0]&&b.length<10)b[b.length]=$.fn.mColorPicker.color;$(this).css("background-color",b[i++])});$.fn.mColorPicker.init.enhancedSwatches&&$.fn.mColorPicker.setCookie("swatches",b.join("||"),365)};$.fn.mColorPicker.whichColor=function(a,b,d){var c=colorG=colorB=255;a<32?(colorG=a*8,colorB=0):a<64?(c=256-(a-32)*8,colorB=0):a<96?(c=0,colorB=(a-64)*8):a<128?(c=0,colorG=256-(a-96)*8):a<160?(c=(a-128)*8,colorG=0):(colorG=0,colorB=256-(a-160)*8);b<64?(c+=(256-c)*(64-b)/64,colorG+=(256-colorG)*(64-b)/64,colorB+=(256-colorB)*(64-b)/64):b<=128?(c-=c*(b-64)/64,colorG-=colorG*(b-64)/64,colorB-=colorB*(b-64)/64):b>128&&(c=colorG=colorB=256-a/192*256);c=Math.round(Math.min(c,255));colorG=Math.round(Math.min(colorG,255));colorB=Math.round(Math.min(colorB,255));return d=="true"?(c=c.toString(16),colorG=colorG.toString(16),colorB=colorB.toString(16),c.length<2&&(c=0+c),colorG.length<2&&(colorG=0+colorG),colorB.length<2&&(colorB=0+colorB),"#"+c+colorG+colorB):"rgb("+c+", "+colorG+", "+colorB+")"};$.fn.mColorPicker.RGBtoHex=function(a){a=a.toLowerCase();if(typeof a=="undefined")return"";if(a.indexOf("#")>-1&&a.length>6)return a;if(a.indexOf("rgb")<0)return a;if(a.indexOf("#")>-1)return"#"+a.substr(1,1)+a.substr(1,1)+a.substr(2,1)+a.substr(2,1)+a.substr(3,1)+a.substr(3,1);for(var b="0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f".split(","),d="#",c=0,a=a.replace(/[^0-9,]/g,"").split(","),e=0;e<a.length;e++)c=Math.floor(a[e]/16),d+=b[c]+b[a[e]-c*16];return d};$.fn.mColorPicker.hexToRGB=function(a){a=a.toLowerCase();if(typeof a=="undefined")return"";if(a.indexOf("rgb")>-1)return a;if(a.indexOf("#")<0)return a;a=a.replace("#","");a.length<6&&(a=a.substr(0,1)+a.substr(0,1)+a.substr(1,1)+a.substr(1,1)+a.substr(2,1)+a.substr(2,1));return"rgb("+parseInt(a.substr(0,2),16)+", "+parseInt(a.substr(2,2),16)+", "+parseInt(a.substr(4,2),16)+")"};$(document).ready(function(){$.fn.mColorPicker.init.replace&&($('input[data-mcolorpicker!="true"]').filter(function(){return $.fn.mColorPicker.init.replace=="[type=color]"?this.getAttribute("type")=="color":$(this).is($.fn.mColorPicker.init.replace)}).mColorPicker(),$.fn.mColorPicker.liveEvents());$(".mColorPicker").live("keyup",function(){try{$(this).css({"background-color":$(this).val()}).css({color:$.fn.mColorPicker.textColor($(this).css("background-color"))}).trigger("change")}catch(a){}});$(".mColorPickerTrigger").live("click",function(){$.fn.mColorPicker.colorShow($(this).attr("id").replace("icp_",""))})});})(jQuery);
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment