diff --git a/.eslintrc b/.eslintrc index f1b5b3c4f1..6ebe4cfa07 100644 --- a/.eslintrc +++ b/.eslintrc @@ -19,7 +19,11 @@ "dot-notation": [2, { "allowKeywords": false }], "eol-last": 2, "eqeqeq": [2, "smart"], - "indent": [2, 2, {"SwitchCase": 1, "VariableDeclarator": 2}], + "indent": [2, 2, { + "MemberExpression": 0, + "SwitchCase": 1, + "VariableDeclarator": 2 + }], "key-spacing": 1, "keyword-spacing": [2, { "after": true }], "linebreak-style": 2, @@ -76,7 +80,7 @@ "no-unused-expressions": [2, {"allowTernary": true, "allowShortCircuit": true}], "no-with": 2, "object-curly-spacing": [2, "never"], - "quote-props": [1, "consistent-as-needed"], + "quote-props": [1, "consistent-as-needed", {"keywords": true}], "quotes": [2, "single", "avoid-escape"], "radix": 2, "semi": 2, diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000000..9e10c530a6 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,39 @@ +name: Test + +on: + push: + branches: + - master + pull_request: + branches: + - master + paths: + - '.github/workflows/**' + - 'test/**' + - '*.js' + - 'package.json' + +jobs: + tests: + env: + NPM_CONFIG_PROGRESS: "false" + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: 14 + cache: 'npm' + - name: Install dependencies + run: | + npm ci + npm install --no-audit karma-cli karma-sauce-launcher + - name: Test + run: npm test + - name: Test in Sauce Labs + run: BUILD_NUMBER="$GITHUB_RUN_NUMBER" BUILD_ID="$GITHUB_RUN_ID" JOB_NUMBER="$GITHUB_JOB" ./node_modules/.bin/karma start karma.conf-sauce.js + env: + SAUCE_USERNAME: ${{ secrets.SauceUsername }} + SAUCE_ACCESS_KEY: ${{ secrets.SauceAccessKey }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5615d5d1e8..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -language: node_js -node_js: - - "6" -before_install: - - npm install -g npm - - npm install -g karma-cli -before_script: - - npm install karma-sauce-launcher - - export DISPLAY=:99.0 - - sh -e /etc/init.d/xvfb start -script: - - npm test - - karma start karma.conf-sauce.js -notifications: - email: false -sudo: false -env: - global: - - NPM_CONFIG_PROGRESS="false" - - secure: G9oDQUXytNHni0wasGDXO3lQE/xuP9gd6VZ20kuh5FzVlqfY5L7JfYWki435nZ1z2yPD1QVAZi+1BCmCwnkTLVO9gB7cmDJDt1VzeHdCSOqCXGDAbOcq67/OO4FUa77sCQSDnqOOGVbiUPldaDl8G6uylk72Ll8b0pPwUWdRCM8= - - secure: dniSzTSxXzaSGYjW3+LiNesx/BtTWo6RHuMKm19MwNo/YJYJJ/1YSEH/9vCmlVzc00CqvJ5Khwu9XPzcDV4gkuNQFN1+QcgGI2heVUqac/jqlGF39VEH8Xc+H40MsRLkwgSIkadIPWj4wBbbzqyC9M+J/KjUPOhBXGtp+FARu0I= diff --git a/CNAME b/CNAME index dfadb7985a..706ffc0a0f 100644 --- a/CNAME +++ b/CNAME @@ -1,2 +1 @@ -backbonejs.org - +backbonejs.org \ No newline at end of file diff --git a/LICENSE b/LICENSE index 9118224914..a66cb771ba 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2010-2019 Jeremy Ashkenas, DocumentCloud +Copyright (c) 2010-2022 Jeremy Ashkenas, DocumentCloud Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/README.md b/README.md index 276b7fc3eb..2230925ad1 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,9 @@ https://gitter.im/jashkenas/backbone Backbone is an open-sourced component of DocumentCloud: https://github.com/documentcloud +Testing powered by SauceLabs: +https://saucelabs.com + Many thanks to our contributors: https://github.com/jashkenas/backbone/graphs/contributors diff --git a/backbone-min.js b/backbone-min.js index c8c33e0d7f..10945d244e 100644 --- a/backbone-min.js +++ b/backbone-min.js @@ -1,2 +1,2 @@ -(function(t){var e=typeof self=="object"&&self.self===self&&self||typeof global=="object"&&global.global===global&&global;if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,n,r){e.Backbone=t(e,r,i,n)})}else if(typeof exports!=="undefined"){var i=require("underscore"),n;try{n=require("jquery")}catch(r){}t(e,exports,i,n)}else{e.Backbone=t(e,{},e._,e.jQuery||e.Zepto||e.ender||e.$)}})(function(t,e,i,n){var r=t.Backbone;var s=Array.prototype.slice;e.VERSION="1.4.0";e.$=n;e.noConflict=function(){t.Backbone=r;return this};e.emulateHTTP=false;e.emulateJSON=false;var a=e.Events={};var o=/\s+/;var h;var u=function(t,e,n,r,s){var a=0,h;if(n&&typeof n==="object"){if(r!==void 0&&"context"in s&&s.context===void 0)s.context=r;for(h=i.keys(n);athis.length)r=this.length;if(r<0)r+=this.length+1;var s=[];var a=[];var o=[];var h=[];var u={};var l=e.add;var c=e.merge;var f=e.remove;var d=false;var v=this.comparator&&r==null&&e.sort!==false;var p=i.isString(this.comparator)?this.comparator:null;var g,m;for(m=0;m7);this._useHashChange=this._wantsHashChange&&this._hasHashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.history&&this.history.pushState);this._usePushState=this._wantsPushState&&this._hasPushState;this.fragment=this.getFragment();this.root=("/"+this.root+"/").replace(L,"/");if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){var e=this.root.slice(0,-1)||"/";this.location.replace(e+"#"+this.getPath());return true}else if(this._hasPushState&&this.atRoot()){this.navigate(this.getHash(),{replace:true})}}if(!this._hasHashChange&&this._wantsHashChange&&!this._usePushState){this.iframe=document.createElement("iframe");this.iframe.src="javascript:0";this.iframe.style.display="none";this.iframe.tabIndex=-1;var n=document.body;var r=n.insertBefore(this.iframe,n.firstChild).contentWindow;r.document.open();r.document.close();r.location.hash="#"+this.fragment}var s=window.addEventListener||function(t,e){return attachEvent("on"+t,e)};if(this._usePushState){s("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){s("hashchange",this.checkUrl,false)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}if(!this.options.silent)return this.loadUrl()},stop:function(){var t=window.removeEventListener||function(t,e){return detachEvent("on"+t,e)};if(this._usePushState){t("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){t("hashchange",this.checkUrl,false)}if(this.iframe){document.body.removeChild(this.iframe);this.iframe=null}if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);B.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getHash(this.iframe.contentWindow)}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(t){if(!this.matchRoot())return false;t=this.fragment=this.getFragment(t);return i.some(this.handlers,function(e){if(e.route.test(t)){e.callback(t);return true}})},navigate:function(t,e){if(!B.started)return false;if(!e||e===true)e={trigger:!!e};t=this.getFragment(t||"");var i=this.root;if(t===""||t.charAt(0)==="?"){i=i.slice(0,-1)||"/"}var n=i+t;t=t.replace(W,"");var r=this.decodeFragment(t);if(this.fragment===r)return;this.fragment=r;if(this._usePushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,n)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getHash(this.iframe.contentWindow)){var s=this.iframe.contentWindow;if(!e.replace){s.document.open();s.document.close()}this._updateHash(s.location,t,e.replace)}}else{return this.location.assign(n)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var n=t.href.replace(/(javascript:|#).*$/,"");t.replace(n+"#"+e)}else{t.hash="#"+e}}});e.history=new B;var D=function(t,e){var n=this;var r;if(t&&i.has(t,"constructor")){r=t.constructor}else{r=function(){return n.apply(this,arguments)}}i.extend(r,n,e);r.prototype=i.create(n.prototype,t);r.prototype.constructor=r;r.__super__=n.prototype;return r};m.extend=_.extend=O.extend=T.extend=B.extend=D;var V=function(){throw new Error('A "url" property or function must be specified')};var G=function(t,e){var i=e.error;e.error=function(n){if(i)i.call(e.context,t,n,e);t.trigger("error",t,n,e)}};return e}); -//# sourceMappingURL=backbone-min.map \ No newline at end of file +(function(r){var n=typeof self=="object"&&self.self===self&&self||typeof global=="object"&&global.global===global&&global;if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(t,e,i){n.Backbone=r(n,i,t,e)})}else if(typeof exports!=="undefined"){var t=require("underscore"),e;try{e=require("jquery")}catch(t){}r(n,exports,t,e)}else{n.Backbone=r(n,{},n._,n.jQuery||n.Zepto||n.ender||n.$)}})(function(t,h,x,e){var i=t.Backbone;var a=Array.prototype.slice;h.VERSION="1.4.1";h.$=e;h.noConflict=function(){t.Backbone=i;return this};h.emulateHTTP=false;h.emulateJSON=false;var r=h.Events={};var o=/\s+/;var l;var u=function(t,e,i,r,n){var s=0,a;if(i&&typeof i==="object"){if(r!==void 0&&"context"in n&&n.context===void 0)n.context=r;for(a=x.keys(i);sthis.length)r=this.length;if(r<0)r+=this.length+1;var n=[];var s=[];var a=[];var o=[];var h={};var l=e.add;var u=e.merge;var c=e.remove;var f=false;var d=this.comparator&&r==null&&e.sort!==false;var v=x.isString(this.comparator)?this.comparator:null;var p,g;for(g=0;g7);this._useHashChange=this._wantsHashChange&&this._hasHashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.history&&this.history.pushState);this._usePushState=this._wantsPushState&&this._hasPushState;this.fragment=this.getFragment();this.root=("/"+this.root+"/").replace(L,"/");if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){var e=this.root.slice(0,-1)||"/";this.location.replace(e+"#"+this.getPath());return true}else if(this._hasPushState&&this.atRoot()){this.navigate(this.getHash(),{replace:true})}}if(!this._hasHashChange&&this._wantsHashChange&&!this._usePushState){this.iframe=document.createElement("iframe");this.iframe.src="javascript:0";this.iframe.style.display="none";this.iframe.tabIndex=-1;var i=document.body;var r=i.insertBefore(this.iframe,i.firstChild).contentWindow;r.document.open();r.document.close();r.location.hash="#"+this.fragment}var n=window.addEventListener||function(t,e){return attachEvent("on"+t,e)};if(this._usePushState){n("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){n("hashchange",this.checkUrl,false)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}if(!this.options.silent)return this.loadUrl()},stop:function(){var t=window.removeEventListener||function(t,e){return detachEvent("on"+t,e)};if(this._usePushState){t("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){t("hashchange",this.checkUrl,false)}if(this.iframe){document.body.removeChild(this.iframe);this.iframe=null}if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);B.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getHash(this.iframe.contentWindow)}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(e){if(!this.matchRoot())return false;e=this.fragment=this.getFragment(e);return x.some(this.handlers,function(t){if(t.route.test(e)){t.callback(e);return true}})},navigate:function(t,e){if(!B.started)return false;if(!e||e===true)e={trigger:!!e};t=this.getFragment(t||"");var i=this.root;if(t===""||t.charAt(0)==="?"){i=i.slice(0,-1)||"/"}var r=i+t;t=t.replace(W,"");var n=this.decodeFragment(t);if(this.fragment===n)return;this.fragment=n;if(this._usePushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,r)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getHash(this.iframe.contentWindow)){var s=this.iframe.contentWindow;if(!e.replace){s.document.open();s.document.close()}this._updateHash(s.location,t,e.replace)}}else{return this.location.assign(r)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,"");t.replace(r+"#"+e)}else{t.hash="#"+e}}});h.history=new B;var D=function(t,e){var i=this;var r;if(t&&x.has(t,"constructor")){r=t.constructor}else{r=function(){return i.apply(this,arguments)}}x.extend(r,i,e);r.prototype=x.create(i.prototype,t);r.prototype.constructor=r;r.__super__=i.prototype;return r};g.extend=m.extend=O.extend=A.extend=B.extend=D;var V=function(){throw new Error('A "url" property or function must be specified')};var G=function(e,i){var r=i.error;i.error=function(t){if(r)r.call(i.context,e,t,i);e.trigger("error",e,t,i)}};return h}); +//# sourceMappingURL=backbone-min.js.map \ No newline at end of file diff --git a/backbone-min.js.map b/backbone-min.js.map new file mode 100644 index 0000000000..c1bcd82abd --- /dev/null +++ b/backbone-min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["backbone.js"],"names":["factory","root","self","global","define","amd","_","$","exports","Backbone","require","e","jQuery","Zepto","ender","previousBackbone","slice","Array","prototype","VERSION","noConflict","this","emulateHTTP","emulateJSON","Events","eventSplitter","_listening","eventsApi","iteratee","events","name","callback","opts","i","names","context","keys","length","test","split","on","_events","onApi","ctx","listening","listeners","_listeners","id","interop","listenTo","obj","_listenId","uniqueId","listeningTo","_listeningTo","Listening","error","tryCatchOn","options","handlers","count","push","off","offApi","stopListening","ids","isEmpty","cleanup","remaining","j","handler","_callback","once","onceMap","bind","listenToOnce","map","offer","apply","arguments","trigger","Math","max","args","triggerApi","objEvents","allEvents","all","triggerEvents","concat","ev","l","a1","a2","a3","call","listener","unbind","extend","Model","attributes","attrs","preinitialize","cid","cidPrefix","collection","parse","defaults","result","set","changed","initialize","validationError","idAttribute","toJSON","clone","sync","get","attr","escape","has","matches","key","val","_validate","unset","silent","changes","changing","_changing","_previousAttributes","current","prev","isEqual","prevId","_pending","clear","hasChanged","changedAttributes","diff","old","previous","previousAttributes","fetch","model","success","resp","serverAttrs","wrapError","save","validate","wait","method","isNew","patch","xhr","destroy","defer","url","base","urlError","replace","encodeURIComponent","constructor","isValid","Collection","models","comparator","_reset","reset","setOptions","add","remove","merge","addOptions","splice","array","insert","at","min","tail","singular","isArray","removed","_removeModels","added","merged","_isModel","toAdd","toMerge","toRemove","modelMap","sort","sortable","sortAttr","isString","existing","_prepareModel","_addReference","orderChanged","some","m","index","_removeReference","previousModels","pop","unshift","shift","_byId","modelId","where","first","findWhere","Error","isFunction","sortBy","pluck","create","callbackOpts","values","CollectionIterator","ITERATOR_VALUES","ITERATOR_KEYS","entries","ITERATOR_KEYSVALUES","indexOf","_onModelEvent","event","$$iterator","Symbol","iterator","kind","_collection","_kind","_index","next","value","done","View","pick","viewOptions","_ensureElement","delegateEventSplitter","tagName","selector","$el","find","render","_removeElement","setElement","element","undelegateEvents","_setElement","delegateEvents","el","match","delegate","eventName","undelegate","_createElement","document","createElement","className","_setAttributes","addMethod","attribute","cb","defaultVal","addUnderscoreMethods","Class","methods","each","instance","isObject","modelMatcher","matcher","collectionMethods","forEach","collect","reduce","foldl","inject","reduceRight","foldr","detect","filter","select","reject","every","any","include","includes","contains","invoke","toArray","size","head","take","initial","rest","drop","last","without","difference","shuffle","lastIndexOf","chain","sample","partition","groupBy","countBy","indexBy","findIndex","findLastIndex","modelMethods","pairs","invert","omit","config","Base","mixin","mappings","functions","memo","type","methodMap","params","dataType","data","contentType","JSON","stringify","_method","beforeSend","setRequestHeader","processData","textStatus","errorThrown","ajax","update","delete","read","Router","routes","_bindRoutes","optionalParam","namedParam","splatParam","escapeRegExp","route","isRegExp","_routeToRegExp","router","history","fragment","_extractParameters","execute","navigate","optional","RegExp","exec","param","decodeURIComponent","History","checkUrl","window","location","routeStripper","rootStripper","pathStripper","started","interval","atRoot","path","pathname","getSearch","matchRoot","decodeFragment","rootPath","decodeURI","href","getHash","getPath","charAt","getFragment","_usePushState","_wantsHashChange","start","hashChange","_hasHashChange","documentMode","_useHashChange","_wantsPushState","pushState","_hasPushState","iframe","src","style","display","tabIndex","body","iWindow","insertBefore","firstChild","contentWindow","open","close","hash","addEventListener","attachEvent","_checkUrlInterval","setInterval","loadUrl","stop","removeEventListener","detachEvent","removeChild","clearInterval","decodedFragment","title","_updateHash","assign","protoProps","staticProps","parent","child","__super__"],"mappings":"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"} \ No newline at end of file diff --git a/backbone-min.map b/backbone-min.map index a45f7c13e9..c1bcd82abd 100644 --- a/backbone-min.map +++ b/backbone-min.map @@ -1 +1 @@ -{"version":3,"file":"backbone-min.js","sources":["backbone.js"],"names":["factory","root","self","global","define","amd","_","$","exports","Backbone","require","e","jQuery","Zepto","ender","previousBackbone","slice","Array","prototype","VERSION","noConflict","this","emulateHTTP","emulateJSON","Events","eventSplitter","_listening","eventsApi","iteratee","events","name","callback","opts","i","names","context","keys","length","test","split","on","_events","onApi","ctx","listening","listeners","_listeners","id","interop","listenTo","obj","_listenId","uniqueId","listeningTo","_listeningTo","Listening","error","tryCatchOn","options","handlers","count","push","off","offApi","stopListening","ids","isEmpty","cleanup","remaining","j","handler","_callback","once","onceMap","bind","listenToOnce","map","offer","apply","arguments","trigger","Math","max","args","triggerApi","objEvents","allEvents","all","triggerEvents","concat","ev","l","a1","a2","a3","call","listener","unbind","extend","Model","attributes","attrs","preinitialize","cid","cidPrefix","collection","parse","defaults","result","set","changed","initialize","validationError","idAttribute","toJSON","clone","sync","get","attr","escape","has","matches","key","val","_validate","unset","silent","changes","changing","_changing","_previousAttributes","current","prev","isEqual","_pending","clear","hasChanged","changedAttributes","diff","old","previous","previousAttributes","fetch","model","success","resp","serverAttrs","wrapError","save","validate","wait","method","isNew","patch","xhr","destroy","defer","url","base","urlError","replace","encodeURIComponent","constructor","isValid","Collection","models","comparator","_reset","reset","setOptions","add","remove","merge","addOptions","splice","array","insert","at","min","tail","singular","isArray","removed","_removeModels","added","merged","_isModel","toAdd","toMerge","toRemove","modelMap","sort","sortable","sortAttr","isString","existing","_prepareModel","_addReference","orderChanged","some","m","index","_removeReference","previousModels","pop","unshift","shift","_byId","modelId","where","first","findWhere","Error","isFunction","sortBy","pluck","create","callbackOpts","values","CollectionIterator","ITERATOR_VALUES","ITERATOR_KEYS","entries","ITERATOR_KEYSVALUES","indexOf","_onModelEvent","event","prevId","$$iterator","Symbol","iterator","kind","_collection","_kind","_index","next","value","done","View","pick","viewOptions","_ensureElement","delegateEventSplitter","tagName","selector","$el","find","render","_removeElement","setElement","element","undelegateEvents","_setElement","delegateEvents","el","match","delegate","eventName","undelegate","_createElement","document","createElement","className","_setAttributes","addMethod","attribute","cb","defaultVal","addUnderscoreMethods","Class","methods","each","instance","isObject","modelMatcher","matcher","collectionMethods","forEach","collect","reduce","foldl","inject","reduceRight","foldr","detect","filter","select","reject","every","any","include","includes","contains","invoke","toArray","size","head","take","initial","rest","drop","last","without","difference","shuffle","lastIndexOf","chain","sample","partition","groupBy","countBy","indexBy","findIndex","findLastIndex","modelMethods","pairs","invert","omit","config","Base","mixin","mappings","functions","memo","type","methodMap","params","dataType","data","contentType","JSON","stringify","_method","beforeSend","setRequestHeader","processData","textStatus","errorThrown","ajax","update","delete","read","Router","routes","_bindRoutes","optionalParam","namedParam","splatParam","escapeRegExp","route","isRegExp","_routeToRegExp","router","history","fragment","_extractParameters","execute","navigate","optional","RegExp","exec","param","decodeURIComponent","History","checkUrl","window","location","routeStripper","rootStripper","pathStripper","started","interval","atRoot","path","pathname","getSearch","matchRoot","decodeFragment","rootPath","decodeURI","href","getHash","getPath","charAt","getFragment","_usePushState","_wantsHashChange","start","hashChange","_hasHashChange","documentMode","_useHashChange","_wantsPushState","pushState","_hasPushState","iframe","src","style","display","tabIndex","body","iWindow","insertBefore","firstChild","contentWindow","open","close","hash","addEventListener","attachEvent","_checkUrlInterval","setInterval","loadUrl","stop","removeEventListener","detachEvent","removeChild","clearInterval","decodedFragment","title","_updateHash","assign","protoProps","staticProps","parent","child","__super__"],"mappings":"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"} \ No newline at end of file +{"version":3,"sources":["backbone.js"],"names":["factory","root","self","global","define","amd","_","$","exports","Backbone","require","e","jQuery","Zepto","ender","previousBackbone","slice","Array","prototype","VERSION","noConflict","this","emulateHTTP","emulateJSON","Events","eventSplitter","_listening","eventsApi","iteratee","events","name","callback","opts","i","names","context","keys","length","test","split","on","_events","onApi","ctx","listening","listeners","_listeners","id","interop","listenTo","obj","_listenId","uniqueId","listeningTo","_listeningTo","Listening","error","tryCatchOn","options","handlers","count","push","off","offApi","stopListening","ids","isEmpty","cleanup","remaining","j","handler","_callback","once","onceMap","bind","listenToOnce","map","offer","apply","arguments","trigger","Math","max","args","triggerApi","objEvents","allEvents","all","triggerEvents","concat","ev","l","a1","a2","a3","call","listener","unbind","extend","Model","attributes","attrs","preinitialize","cid","cidPrefix","collection","parse","defaults","result","set","changed","initialize","validationError","idAttribute","toJSON","clone","sync","get","attr","escape","has","matches","key","val","_validate","unset","silent","changes","changing","_changing","_previousAttributes","current","prev","isEqual","prevId","_pending","clear","hasChanged","changedAttributes","diff","old","previous","previousAttributes","fetch","model","success","resp","serverAttrs","wrapError","save","validate","wait","method","isNew","patch","xhr","destroy","defer","url","base","urlError","replace","encodeURIComponent","constructor","isValid","Collection","models","comparator","_reset","reset","setOptions","add","remove","merge","addOptions","splice","array","insert","at","min","tail","singular","isArray","removed","_removeModels","added","merged","_isModel","toAdd","toMerge","toRemove","modelMap","sort","sortable","sortAttr","isString","existing","_prepareModel","_addReference","orderChanged","some","m","index","_removeReference","previousModels","pop","unshift","shift","_byId","modelId","where","first","findWhere","Error","isFunction","sortBy","pluck","create","callbackOpts","values","CollectionIterator","ITERATOR_VALUES","ITERATOR_KEYS","entries","ITERATOR_KEYSVALUES","indexOf","_onModelEvent","event","$$iterator","Symbol","iterator","kind","_collection","_kind","_index","next","value","done","View","pick","viewOptions","_ensureElement","delegateEventSplitter","tagName","selector","$el","find","render","_removeElement","setElement","element","undelegateEvents","_setElement","delegateEvents","el","match","delegate","eventName","undelegate","_createElement","document","createElement","className","_setAttributes","addMethod","attribute","cb","defaultVal","addUnderscoreMethods","Class","methods","each","instance","isObject","modelMatcher","matcher","collectionMethods","forEach","collect","reduce","foldl","inject","reduceRight","foldr","detect","filter","select","reject","every","any","include","includes","contains","invoke","toArray","size","head","take","initial","rest","drop","last","without","difference","shuffle","lastIndexOf","chain","sample","partition","groupBy","countBy","indexBy","findIndex","findLastIndex","modelMethods","pairs","invert","omit","config","Base","mixin","mappings","functions","memo","type","methodMap","params","dataType","data","contentType","JSON","stringify","_method","beforeSend","setRequestHeader","processData","textStatus","errorThrown","ajax","update","delete","read","Router","routes","_bindRoutes","optionalParam","namedParam","splatParam","escapeRegExp","route","isRegExp","_routeToRegExp","router","history","fragment","_extractParameters","execute","navigate","optional","RegExp","exec","param","decodeURIComponent","History","checkUrl","window","location","routeStripper","rootStripper","pathStripper","started","interval","atRoot","path","pathname","getSearch","matchRoot","decodeFragment","rootPath","decodeURI","href","getHash","getPath","charAt","getFragment","_usePushState","_wantsHashChange","start","hashChange","_hasHashChange","documentMode","_useHashChange","_wantsPushState","pushState","_hasPushState","iframe","src","style","display","tabIndex","body","iWindow","insertBefore","firstChild","contentWindow","open","close","hash","addEventListener","attachEvent","_checkUrlInterval","setInterval","loadUrl","stop","removeEventListener","detachEvent","removeChild","clearInterval","decodedFragment","title","_updateHash","assign","protoProps","staticProps","parent","child","__super__"],"mappings":"CAOA,SAAUA,GAIR,IAAIC,SAAcC,MAAQ,UAAYA,KAAKA,OAASA,MAAQA,aAC3CC,QAAU,UAAYA,OAAOA,SAAWA,QAAUA,OAGnE,UAAWC,SAAW,YAAcA,OAAOC,IAAK,CAC9CD,OAAO,CAAC,aAAc,SAAU,WAAY,SAASE,EAAGC,EAAGC,GAGzDP,EAAKQ,SAAWT,EAAQC,EAAMO,EAASF,EAAGC,UAIvC,UAAWC,UAAY,YAAa,CACzC,IAAIF,EAAII,QAAQ,cAAeH,EAC/B,IAAMA,EAAIG,QAAQ,UAAa,MAAOC,IACtCX,EAAQC,EAAMO,QAASF,EAAGC,OAGrB,CACLN,EAAKQ,SAAWT,EAAQC,EAAM,GAAIA,EAAKK,EAAGL,EAAKW,QAAUX,EAAKY,OAASZ,EAAKa,OAASb,EAAKM,KAvB9F,CA0BG,SAASN,EAAMQ,EAAUH,EAAGC,GAO7B,IAAIQ,EAAmBd,EAAKQ,SAG5B,IAAIO,EAAQC,MAAMC,UAAUF,MAG5BP,EAASU,QAAU,QAInBV,EAASF,EAAIA,EAIbE,EAASW,WAAa,WACpBnB,EAAKQ,SAAWM,EAChB,OAAOM,MAMTZ,EAASa,YAAc,MAMvBb,EAASc,YAAc,MAevB,IAAIC,EAASf,EAASe,OAAS,GAG/B,IAAIC,EAAgB,MAGpB,IAAIC,EAKJ,IAAIC,EAAY,SAASC,EAAUC,EAAQC,EAAMC,EAAUC,GACzD,IAAIC,EAAI,EAAGC,EACX,GAAIJ,UAAeA,IAAS,SAAU,CAEpC,GAAIC,SAAkB,GAAK,YAAaC,GAAQA,EAAKG,eAAiB,EAAGH,EAAKG,QAAUJ,EACxF,IAAKG,EAAQ5B,EAAE8B,KAAKN,GAAOG,EAAIC,EAAMG,OAASJ,IAAK,CACjDJ,EAASF,EAAUC,EAAUC,EAAQK,EAAMD,GAAIH,EAAKI,EAAMD,IAAKD,SAE5D,GAAIF,GAAQL,EAAca,KAAKR,GAAO,CAE3C,IAAKI,EAAQJ,EAAKS,MAAMd,GAAgBQ,EAAIC,EAAMG,OAAQJ,IAAK,CAC7DJ,EAASD,EAASC,EAAQK,EAAMD,GAAIF,EAAUC,QAE3C,CAELH,EAASD,EAASC,EAAQC,EAAMC,EAAUC,GAE5C,OAAOH,GAKTL,EAAOgB,GAAK,SAASV,EAAMC,EAAUI,GACnCd,KAAKoB,QAAUd,EAAUe,EAAOrB,KAAKoB,SAAW,GAAIX,EAAMC,EAAU,CAClEI,QAASA,EACTQ,IAAKtB,KACLuB,UAAWlB,IAGb,GAAIA,EAAY,CACd,IAAImB,EAAYxB,KAAKyB,aAAezB,KAAKyB,WAAa,IACtDD,EAAUnB,EAAWqB,IAAMrB,EAG3BA,EAAWsB,QAAU,MAGvB,OAAO3B,MAMTG,EAAOyB,SAAW,SAASC,EAAKpB,EAAMC,GACpC,IAAKmB,EAAK,OAAO7B,KACjB,IAAI0B,EAAKG,EAAIC,YAAcD,EAAIC,UAAY7C,EAAE8C,SAAS,MACtD,IAAIC,EAAchC,KAAKiC,eAAiBjC,KAAKiC,aAAe,IAC5D,IAAIV,EAAYlB,EAAa2B,EAAYN,GAIzC,IAAKH,EAAW,CACdvB,KAAK8B,YAAc9B,KAAK8B,UAAY7C,EAAE8C,SAAS,MAC/CR,EAAYlB,EAAa2B,EAAYN,GAAM,IAAIQ,EAAUlC,KAAM6B,GAIjE,IAAIM,EAAQC,EAAWP,EAAKpB,EAAMC,EAAUV,MAC5CK,OAAkB,EAElB,GAAI8B,EAAO,MAAMA,EAEjB,GAAIZ,EAAUI,QAASJ,EAAUJ,GAAGV,EAAMC,GAE1C,OAAOV,MAIT,IAAIqB,EAAQ,SAASb,EAAQC,EAAMC,EAAU2B,GAC3C,GAAI3B,EAAU,CACZ,IAAI4B,EAAW9B,EAAOC,KAAUD,EAAOC,GAAQ,IAC/C,IAAIK,EAAUuB,EAAQvB,QAASQ,EAAMe,EAAQf,IAAKC,EAAYc,EAAQd,UACtE,GAAIA,EAAWA,EAAUgB,QAEzBD,EAASE,KAAK,CAAC9B,SAAUA,EAAUI,QAASA,EAASQ,IAAKR,GAAWQ,EAAKC,UAAWA,IAEvF,OAAOf,GAKT,IAAI4B,EAAa,SAASP,EAAKpB,EAAMC,EAAUI,GAC7C,IACEe,EAAIV,GAAGV,EAAMC,EAAUI,GACvB,MAAOxB,GACP,OAAOA,IAQXa,EAAOsC,IAAM,SAAShC,EAAMC,EAAUI,GACpC,IAAKd,KAAKoB,QAAS,OAAOpB,KAC1BA,KAAKoB,QAAUd,EAAUoC,EAAQ1C,KAAKoB,QAASX,EAAMC,EAAU,CAC7DI,QAASA,EACTU,UAAWxB,KAAKyB,aAGlB,OAAOzB,MAKTG,EAAOwC,cAAgB,SAASd,EAAKpB,EAAMC,GACzC,IAAIsB,EAAchC,KAAKiC,aACvB,IAAKD,EAAa,OAAOhC,KAEzB,IAAI4C,EAAMf,EAAM,CAACA,EAAIC,WAAa7C,EAAE8B,KAAKiB,GACzC,IAAK,IAAIpB,EAAI,EAAGA,EAAIgC,EAAI5B,OAAQJ,IAAK,CACnC,IAAIW,EAAYS,EAAYY,EAAIhC,IAIhC,IAAKW,EAAW,MAEhBA,EAAUM,IAAIY,IAAIhC,EAAMC,EAAUV,MAClC,GAAIuB,EAAUI,QAASJ,EAAUkB,IAAIhC,EAAMC,GAE7C,GAAIzB,EAAE4D,QAAQb,GAAchC,KAAKiC,kBAAoB,EAErD,OAAOjC,MAIT,IAAI0C,EAAS,SAASlC,EAAQC,EAAMC,EAAU2B,GAC5C,IAAK7B,EAAQ,OAEb,IAAIM,EAAUuB,EAAQvB,QAASU,EAAYa,EAAQb,UACnD,IAAIZ,EAAI,EAAGC,EAGX,IAAKJ,IAASK,IAAYJ,EAAU,CAClC,IAAKG,EAAQ5B,EAAE8B,KAAKS,GAAYZ,EAAIC,EAAMG,OAAQJ,IAAK,CACrDY,EAAUX,EAAMD,IAAIkC,UAEtB,OAGFjC,EAAQJ,EAAO,CAACA,GAAQxB,EAAE8B,KAAKP,GAC/B,KAAOI,EAAIC,EAAMG,OAAQJ,IAAK,CAC5BH,EAAOI,EAAMD,GACb,IAAI0B,EAAW9B,EAAOC,GAGtB,IAAK6B,EAAU,MAGf,IAAIS,EAAY,GAChB,IAAK,IAAIC,EAAI,EAAGA,EAAIV,EAAStB,OAAQgC,IAAK,CACxC,IAAIC,EAAUX,EAASU,GACvB,GACEtC,GAAYA,IAAauC,EAAQvC,UAC/BA,IAAauC,EAAQvC,SAASwC,WAC5BpC,GAAWA,IAAYmC,EAAQnC,QACnC,CACAiC,EAAUP,KAAKS,OACV,CACL,IAAI1B,EAAY0B,EAAQ1B,UACxB,GAAIA,EAAWA,EAAUkB,IAAIhC,EAAMC,IAKvC,GAAIqC,EAAU/B,OAAQ,CACpBR,EAAOC,GAAQsC,MACV,QACEvC,EAAOC,IAIlB,OAAOD,GAOTL,EAAOgD,KAAO,SAAS1C,EAAMC,EAAUI,GAErC,IAAIN,EAASF,EAAU8C,EAAS,GAAI3C,EAAMC,EAAUV,KAAKyC,IAAIY,KAAKrD,OAClE,UAAWS,IAAS,UAAYK,GAAW,KAAMJ,OAAgB,EACjE,OAAOV,KAAKmB,GAAGX,EAAQE,EAAUI,IAInCX,EAAOmD,aAAe,SAASzB,EAAKpB,EAAMC,GAExC,IAAIF,EAASF,EAAU8C,EAAS,GAAI3C,EAAMC,EAAUV,KAAK2C,cAAcU,KAAKrD,KAAM6B,IAClF,OAAO7B,KAAK4B,SAASC,EAAKrB,IAK5B,IAAI4C,EAAU,SAASG,EAAK9C,EAAMC,EAAU8C,GAC1C,GAAI9C,EAAU,CACZ,IAAIyC,EAAOI,EAAI9C,GAAQxB,EAAEkE,KAAK,WAC5BK,EAAM/C,EAAM0C,GACZzC,EAAS+C,MAAMzD,KAAM0D,aAEvBP,EAAKD,UAAYxC,EAEnB,OAAO6C,GAOTpD,EAAOwD,QAAU,SAASlD,GACxB,IAAKT,KAAKoB,QAAS,OAAOpB,KAE1B,IAAIgB,EAAS4C,KAAKC,IAAI,EAAGH,UAAU1C,OAAS,GAC5C,IAAI8C,EAAOlE,MAAMoB,GACjB,IAAK,IAAIJ,EAAI,EAAGA,EAAII,EAAQJ,IAAKkD,EAAKlD,GAAK8C,UAAU9C,EAAI,GAEzDN,EAAUyD,EAAY/D,KAAKoB,QAASX,OAAW,EAAGqD,GAClD,OAAO9D,MAIT,IAAI+D,EAAa,SAASC,EAAWvD,EAAMC,EAAUoD,GACnD,GAAIE,EAAW,CACb,IAAIxD,EAASwD,EAAUvD,GACvB,IAAIwD,EAAYD,EAAUE,IAC1B,GAAI1D,GAAUyD,EAAWA,EAAYA,EAAUtE,QAC/C,GAAIa,EAAQ2D,EAAc3D,EAAQsD,GAClC,GAAIG,EAAWE,EAAcF,EAAW,CAACxD,GAAM2D,OAAON,IAExD,OAAOE,GAMT,IAAIG,EAAgB,SAAS3D,EAAQsD,GACnC,IAAIO,EAAIzD,GAAK,EAAG0D,EAAI9D,EAAOQ,OAAQuD,EAAKT,EAAK,GAAIU,EAAKV,EAAK,GAAIW,EAAKX,EAAK,GACzE,OAAQA,EAAK9C,QACX,KAAK,EAAG,QAASJ,EAAI0D,GAAID,EAAK7D,EAAOI,IAAIF,SAASgE,KAAKL,EAAG/C,KAAM,OAChE,KAAK,EAAG,QAASV,EAAI0D,GAAID,EAAK7D,EAAOI,IAAIF,SAASgE,KAAKL,EAAG/C,IAAKiD,GAAK,OACpE,KAAK,EAAG,QAAS3D,EAAI0D,GAAID,EAAK7D,EAAOI,IAAIF,SAASgE,KAAKL,EAAG/C,IAAKiD,EAAIC,GAAK,OACxE,KAAK,EAAG,QAAS5D,EAAI0D,GAAID,EAAK7D,EAAOI,IAAIF,SAASgE,KAAKL,EAAG/C,IAAKiD,EAAIC,EAAIC,GAAK,OAC5E,QAAS,QAAS7D,EAAI0D,GAAID,EAAK7D,EAAOI,IAAIF,SAAS+C,MAAMY,EAAG/C,IAAKwC,GAAO,SAM5E,IAAI5B,EAAY,SAASyC,EAAU9C,GACjC7B,KAAK0B,GAAKiD,EAAS7C,UACnB9B,KAAK2E,SAAWA,EAChB3E,KAAK6B,IAAMA,EACX7B,KAAK2B,QAAU,KACf3B,KAAKuC,MAAQ,EACbvC,KAAKoB,aAAe,GAGtBc,EAAUrC,UAAUsB,GAAKhB,EAAOgB,GAMhCe,EAAUrC,UAAU4C,IAAM,SAAShC,EAAMC,GACvC,IAAIoC,EACJ,GAAI9C,KAAK2B,QAAS,CAChB3B,KAAKoB,QAAUd,EAAUoC,EAAQ1C,KAAKoB,QAASX,EAAMC,EAAU,CAC7DI,aAAc,EACdU,eAAgB,IAElBsB,GAAW9C,KAAKoB,YACX,CACLpB,KAAKuC,QACLO,EAAU9C,KAAKuC,QAAU,EAE3B,GAAIO,EAAS9C,KAAK8C,WAIpBZ,EAAUrC,UAAUiD,QAAU,kBACrB9C,KAAK2E,SAAS1C,aAAajC,KAAK6B,IAAIC,WAC3C,IAAK9B,KAAK2B,eAAgB3B,KAAK6B,IAAIJ,WAAWzB,KAAK0B,KAIrDvB,EAAOkD,KAASlD,EAAOgB,GACvBhB,EAAOyE,OAASzE,EAAOsC,IAIvBxD,EAAE4F,OAAOzF,EAAUe,GAYnB,IAAI2E,EAAQ1F,EAAS0F,MAAQ,SAASC,EAAY1C,GAChD,IAAI2C,EAAQD,GAAc,GAC1B1C,IAAYA,EAAU,IACtBrC,KAAKiF,cAAcxB,MAAMzD,KAAM0D,WAC/B1D,KAAKkF,IAAMjG,EAAE8C,SAAS/B,KAAKmF,WAC3BnF,KAAK+E,WAAa,GAClB,GAAI1C,EAAQ+C,WAAYpF,KAAKoF,WAAa/C,EAAQ+C,WAClD,GAAI/C,EAAQgD,MAAOL,EAAQhF,KAAKqF,MAAML,EAAO3C,IAAY,GACzD,IAAIiD,EAAWrG,EAAEsG,OAAOvF,KAAM,YAC9BgF,EAAQ/F,EAAEqG,SAASrG,EAAE4F,OAAO,GAAIS,EAAUN,GAAQM,GAClDtF,KAAKwF,IAAIR,EAAO3C,GAChBrC,KAAKyF,QAAU,GACfzF,KAAK0F,WAAWjC,MAAMzD,KAAM0D,YAI9BzE,EAAE4F,OAAOC,EAAMjF,UAAWM,EAAQ,CAGhCsF,QAAS,KAGTE,gBAAiB,KAIjBC,YAAa,KAIbT,UAAW,IAIXF,cAAe,aAIfS,WAAY,aAGZG,OAAQ,SAASxD,GACf,OAAOpD,EAAE6G,MAAM9F,KAAK+E,aAKtBgB,KAAM,WACJ,OAAO3G,EAAS2G,KAAKtC,MAAMzD,KAAM0D,YAInCsC,IAAK,SAASC,GACZ,OAAOjG,KAAK+E,WAAWkB,IAIzBC,OAAQ,SAASD,GACf,OAAOhH,EAAEiH,OAAOlG,KAAKgG,IAAIC,KAK3BE,IAAK,SAASF,GACZ,OAAOjG,KAAKgG,IAAIC,IAAS,MAI3BG,QAAS,SAASpB,GAChB,QAAS/F,EAAEsB,SAASyE,EAAOhF,KAAlBf,CAAwBe,KAAK+E,aAMxCS,IAAK,SAASa,EAAKC,EAAKjE,GACtB,GAAIgE,GAAO,KAAM,OAAOrG,KAGxB,IAAIgF,EACJ,UAAWqB,IAAQ,SAAU,CAC3BrB,EAAQqB,EACRhE,EAAUiE,MACL,EACJtB,EAAQ,IAAIqB,GAAOC,EAGtBjE,IAAYA,EAAU,IAGtB,IAAKrC,KAAKuG,UAAUvB,EAAO3C,GAAU,OAAO,MAG5C,IAAImE,EAAanE,EAAQmE,MACzB,IAAIC,EAAapE,EAAQoE,OACzB,IAAIC,EAAa,GACjB,IAAIC,EAAa3G,KAAK4G,UACtB5G,KAAK4G,UAAY,KAEjB,IAAKD,EAAU,CACb3G,KAAK6G,oBAAsB5H,EAAE6G,MAAM9F,KAAK+E,YACxC/E,KAAKyF,QAAU,GAGjB,IAAIqB,EAAU9G,KAAK+E,WACnB,IAAIU,EAAUzF,KAAKyF,QACnB,IAAIsB,EAAU/G,KAAK6G,oBAGnB,IAAK,IAAIZ,KAAQjB,EAAO,CACtBsB,EAAMtB,EAAMiB,GACZ,IAAKhH,EAAE+H,QAAQF,EAAQb,GAAOK,GAAMI,EAAQlE,KAAKyD,GACjD,IAAKhH,EAAE+H,QAAQD,EAAKd,GAAOK,GAAM,CAC/Bb,EAAQQ,GAAQK,MACX,QACEb,EAAQQ,GAEjBO,SAAeM,EAAQb,GAAQa,EAAQb,GAAQK,EAIjD,GAAItG,KAAK4F,eAAeZ,EAAO,CAC7B,IAAIiC,EAASjH,KAAK0B,GAClB1B,KAAK0B,GAAK1B,KAAKgG,IAAIhG,KAAK4F,aACxB5F,KAAK2D,QAAQ,WAAY3D,KAAMiH,EAAQ5E,GAIzC,IAAKoE,EAAQ,CACX,GAAIC,EAAQ1F,OAAQhB,KAAKkH,SAAW7E,EACpC,IAAK,IAAIzB,EAAI,EAAGA,EAAI8F,EAAQ1F,OAAQJ,IAAK,CACvCZ,KAAK2D,QAAQ,UAAY+C,EAAQ9F,GAAIZ,KAAM8G,EAAQJ,EAAQ9F,IAAKyB,IAMpE,GAAIsE,EAAU,OAAO3G,KACrB,IAAKyG,EAAQ,CACX,MAAOzG,KAAKkH,SAAU,CACpB7E,EAAUrC,KAAKkH,SACflH,KAAKkH,SAAW,MAChBlH,KAAK2D,QAAQ,SAAU3D,KAAMqC,IAGjCrC,KAAKkH,SAAW,MAChBlH,KAAK4G,UAAY,MACjB,OAAO5G,MAKTwG,MAAO,SAASP,EAAM5D,GACpB,OAAOrC,KAAKwF,IAAIS,OAAW,EAAGhH,EAAE4F,OAAO,GAAIxC,EAAS,CAACmE,MAAO,SAI9DW,MAAO,SAAS9E,GACd,IAAI2C,EAAQ,GACZ,IAAK,IAAIqB,KAAOrG,KAAK+E,WAAYC,EAAMqB,QAAY,EACnD,OAAOrG,KAAKwF,IAAIR,EAAO/F,EAAE4F,OAAO,GAAIxC,EAAS,CAACmE,MAAO,SAKvDY,WAAY,SAASnB,GACnB,GAAIA,GAAQ,KAAM,OAAQhH,EAAE4D,QAAQ7C,KAAKyF,SACzC,OAAOxG,EAAEkH,IAAInG,KAAKyF,QAASQ,IAS7BoB,kBAAmB,SAASC,GAC1B,IAAKA,EAAM,OAAOtH,KAAKoH,aAAenI,EAAE6G,MAAM9F,KAAKyF,SAAW,MAC9D,IAAI8B,EAAMvH,KAAK4G,UAAY5G,KAAK6G,oBAAsB7G,KAAK+E,WAC3D,IAAIU,EAAU,GACd,IAAI2B,EACJ,IAAK,IAAInB,KAAQqB,EAAM,CACrB,IAAIhB,EAAMgB,EAAKrB,GACf,GAAIhH,EAAE+H,QAAQO,EAAItB,GAAOK,GAAM,SAC/Bb,EAAQQ,GAAQK,EAChBc,EAAa,KAEf,OAAOA,EAAa3B,EAAU,OAKhC+B,SAAU,SAASvB,GACjB,GAAIA,GAAQ,OAASjG,KAAK6G,oBAAqB,OAAO,KACtD,OAAO7G,KAAK6G,oBAAoBZ,IAKlCwB,mBAAoB,WAClB,OAAOxI,EAAE6G,MAAM9F,KAAK6G,sBAKtBa,MAAO,SAASrF,GACdA,EAAUpD,EAAE4F,OAAO,CAACQ,MAAO,MAAOhD,GAClC,IAAIsF,EAAQ3H,KACZ,IAAI4H,EAAUvF,EAAQuF,QACtBvF,EAAQuF,QAAU,SAASC,GACzB,IAAIC,EAAczF,EAAQgD,MAAQsC,EAAMtC,MAAMwC,EAAMxF,GAAWwF,EAC/D,IAAKF,EAAMnC,IAAIsC,EAAazF,GAAU,OAAO,MAC7C,GAAIuF,EAASA,EAAQlD,KAAKrC,EAAQvB,QAAS6G,EAAOE,EAAMxF,GACxDsF,EAAMhE,QAAQ,OAAQgE,EAAOE,EAAMxF,IAErC0F,EAAU/H,KAAMqC,GAChB,OAAOrC,KAAK+F,KAAK,OAAQ/F,KAAMqC,IAMjC2F,KAAM,SAAS3B,EAAKC,EAAKjE,GAEvB,IAAI2C,EACJ,GAAIqB,GAAO,aAAeA,IAAQ,SAAU,CAC1CrB,EAAQqB,EACRhE,EAAUiE,MACL,EACJtB,EAAQ,IAAIqB,GAAOC,EAGtBjE,EAAUpD,EAAE4F,OAAO,CAACoD,SAAU,KAAM5C,MAAO,MAAOhD,GAClD,IAAI6F,EAAO7F,EAAQ6F,KAKnB,GAAIlD,IAAUkD,EAAM,CAClB,IAAKlI,KAAKwF,IAAIR,EAAO3C,GAAU,OAAO,WACjC,IAAKrC,KAAKuG,UAAUvB,EAAO3C,GAAU,CAC1C,OAAO,MAKT,IAAIsF,EAAQ3H,KACZ,IAAI4H,EAAUvF,EAAQuF,QACtB,IAAI7C,EAAa/E,KAAK+E,WACtB1C,EAAQuF,QAAU,SAASC,GAEzBF,EAAM5C,WAAaA,EACnB,IAAI+C,EAAczF,EAAQgD,MAAQsC,EAAMtC,MAAMwC,EAAMxF,GAAWwF,EAC/D,GAAIK,EAAMJ,EAAc7I,EAAE4F,OAAO,GAAIG,EAAO8C,GAC5C,GAAIA,IAAgBH,EAAMnC,IAAIsC,EAAazF,GAAU,OAAO,MAC5D,GAAIuF,EAASA,EAAQlD,KAAKrC,EAAQvB,QAAS6G,EAAOE,EAAMxF,GACxDsF,EAAMhE,QAAQ,OAAQgE,EAAOE,EAAMxF,IAErC0F,EAAU/H,KAAMqC,GAGhB,GAAI2C,GAASkD,EAAMlI,KAAK+E,WAAa9F,EAAE4F,OAAO,GAAIE,EAAYC,GAE9D,IAAImD,EAASnI,KAAKoI,QAAU,SAAW/F,EAAQgG,MAAQ,QAAU,SACjE,GAAIF,IAAW,UAAY9F,EAAQ2C,MAAO3C,EAAQ2C,MAAQA,EAC1D,IAAIsD,EAAMtI,KAAK+F,KAAKoC,EAAQnI,KAAMqC,GAGlCrC,KAAK+E,WAAaA,EAElB,OAAOuD,GAMTC,QAAS,SAASlG,GAChBA,EAAUA,EAAUpD,EAAE6G,MAAMzD,GAAW,GACvC,IAAIsF,EAAQ3H,KACZ,IAAI4H,EAAUvF,EAAQuF,QACtB,IAAIM,EAAO7F,EAAQ6F,KAEnB,IAAIK,EAAU,WACZZ,EAAMhF,gBACNgF,EAAMhE,QAAQ,UAAWgE,EAAOA,EAAMvC,WAAY/C,IAGpDA,EAAQuF,QAAU,SAASC,GACzB,GAAIK,EAAMK,IACV,GAAIX,EAASA,EAAQlD,KAAKrC,EAAQvB,QAAS6G,EAAOE,EAAMxF,GACxD,IAAKsF,EAAMS,QAAST,EAAMhE,QAAQ,OAAQgE,EAAOE,EAAMxF,IAGzD,IAAIiG,EAAM,MACV,GAAItI,KAAKoI,QAAS,CAChBnJ,EAAEuJ,MAAMnG,EAAQuF,aACX,CACLG,EAAU/H,KAAMqC,GAChBiG,EAAMtI,KAAK+F,KAAK,SAAU/F,KAAMqC,GAElC,IAAK6F,EAAMK,IACX,OAAOD,GAMTG,IAAK,WACH,IAAIC,EACFzJ,EAAEsG,OAAOvF,KAAM,YACff,EAAEsG,OAAOvF,KAAKoF,WAAY,QAC1BuD,IACF,GAAI3I,KAAKoI,QAAS,OAAOM,EACzB,IAAIhH,EAAK1B,KAAKgG,IAAIhG,KAAK4F,aACvB,OAAO8C,EAAKE,QAAQ,SAAU,OAASC,mBAAmBnH,IAK5D2D,MAAO,SAASwC,EAAMxF,GACpB,OAAOwF,GAIT/B,MAAO,WACL,OAAO,IAAI9F,KAAK8I,YAAY9I,KAAK+E,aAInCqD,MAAO,WACL,OAAQpI,KAAKmG,IAAInG,KAAK4F,cAIxBmD,QAAS,SAAS1G,GAChB,OAAOrC,KAAKuG,UAAU,GAAItH,EAAE4F,OAAO,GAAIxC,EAAS,CAAC4F,SAAU,SAK7D1B,UAAW,SAASvB,EAAO3C,GACzB,IAAKA,EAAQ4F,WAAajI,KAAKiI,SAAU,OAAO,KAChDjD,EAAQ/F,EAAE4F,OAAO,GAAI7E,KAAK+E,WAAYC,GACtC,IAAI7C,EAAQnC,KAAK2F,gBAAkB3F,KAAKiI,SAASjD,EAAO3C,IAAY,KACpE,IAAKF,EAAO,OAAO,KACnBnC,KAAK2D,QAAQ,UAAW3D,KAAMmC,EAAOlD,EAAE4F,OAAOxC,EAAS,CAACsD,gBAAiBxD,KACzE,OAAO,SAkBX,IAAI6G,EAAa5J,EAAS4J,WAAa,SAASC,EAAQ5G,GACtDA,IAAYA,EAAU,IACtBrC,KAAKiF,cAAcxB,MAAMzD,KAAM0D,WAC/B,GAAIrB,EAAQsF,MAAO3H,KAAK2H,MAAQtF,EAAQsF,MACxC,GAAItF,EAAQ6G,kBAAoB,EAAGlJ,KAAKkJ,WAAa7G,EAAQ6G,WAC7DlJ,KAAKmJ,SACLnJ,KAAK0F,WAAWjC,MAAMzD,KAAM0D,WAC5B,GAAIuF,EAAQjJ,KAAKoJ,MAAMH,EAAQhK,EAAE4F,OAAO,CAAC4B,OAAQ,MAAOpE,KAI1D,IAAIgH,EAAa,CAACC,IAAK,KAAMC,OAAQ,KAAMC,MAAO,MAClD,IAAIC,EAAa,CAACH,IAAK,KAAMC,OAAQ,OAGrC,IAAIG,EAAS,SAASC,EAAOC,EAAQC,GACnCA,EAAKjG,KAAKkG,IAAIlG,KAAKC,IAAIgG,EAAI,GAAIF,EAAM3I,QACrC,IAAI+I,EAAOnK,MAAM+J,EAAM3I,OAAS6I,GAChC,IAAI7I,EAAS4I,EAAO5I,OACpB,IAAIJ,EACJ,IAAKA,EAAI,EAAGA,EAAImJ,EAAK/I,OAAQJ,IAAKmJ,EAAKnJ,GAAK+I,EAAM/I,EAAIiJ,GACtD,IAAKjJ,EAAI,EAAGA,EAAII,EAAQJ,IAAK+I,EAAM/I,EAAIiJ,GAAMD,EAAOhJ,GACpD,IAAKA,EAAI,EAAGA,EAAImJ,EAAK/I,OAAQJ,IAAK+I,EAAM/I,EAAII,EAAS6I,GAAME,EAAKnJ,IAIlE3B,EAAE4F,OAAOmE,EAAWnJ,UAAWM,EAAQ,CAIrCwH,MAAO7C,EAKPG,cAAe,aAIfS,WAAY,aAIZG,OAAQ,SAASxD,GACf,OAAOrC,KAAKuD,IAAI,SAASoE,GAAS,OAAOA,EAAM9B,OAAOxD,MAIxD0D,KAAM,WACJ,OAAO3G,EAAS2G,KAAKtC,MAAMzD,KAAM0D,YAMnC4F,IAAK,SAASL,EAAQ5G,GACpB,OAAOrC,KAAKwF,IAAIyD,EAAQhK,EAAE4F,OAAO,CAAC2E,MAAO,OAAQnH,EAASoH,KAI5DF,OAAQ,SAASN,EAAQ5G,GACvBA,EAAUpD,EAAE4F,OAAO,GAAIxC,GACvB,IAAI2H,GAAY/K,EAAEgL,QAAQhB,GAC1BA,EAASe,EAAW,CAACf,GAAUA,EAAOtJ,QACtC,IAAIuK,EAAUlK,KAAKmK,cAAclB,EAAQ5G,GACzC,IAAKA,EAAQoE,QAAUyD,EAAQlJ,OAAQ,CACrCqB,EAAQqE,QAAU,CAAC0D,MAAO,GAAIC,OAAQ,GAAIH,QAASA,GACnDlK,KAAK2D,QAAQ,SAAU3D,KAAMqC,GAE/B,OAAO2H,EAAWE,EAAQ,GAAKA,GAOjC1E,IAAK,SAASyD,EAAQ5G,GACpB,GAAI4G,GAAU,KAAM,OAEpB5G,EAAUpD,EAAE4F,OAAO,GAAIwE,EAAYhH,GACnC,GAAIA,EAAQgD,QAAUrF,KAAKsK,SAASrB,GAAS,CAC3CA,EAASjJ,KAAKqF,MAAM4D,EAAQ5G,IAAY,GAG1C,IAAI2H,GAAY/K,EAAEgL,QAAQhB,GAC1BA,EAASe,EAAW,CAACf,GAAUA,EAAOtJ,QAEtC,IAAIkK,EAAKxH,EAAQwH,GACjB,GAAIA,GAAM,KAAMA,GAAMA,EACtB,GAAIA,EAAK7J,KAAKgB,OAAQ6I,EAAK7J,KAAKgB,OAChC,GAAI6I,EAAK,EAAGA,GAAM7J,KAAKgB,OAAS,EAEhC,IAAIwE,EAAM,GACV,IAAI+E,EAAQ,GACZ,IAAIC,EAAU,GACd,IAAIC,EAAW,GACf,IAAIC,EAAW,GAEf,IAAIpB,EAAMjH,EAAQiH,IAClB,IAAIE,EAAQnH,EAAQmH,MACpB,IAAID,EAASlH,EAAQkH,OAErB,IAAIoB,EAAO,MACX,IAAIC,EAAW5K,KAAKkJ,YAAcW,GAAM,MAAQxH,EAAQsI,OAAS,MACjE,IAAIE,EAAW5L,EAAE6L,SAAS9K,KAAKkJ,YAAclJ,KAAKkJ,WAAa,KAI/D,IAAIvB,EAAO/G,EACX,IAAKA,EAAI,EAAGA,EAAIqI,EAAOjI,OAAQJ,IAAK,CAClC+G,EAAQsB,EAAOrI,GAIf,IAAImK,EAAW/K,KAAKgG,IAAI2B,GACxB,GAAIoD,EAAU,CACZ,GAAIvB,GAAS7B,IAAUoD,EAAU,CAC/B,IAAI/F,EAAQhF,KAAKsK,SAAS3C,GAASA,EAAM5C,WAAa4C,EACtD,GAAItF,EAAQgD,MAAOL,EAAQ+F,EAAS1F,MAAML,EAAO3C,GACjD0I,EAASvF,IAAIR,EAAO3C,GACpBmI,EAAQhI,KAAKuI,GACb,GAAIH,IAAaD,EAAMA,EAAOI,EAAS3D,WAAWyD,GAEpD,IAAKH,EAASK,EAAS7F,KAAM,CAC3BwF,EAASK,EAAS7F,KAAO,KACzBM,EAAIhD,KAAKuI,GAEX9B,EAAOrI,GAAKmK,OAGP,GAAIzB,EAAK,CACd3B,EAAQsB,EAAOrI,GAAKZ,KAAKgL,cAAcrD,EAAOtF,GAC9C,GAAIsF,EAAO,CACT4C,EAAM/H,KAAKmF,GACX3H,KAAKiL,cAActD,EAAOtF,GAC1BqI,EAAS/C,EAAMzC,KAAO,KACtBM,EAAIhD,KAAKmF,KAMf,GAAI4B,EAAQ,CACV,IAAK3I,EAAI,EAAGA,EAAIZ,KAAKgB,OAAQJ,IAAK,CAChC+G,EAAQ3H,KAAKiJ,OAAOrI,GACpB,IAAK8J,EAAS/C,EAAMzC,KAAMuF,EAASjI,KAAKmF,GAE1C,GAAI8C,EAASzJ,OAAQhB,KAAKmK,cAAcM,EAAUpI,GAIpD,IAAI6I,EAAe,MACnB,IAAItC,GAAWgC,GAAYtB,GAAOC,EAClC,GAAI/D,EAAIxE,QAAU4H,EAAS,CACzBsC,EAAelL,KAAKgB,SAAWwE,EAAIxE,QAAU/B,EAAEkM,KAAKnL,KAAKiJ,OAAQ,SAASmC,EAAGC,GAC3E,OAAOD,IAAM5F,EAAI6F,KAEnBrL,KAAKiJ,OAAOjI,OAAS,EACrB0I,EAAO1J,KAAKiJ,OAAQzD,EAAK,GACzBxF,KAAKgB,OAAShB,KAAKiJ,OAAOjI,YACrB,GAAIuJ,EAAMvJ,OAAQ,CACvB,GAAI4J,EAAUD,EAAO,KACrBjB,EAAO1J,KAAKiJ,OAAQsB,EAAOV,GAAM,KAAO7J,KAAKgB,OAAS6I,GACtD7J,KAAKgB,OAAShB,KAAKiJ,OAAOjI,OAI5B,GAAI2J,EAAM3K,KAAK2K,KAAK,CAAClE,OAAQ,OAG7B,IAAKpE,EAAQoE,OAAQ,CACnB,IAAK7F,EAAI,EAAGA,EAAI2J,EAAMvJ,OAAQJ,IAAK,CACjC,GAAIiJ,GAAM,KAAMxH,EAAQgJ,MAAQxB,EAAKjJ,EACrC+G,EAAQ4C,EAAM3J,GACd+G,EAAMhE,QAAQ,MAAOgE,EAAO3H,KAAMqC,GAEpC,GAAIsI,GAAQO,EAAclL,KAAK2D,QAAQ,OAAQ3D,KAAMqC,GACrD,GAAIkI,EAAMvJ,QAAUyJ,EAASzJ,QAAUwJ,EAAQxJ,OAAQ,CACrDqB,EAAQqE,QAAU,CAChB0D,MAAOG,EACPL,QAASO,EACTJ,OAAQG,GAEVxK,KAAK2D,QAAQ,SAAU3D,KAAMqC,IAKjC,OAAO2H,EAAWf,EAAO,GAAKA,GAOhCG,MAAO,SAASH,EAAQ5G,GACtBA,EAAUA,EAAUpD,EAAE6G,MAAMzD,GAAW,GACvC,IAAK,IAAIzB,EAAI,EAAGA,EAAIZ,KAAKiJ,OAAOjI,OAAQJ,IAAK,CAC3CZ,KAAKsL,iBAAiBtL,KAAKiJ,OAAOrI,GAAIyB,GAExCA,EAAQkJ,eAAiBvL,KAAKiJ,OAC9BjJ,KAAKmJ,SACLF,EAASjJ,KAAKsJ,IAAIL,EAAQhK,EAAE4F,OAAO,CAAC4B,OAAQ,MAAOpE,IACnD,IAAKA,EAAQoE,OAAQzG,KAAK2D,QAAQ,QAAS3D,KAAMqC,GACjD,OAAO4G,GAITzG,KAAM,SAASmF,EAAOtF,GACpB,OAAOrC,KAAKsJ,IAAI3B,EAAO1I,EAAE4F,OAAO,CAACgF,GAAI7J,KAAKgB,QAASqB,KAIrDmJ,IAAK,SAASnJ,GACZ,IAAIsF,EAAQ3H,KAAK6J,GAAG7J,KAAKgB,OAAS,GAClC,OAAOhB,KAAKuJ,OAAO5B,EAAOtF,IAI5BoJ,QAAS,SAAS9D,EAAOtF,GACvB,OAAOrC,KAAKsJ,IAAI3B,EAAO1I,EAAE4F,OAAO,CAACgF,GAAI,GAAIxH,KAI3CqJ,MAAO,SAASrJ,GACd,IAAIsF,EAAQ3H,KAAK6J,GAAG,GACpB,OAAO7J,KAAKuJ,OAAO5B,EAAOtF,IAI5B1C,MAAO,WACL,OAAOA,EAAM8D,MAAMzD,KAAKiJ,OAAQvF,YAKlCsC,IAAK,SAASnE,GACZ,GAAIA,GAAO,KAAM,YAAY,EAC7B,OAAO7B,KAAK2L,MAAM9J,IAChB7B,KAAK2L,MAAM3L,KAAK4L,QAAQ5L,KAAKsK,SAASzI,GAAOA,EAAIkD,WAAalD,EAAKA,EAAI+D,eACvE/D,EAAIqD,KAAOlF,KAAK2L,MAAM9J,EAAIqD,MAI9BiB,IAAK,SAAStE,GACZ,OAAO7B,KAAKgG,IAAInE,IAAQ,MAI1BgI,GAAI,SAASwB,GACX,GAAIA,EAAQ,EAAGA,GAASrL,KAAKgB,OAC7B,OAAOhB,KAAKiJ,OAAOoC,IAKrBQ,MAAO,SAAS7G,EAAO8G,GACrB,OAAO9L,KAAK8L,EAAQ,OAAS,UAAU9G,IAKzC+G,UAAW,SAAS/G,GAClB,OAAOhF,KAAK6L,MAAM7G,EAAO,OAM3B2F,KAAM,SAAStI,GACb,IAAI6G,EAAalJ,KAAKkJ,WACtB,IAAKA,EAAY,MAAM,IAAI8C,MAAM,0CACjC3J,IAAYA,EAAU,IAEtB,IAAIrB,EAASkI,EAAWlI,OACxB,GAAI/B,EAAEgN,WAAW/C,GAAaA,EAAaA,EAAW7F,KAAKrD,MAG3D,GAAIgB,IAAW,GAAK/B,EAAE6L,SAAS5B,GAAa,CAC1ClJ,KAAKiJ,OAASjJ,KAAKkM,OAAOhD,OACrB,CACLlJ,KAAKiJ,OAAO0B,KAAKzB,GAEnB,IAAK7G,EAAQoE,OAAQzG,KAAK2D,QAAQ,OAAQ3D,KAAMqC,GAChD,OAAOrC,MAITmM,MAAO,SAASlG,GACd,OAAOjG,KAAKuD,IAAI0C,EAAO,KAMzByB,MAAO,SAASrF,GACdA,EAAUpD,EAAE4F,OAAO,CAACQ,MAAO,MAAOhD,GAClC,IAAIuF,EAAUvF,EAAQuF,QACtB,IAAIxC,EAAapF,KACjBqC,EAAQuF,QAAU,SAASC,GACzB,IAAIM,EAAS9F,EAAQ+G,MAAQ,QAAU,MACvChE,EAAW+C,GAAQN,EAAMxF,GACzB,GAAIuF,EAASA,EAAQlD,KAAKrC,EAAQvB,QAASsE,EAAYyC,EAAMxF,GAC7D+C,EAAWzB,QAAQ,OAAQyB,EAAYyC,EAAMxF,IAE/C0F,EAAU/H,KAAMqC,GAChB,OAAOrC,KAAK+F,KAAK,OAAQ/F,KAAMqC,IAMjC+J,OAAQ,SAASzE,EAAOtF,GACtBA,EAAUA,EAAUpD,EAAE6G,MAAMzD,GAAW,GACvC,IAAI6F,EAAO7F,EAAQ6F,KACnBP,EAAQ3H,KAAKgL,cAAcrD,EAAOtF,GAClC,IAAKsF,EAAO,OAAO,MACnB,IAAKO,EAAMlI,KAAKsJ,IAAI3B,EAAOtF,GAC3B,IAAI+C,EAAapF,KACjB,IAAI4H,EAAUvF,EAAQuF,QACtBvF,EAAQuF,QAAU,SAASwD,EAAGvD,EAAMwE,GAClC,GAAInE,EAAM9C,EAAWkE,IAAI8B,EAAGiB,GAC5B,GAAIzE,EAASA,EAAQlD,KAAK2H,EAAavL,QAASsK,EAAGvD,EAAMwE,IAE3D1E,EAAMK,KAAK,KAAM3F,GACjB,OAAOsF,GAKTtC,MAAO,SAASwC,EAAMxF,GACpB,OAAOwF,GAIT/B,MAAO,WACL,OAAO,IAAI9F,KAAK8I,YAAY9I,KAAKiJ,OAAQ,CACvCtB,MAAO3H,KAAK2H,MACZuB,WAAYlJ,KAAKkJ,cAKrB0C,QAAS,SAAS5G,EAAOY,GACvB,OAAOZ,EAAMY,GAAe5F,KAAK2H,MAAM9H,UAAU+F,aAAe,OAIlE0G,OAAQ,WACN,OAAO,IAAIC,EAAmBvM,KAAMwM,IAItCzL,KAAM,WACJ,OAAO,IAAIwL,EAAmBvM,KAAMyM,IAItCC,QAAS,WACP,OAAO,IAAIH,EAAmBvM,KAAM2M,IAKtCxD,OAAQ,WACNnJ,KAAKgB,OAAS,EACdhB,KAAKiJ,OAAS,GACdjJ,KAAK2L,MAAS,IAKhBX,cAAe,SAAShG,EAAO3C,GAC7B,GAAIrC,KAAKsK,SAAStF,GAAQ,CACxB,IAAKA,EAAMI,WAAYJ,EAAMI,WAAapF,KAC1C,OAAOgF,EAET3C,EAAUA,EAAUpD,EAAE6G,MAAMzD,GAAW,GACvCA,EAAQ+C,WAAapF,KAErB,IAAI2H,EACJ,GAAI3H,KAAK2H,MAAM9H,UAAW,CACxB8H,EAAQ,IAAI3H,KAAK2H,MAAM3C,EAAO3C,OACzB,CAELsF,EAAQ3H,KAAK2H,MAAM3C,EAAO3C,GAG5B,IAAKsF,EAAMhC,gBAAiB,OAAOgC,EACnC3H,KAAK2D,QAAQ,UAAW3D,KAAM2H,EAAMhC,gBAAiBtD,GACrD,OAAO,OAIT8H,cAAe,SAASlB,EAAQ5G,GAC9B,IAAI6H,EAAU,GACd,IAAK,IAAItJ,EAAI,EAAGA,EAAIqI,EAAOjI,OAAQJ,IAAK,CACtC,IAAI+G,EAAQ3H,KAAKgG,IAAIiD,EAAOrI,IAC5B,IAAK+G,EAAO,SAEZ,IAAI0D,EAAQrL,KAAK4M,QAAQjF,GACzB3H,KAAKiJ,OAAOS,OAAO2B,EAAO,GAC1BrL,KAAKgB,gBAIEhB,KAAK2L,MAAMhE,EAAMzC,KACxB,IAAIxD,EAAK1B,KAAK4L,QAAQjE,EAAM5C,WAAY4C,EAAM/B,aAC9C,GAAIlE,GAAM,YAAa1B,KAAK2L,MAAMjK,GAElC,IAAKW,EAAQoE,OAAQ,CACnBpE,EAAQgJ,MAAQA,EAChB1D,EAAMhE,QAAQ,SAAUgE,EAAO3H,KAAMqC,GAGvC6H,EAAQ1H,KAAKmF,GACb3H,KAAKsL,iBAAiB3D,EAAOtF,GAE/B,OAAO6H,GAKTI,SAAU,SAAS3C,GACjB,OAAOA,aAAiB7C,GAI1BmG,cAAe,SAAStD,EAAOtF,GAC7BrC,KAAK2L,MAAMhE,EAAMzC,KAAOyC,EACxB,IAAIjG,EAAK1B,KAAK4L,QAAQjE,EAAM5C,WAAY4C,EAAM/B,aAC9C,GAAIlE,GAAM,KAAM1B,KAAK2L,MAAMjK,GAAMiG,EACjCA,EAAMxG,GAAG,MAAOnB,KAAK6M,cAAe7M,OAItCsL,iBAAkB,SAAS3D,EAAOtF,UACzBrC,KAAK2L,MAAMhE,EAAMzC,KACxB,IAAIxD,EAAK1B,KAAK4L,QAAQjE,EAAM5C,WAAY4C,EAAM/B,aAC9C,GAAIlE,GAAM,YAAa1B,KAAK2L,MAAMjK,GAClC,GAAI1B,OAAS2H,EAAMvC,kBAAmBuC,EAAMvC,WAC5CuC,EAAMlF,IAAI,MAAOzC,KAAK6M,cAAe7M,OAOvC6M,cAAe,SAASC,EAAOnF,EAAOvC,EAAY/C,GAChD,GAAIsF,EAAO,CACT,IAAKmF,IAAU,OAASA,IAAU,WAAa1H,IAAepF,KAAM,OACpE,GAAI8M,IAAU,UAAW9M,KAAKuJ,OAAO5B,EAAOtF,GAC5C,GAAIyK,IAAU,WAAY,CACxB,IAAI7F,EAASjH,KAAK4L,QAAQjE,EAAMF,qBAAsBE,EAAM/B,aAC5D,IAAIlE,EAAK1B,KAAK4L,QAAQjE,EAAM5C,WAAY4C,EAAM/B,aAC9C,GAAIqB,GAAU,YAAajH,KAAK2L,MAAM1E,GACtC,GAAIvF,GAAM,KAAM1B,KAAK2L,MAAMjK,GAAMiG,GAGrC3H,KAAK2D,QAAQF,MAAMzD,KAAM0D,cAQ7B,IAAIqJ,SAAoBC,SAAW,YAAcA,OAAOC,SACxD,GAAIF,EAAY,CACd/D,EAAWnJ,UAAUkN,GAAc/D,EAAWnJ,UAAUyM,OAU1D,IAAIC,EAAqB,SAASnH,EAAY8H,GAC5ClN,KAAKmN,YAAc/H,EACnBpF,KAAKoN,MAAQF,EACblN,KAAKqN,OAAS,GAMhB,IAAIb,EAAkB,EACtB,IAAIC,EAAgB,EACpB,IAAIE,EAAsB,EAG1B,GAAII,EAAY,CACdR,EAAmB1M,UAAUkN,GAAc,WACzC,OAAO/M,MAIXuM,EAAmB1M,UAAUyN,KAAO,WAClC,GAAItN,KAAKmN,YAAa,CAGpB,GAAInN,KAAKqN,OAASrN,KAAKmN,YAAYnM,OAAQ,CACzC,IAAI2G,EAAQ3H,KAAKmN,YAAYtD,GAAG7J,KAAKqN,QACrCrN,KAAKqN,SAGL,IAAIE,EACJ,GAAIvN,KAAKoN,QAAUZ,EAAiB,CAClCe,EAAQ5F,MACH,CACL,IAAIjG,EAAK1B,KAAKmN,YAAYvB,QAAQjE,EAAM5C,WAAY4C,EAAM/B,aAC1D,GAAI5F,KAAKoN,QAAUX,EAAe,CAChCc,EAAQ7L,MACH,CACL6L,EAAQ,CAAC7L,EAAIiG,IAGjB,MAAO,CAAC4F,MAAOA,EAAOC,KAAM,OAK9BxN,KAAKmN,iBAAmB,EAG1B,MAAO,CAACI,WAAY,EAAGC,KAAM,OAgB/B,IAAIC,EAAOrO,EAASqO,KAAO,SAASpL,GAClCrC,KAAKkF,IAAMjG,EAAE8C,SAAS,QACtB/B,KAAKiF,cAAcxB,MAAMzD,KAAM0D,WAC/BzE,EAAE4F,OAAO7E,KAAMf,EAAEyO,KAAKrL,EAASsL,IAC/B3N,KAAK4N,iBACL5N,KAAK0F,WAAWjC,MAAMzD,KAAM0D,YAI9B,IAAImK,EAAwB,iBAG5B,IAAIF,EAAc,CAAC,QAAS,aAAc,KAAM,KAAM,aAAc,YAAa,UAAW,UAG5F1O,EAAE4F,OAAO4I,EAAK5N,UAAWM,EAAQ,CAG/B2N,QAAS,MAIT5O,EAAG,SAAS6O,GACV,OAAO/N,KAAKgO,IAAIC,KAAKF,IAKvB9I,cAAe,aAIfS,WAAY,aAKZwI,OAAQ,WACN,OAAOlO,MAKTuJ,OAAQ,WACNvJ,KAAKmO,iBACLnO,KAAK2C,gBACL,OAAO3C,MAMTmO,eAAgB,WACdnO,KAAKgO,IAAIzE,UAKX6E,WAAY,SAASC,GACnBrO,KAAKsO,mBACLtO,KAAKuO,YAAYF,GACjBrO,KAAKwO,iBACL,OAAOxO,MAQTuO,YAAa,SAASE,GACpBzO,KAAKgO,IAAMS,aAAcrP,EAASF,EAAIuP,EAAKrP,EAASF,EAAEuP,GACtDzO,KAAKyO,GAAKzO,KAAKgO,IAAI,IAgBrBQ,eAAgB,SAAShO,GACvBA,IAAWA,EAASvB,EAAEsG,OAAOvF,KAAM,WACnC,IAAKQ,EAAQ,OAAOR,KACpBA,KAAKsO,mBACL,IAAK,IAAIjI,KAAO7F,EAAQ,CACtB,IAAI2H,EAAS3H,EAAO6F,GACpB,IAAKpH,EAAEgN,WAAW9D,GAASA,EAASnI,KAAKmI,GACzC,IAAKA,EAAQ,SACb,IAAIuG,EAAQrI,EAAIqI,MAAMb,GACtB7N,KAAK2O,SAASD,EAAM,GAAIA,EAAM,GAAIvG,EAAO9E,KAAKrD,OAEhD,OAAOA,MAMT2O,SAAU,SAASC,EAAWb,EAAUpJ,GACtC3E,KAAKgO,IAAI7M,GAAGyN,EAAY,kBAAoB5O,KAAKkF,IAAK6I,EAAUpJ,GAChE,OAAO3E,MAMTsO,iBAAkB,WAChB,GAAItO,KAAKgO,IAAKhO,KAAKgO,IAAIvL,IAAI,kBAAoBzC,KAAKkF,KACpD,OAAOlF,MAKT6O,WAAY,SAASD,EAAWb,EAAUpJ,GACxC3E,KAAKgO,IAAIvL,IAAImM,EAAY,kBAAoB5O,KAAKkF,IAAK6I,EAAUpJ,GACjE,OAAO3E,MAKT8O,eAAgB,SAAShB,GACvB,OAAOiB,SAASC,cAAclB,IAOhCF,eAAgB,WACd,IAAK5N,KAAKyO,GAAI,CACZ,IAAIzJ,EAAQ/F,EAAE4F,OAAO,GAAI5F,EAAEsG,OAAOvF,KAAM,eACxC,GAAIA,KAAK0B,GAAIsD,EAAMtD,GAAKzC,EAAEsG,OAAOvF,KAAM,MACvC,GAAIA,KAAKiP,UAAWjK,EAAM,SAAW/F,EAAEsG,OAAOvF,KAAM,aACpDA,KAAKoO,WAAWpO,KAAK8O,eAAe7P,EAAEsG,OAAOvF,KAAM,aACnDA,KAAKkP,eAAelK,OACf,CACLhF,KAAKoO,WAAWnP,EAAEsG,OAAOvF,KAAM,SAMnCkP,eAAgB,SAASnK,GACvB/E,KAAKgO,IAAI/H,KAAKlB,MAYlB,IAAIoK,EAAY,SAASzG,EAAM1H,EAAQmH,EAAQiH,GAC7C,OAAQpO,GACN,KAAK,EAAG,OAAO,WACb,OAAO0H,EAAKP,GAAQnI,KAAKoP,KAE3B,KAAK,EAAG,OAAO,SAAS7B,GACtB,OAAO7E,EAAKP,GAAQnI,KAAKoP,GAAY7B,IAEvC,KAAK,EAAG,OAAO,SAAShN,EAAUO,GAChC,OAAO4H,EAAKP,GAAQnI,KAAKoP,GAAYC,EAAG9O,EAAUP,MAAOc,IAE3D,KAAK,EAAG,OAAO,SAASP,EAAU+O,EAAYxO,GAC5C,OAAO4H,EAAKP,GAAQnI,KAAKoP,GAAYC,EAAG9O,EAAUP,MAAOsP,EAAYxO,IAEvE,QAAS,OAAO,WACd,IAAIgD,EAAOnE,EAAM+E,KAAKhB,WACtBI,EAAK2H,QAAQzL,KAAKoP,IAClB,OAAO1G,EAAKP,GAAQ1E,MAAMiF,EAAM5E,MAKtC,IAAIyL,EAAuB,SAASC,EAAO9G,EAAM+G,EAASL,GACxDnQ,EAAEyQ,KAAKD,EAAS,SAASzO,EAAQmH,GAC/B,GAAIO,EAAKP,GAASqH,EAAM3P,UAAUsI,GAAUgH,EAAUzG,EAAM1H,EAAQmH,EAAQiH,MAKhF,IAAIC,EAAK,SAAS9O,EAAUoP,GAC1B,GAAI1Q,EAAEgN,WAAW1L,GAAW,OAAOA,EACnC,GAAItB,EAAE2Q,SAASrP,KAAcoP,EAASrF,SAAS/J,GAAW,OAAOsP,EAAatP,GAC9E,GAAItB,EAAE6L,SAASvK,GAAW,OAAO,SAASoH,GAAS,OAAOA,EAAM3B,IAAIzF,IACpE,OAAOA,GAET,IAAIsP,EAAe,SAAS7K,GAC1B,IAAI8K,EAAU7Q,EAAEmH,QAAQpB,GACxB,OAAO,SAAS2C,GACd,OAAOmI,EAAQnI,EAAM5C,cAOzB,IAAIgL,EAAoB,CAACC,QAAS,EAAGN,KAAM,EAAGnM,IAAK,EAAG0M,QAAS,EAAGC,OAAQ,EACxEC,MAAO,EAAGC,OAAQ,EAAGC,YAAa,EAAGC,MAAO,EAAGrC,KAAM,EAAGsC,OAAQ,EAAGC,OAAQ,EAC3EC,OAAQ,EAAGC,OAAQ,EAAGC,MAAO,EAAGzM,IAAK,EAAGiH,KAAM,EAAGyF,IAAK,EAAGC,QAAS,EAAGC,SAAU,EAC/EC,SAAU,EAAGC,OAAQ,EAAGnN,IAAK,EAAGiG,IAAK,EAAGmH,QAAS,EAAGC,KAAM,EAAGpF,MAAO,EACpEqF,KAAM,EAAGC,KAAM,EAAGC,QAAS,EAAGC,KAAM,EAAGvH,KAAM,EAAGwH,KAAM,EAAGC,KAAM,EAC/DC,QAAS,EAAGC,WAAY,EAAG9E,QAAS,EAAG+E,QAAS,EAAGC,YAAa,EAChE/O,QAAS,EAAGgP,MAAO,EAAGC,OAAQ,EAAGC,UAAW,EAAGC,QAAS,EAAGC,QAAS,EACpE/F,OAAQ,EAAGgG,QAAS,EAAGC,UAAW,EAAGC,cAAe,GAKtD,IAAIC,EAAe,CAACtR,KAAM,EAAGuL,OAAQ,EAAGgG,MAAO,EAAGC,OAAQ,EAAG7E,KAAM,EACjE8E,KAAM,EAAGX,MAAO,EAAGhP,QAAS,GAI9B5D,EAAEyQ,KAAK,CACL,CAAC1G,EAAY+G,EAAmB,UAChC,CAACjL,EAAOuN,EAAc,eACrB,SAASI,GACV,IAAIC,EAAOD,EAAO,GACdhD,EAAUgD,EAAO,GACjBrD,EAAYqD,EAAO,GAEvBC,EAAKC,MAAQ,SAAS9Q,GACpB,IAAI+Q,EAAW3T,EAAEiR,OAAOjR,EAAE4T,UAAUhR,GAAM,SAASiR,EAAMrS,GACvDqS,EAAKrS,GAAQ,EACb,OAAOqS,GACN,IACHvD,EAAqBmD,EAAM7Q,EAAK+Q,EAAUxD,IAG5CG,EAAqBmD,EAAMzT,EAAGwQ,EAASL,KAqBzChQ,EAAS2G,KAAO,SAASoC,EAAQR,EAAOtF,GACtC,IAAI0Q,EAAOC,EAAU7K,GAGrBlJ,EAAEqG,SAASjD,IAAYA,EAAU,IAAK,CACpCpC,YAAab,EAASa,YACtBC,YAAad,EAASc,cAIxB,IAAI+S,EAAS,CAACF,KAAMA,EAAMG,SAAU,QAGpC,IAAK7Q,EAAQoG,IAAK,CAChBwK,EAAOxK,IAAMxJ,EAAEsG,OAAOoC,EAAO,QAAUgB,IAIzC,GAAItG,EAAQ8Q,MAAQ,MAAQxL,IAAUQ,IAAW,UAAYA,IAAW,UAAYA,IAAW,SAAU,CACvG8K,EAAOG,YAAc,mBACrBH,EAAOE,KAAOE,KAAKC,UAAUjR,EAAQ2C,OAAS2C,EAAM9B,OAAOxD,IAI7D,GAAIA,EAAQnC,YAAa,CACvB+S,EAAOG,YAAc,oCACrBH,EAAOE,KAAOF,EAAOE,KAAO,CAACxL,MAAOsL,EAAOE,MAAQ,GAKrD,GAAI9Q,EAAQpC,cAAgB8S,IAAS,OAASA,IAAS,UAAYA,IAAS,SAAU,CACpFE,EAAOF,KAAO,OACd,GAAI1Q,EAAQnC,YAAa+S,EAAOE,KAAKI,QAAUR,EAC/C,IAAIS,EAAanR,EAAQmR,WACzBnR,EAAQmR,WAAa,SAASlL,GAC5BA,EAAImL,iBAAiB,yBAA0BV,GAC/C,GAAIS,EAAY,OAAOA,EAAW/P,MAAMzD,KAAM0D,YAKlD,GAAIuP,EAAOF,OAAS,QAAU1Q,EAAQnC,YAAa,CACjD+S,EAAOS,YAAc,MAIvB,IAAIvR,EAAQE,EAAQF,MACpBE,EAAQF,MAAQ,SAASmG,EAAKqL,EAAYC,GACxCvR,EAAQsR,WAAaA,EACrBtR,EAAQuR,YAAcA,EACtB,GAAIzR,EAAOA,EAAMuC,KAAKrC,EAAQvB,QAASwH,EAAKqL,EAAYC,IAI1D,IAAItL,EAAMjG,EAAQiG,IAAMlJ,EAASyU,KAAK5U,EAAE4F,OAAOoO,EAAQ5Q,IACvDsF,EAAMhE,QAAQ,UAAWgE,EAAOW,EAAKjG,GACrC,OAAOiG,GAIT,IAAI0K,EAAY,CACd5G,OAAU,OACV0H,OAAU,MACVzL,MAAS,QACT0L,OAAU,SACVC,KAAQ,OAKV5U,EAASyU,KAAO,WACd,OAAOzU,EAASF,EAAE2U,KAAKpQ,MAAMrE,EAASF,EAAGwE,YAQ3C,IAAIuQ,EAAS7U,EAAS6U,OAAS,SAAS5R,GACtCA,IAAYA,EAAU,IACtBrC,KAAKiF,cAAcxB,MAAMzD,KAAM0D,WAC/B,GAAIrB,EAAQ6R,OAAQlU,KAAKkU,OAAS7R,EAAQ6R,OAC1ClU,KAAKmU,cACLnU,KAAK0F,WAAWjC,MAAMzD,KAAM0D,YAK9B,IAAI0Q,EAAgB,aACpB,IAAIC,EAAgB,eACpB,IAAIC,EAAgB,SACpB,IAAIC,EAAgB,2BAGpBtV,EAAE4F,OAAOoP,EAAOpU,UAAWM,EAAQ,CAIjC8E,cAAe,aAIfS,WAAY,aAQZ8O,MAAO,SAASA,EAAO/T,EAAMC,GAC3B,IAAKzB,EAAEwV,SAASD,GAAQA,EAAQxU,KAAK0U,eAAeF,GACpD,GAAIvV,EAAEgN,WAAWxL,GAAO,CACtBC,EAAWD,EACXA,EAAO,GAET,IAAKC,EAAUA,EAAWV,KAAKS,GAC/B,IAAIkU,EAAS3U,KACbZ,EAASwV,QAAQJ,MAAMA,EAAO,SAASK,GACrC,IAAI/Q,EAAO6Q,EAAOG,mBAAmBN,EAAOK,GAC5C,GAAIF,EAAOI,QAAQrU,EAAUoD,EAAMrD,KAAU,MAAO,CAClDkU,EAAOhR,QAAQF,MAAMkR,EAAQ,CAAC,SAAWlU,GAAM2D,OAAON,IACtD6Q,EAAOhR,QAAQ,QAASlD,EAAMqD,GAC9B1E,EAASwV,QAAQjR,QAAQ,QAASgR,EAAQlU,EAAMqD,MAGpD,OAAO9D,MAKT+U,QAAS,SAASrU,EAAUoD,EAAMrD,GAChC,GAAIC,EAAUA,EAAS+C,MAAMzD,KAAM8D,IAIrCkR,SAAU,SAASH,EAAUxS,GAC3BjD,EAASwV,QAAQI,SAASH,EAAUxS,GACpC,OAAOrC,MAMTmU,YAAa,WACX,IAAKnU,KAAKkU,OAAQ,OAClBlU,KAAKkU,OAASjV,EAAEsG,OAAOvF,KAAM,UAC7B,IAAIwU,EAAON,EAASjV,EAAE8B,KAAKf,KAAKkU,QAChC,OAAQM,EAAQN,EAAO1I,QAAU,KAAM,CACrCxL,KAAKwU,MAAMA,EAAOxU,KAAKkU,OAAOM,MAMlCE,eAAgB,SAASF,GACvBA,EAAQA,EAAM5L,QAAQ2L,EAAc,QACnC3L,QAAQwL,EAAe,WACvBxL,QAAQyL,EAAY,SAAS3F,EAAOuG,GACnC,OAAOA,EAAWvG,EAAQ,aAE3B9F,QAAQ0L,EAAY,YACrB,OAAO,IAAIY,OAAO,IAAMV,EAAQ,yBAMlCM,mBAAoB,SAASN,EAAOK,GAClC,IAAI5B,EAASuB,EAAMW,KAAKN,GAAUlV,MAAM,GACxC,OAAOV,EAAEsE,IAAI0P,EAAQ,SAASmC,EAAOxU,GAEnC,GAAIA,IAAMqS,EAAOjS,OAAS,EAAG,OAAOoU,GAAS,KAC7C,OAAOA,EAAQC,mBAAmBD,GAAS,UAcjD,IAAIE,EAAUlW,EAASkW,QAAU,WAC/BtV,KAAKsC,SAAW,GAChBtC,KAAKuV,SAAWvV,KAAKuV,SAASlS,KAAKrD,MAGnC,UAAWwV,SAAW,YAAa,CACjCxV,KAAKyV,SAAWD,OAAOC,SACvBzV,KAAK4U,QAAUY,OAAOZ,UAK1B,IAAIc,EAAgB,eAGpB,IAAIC,EAAe,aAGnB,IAAIC,EAAe,OAGnBN,EAAQO,QAAU,MAGlB5W,EAAE4F,OAAOyQ,EAAQzV,UAAWM,EAAQ,CAIlC2V,SAAU,GAGVC,OAAQ,WACN,IAAIC,EAAOhW,KAAKyV,SAASQ,SAASrN,QAAQ,SAAU,OACpD,OAAOoN,IAAShW,KAAKpB,OAASoB,KAAKkW,aAIrCC,UAAW,WACT,IAAIH,EAAOhW,KAAKoW,eAAepW,KAAKyV,SAASQ,UAC7C,IAAII,EAAWL,EAAKrW,MAAM,EAAGK,KAAKpB,KAAKoC,OAAS,GAAK,IACrD,OAAOqV,IAAarW,KAAKpB,MAM3BwX,eAAgB,SAASvB,GACvB,OAAOyB,UAAUzB,EAASjM,QAAQ,OAAQ,WAK5CsN,UAAW,WACT,IAAIxH,EAAQ1O,KAAKyV,SAASc,KAAK3N,QAAQ,MAAO,IAAI8F,MAAM,QACxD,OAAOA,EAAQA,EAAM,GAAK,IAK5B8H,QAAS,SAAShB,GAChB,IAAI9G,GAAS8G,GAAUxV,MAAMyV,SAASc,KAAK7H,MAAM,UACjD,OAAOA,EAAQA,EAAM,GAAK,IAI5B+H,QAAS,WACP,IAAIT,EAAOhW,KAAKoW,eACdpW,KAAKyV,SAASQ,SAAWjW,KAAKkW,aAC9BvW,MAAMK,KAAKpB,KAAKoC,OAAS,GAC3B,OAAOgV,EAAKU,OAAO,KAAO,IAAMV,EAAKrW,MAAM,GAAKqW,GAIlDW,YAAa,SAAS9B,GACpB,GAAIA,GAAY,KAAM,CACpB,GAAI7U,KAAK4W,gBAAkB5W,KAAK6W,iBAAkB,CAChDhC,EAAW7U,KAAKyW,cACX,CACL5B,EAAW7U,KAAKwW,WAGpB,OAAO3B,EAASjM,QAAQ8M,EAAe,KAKzCoB,MAAO,SAASzU,GACd,GAAIiT,EAAQO,QAAS,MAAM,IAAI7J,MAAM,6CACrCsJ,EAAQO,QAAU,KAIlB7V,KAAKqC,QAAmBpD,EAAE4F,OAAO,CAACjG,KAAM,KAAMoB,KAAKqC,QAASA,GAC5DrC,KAAKpB,KAAmBoB,KAAKqC,QAAQzD,KACrCoB,KAAK6W,iBAAmB7W,KAAKqC,QAAQ0U,aAAe,MACpD/W,KAAKgX,eAAmB,iBAAkBxB,SAAWzG,SAASkI,oBAAsB,GAAKlI,SAASkI,aAAe,GACjHjX,KAAKkX,eAAmBlX,KAAK6W,kBAAoB7W,KAAKgX,eACtDhX,KAAKmX,kBAAqBnX,KAAKqC,QAAQ+U,UACvCpX,KAAKqX,iBAAsBrX,KAAK4U,SAAW5U,KAAK4U,QAAQwC,WACxDpX,KAAK4W,cAAmB5W,KAAKmX,iBAAmBnX,KAAKqX,cACrDrX,KAAK6U,SAAmB7U,KAAK2W,cAG7B3W,KAAKpB,MAAQ,IAAMoB,KAAKpB,KAAO,KAAKgK,QAAQ+M,EAAc,KAI1D,GAAI3V,KAAK6W,kBAAoB7W,KAAKmX,gBAAiB,CAIjD,IAAKnX,KAAKqX,gBAAkBrX,KAAK+V,SAAU,CACzC,IAAIM,EAAWrW,KAAKpB,KAAKe,MAAM,GAAI,IAAM,IACzCK,KAAKyV,SAAS7M,QAAQyN,EAAW,IAAMrW,KAAKyW,WAE5C,OAAO,UAIF,GAAIzW,KAAKqX,eAAiBrX,KAAK+V,SAAU,CAC9C/V,KAAKgV,SAAShV,KAAKwW,UAAW,CAAC5N,QAAS,QAQ5C,IAAK5I,KAAKgX,gBAAkBhX,KAAK6W,mBAAqB7W,KAAK4W,cAAe,CACxE5W,KAAKsX,OAASvI,SAASC,cAAc,UACrChP,KAAKsX,OAAOC,IAAM,eAClBvX,KAAKsX,OAAOE,MAAMC,QAAU,OAC5BzX,KAAKsX,OAAOI,UAAY,EACxB,IAAIC,EAAO5I,SAAS4I,KAEpB,IAAIC,EAAUD,EAAKE,aAAa7X,KAAKsX,OAAQK,EAAKG,YAAYC,cAC9DH,EAAQ7I,SAASiJ,OACjBJ,EAAQ7I,SAASkJ,QACjBL,EAAQnC,SAASyC,KAAO,IAAMlY,KAAK6U,SAIrC,IAAIsD,EAAmB3C,OAAO2C,kBAAoB,SAASvJ,EAAWjK,GACpE,OAAOyT,YAAY,KAAOxJ,EAAWjK,IAKvC,GAAI3E,KAAK4W,cAAe,CACtBuB,EAAiB,WAAYnY,KAAKuV,SAAU,YACvC,GAAIvV,KAAKkX,iBAAmBlX,KAAKsX,OAAQ,CAC9Ca,EAAiB,aAAcnY,KAAKuV,SAAU,YACzC,GAAIvV,KAAK6W,iBAAkB,CAChC7W,KAAKqY,kBAAoBC,YAAYtY,KAAKuV,SAAUvV,KAAK8V,UAG3D,IAAK9V,KAAKqC,QAAQoE,OAAQ,OAAOzG,KAAKuY,WAKxCC,KAAM,WAEJ,IAAIC,EAAsBjD,OAAOiD,qBAAuB,SAAS7J,EAAWjK,GAC1E,OAAO+T,YAAY,KAAO9J,EAAWjK,IAIvC,GAAI3E,KAAK4W,cAAe,CACtB6B,EAAoB,WAAYzY,KAAKuV,SAAU,YAC1C,GAAIvV,KAAKkX,iBAAmBlX,KAAKsX,OAAQ,CAC9CmB,EAAoB,aAAczY,KAAKuV,SAAU,OAInD,GAAIvV,KAAKsX,OAAQ,CACfvI,SAAS4I,KAAKgB,YAAY3Y,KAAKsX,QAC/BtX,KAAKsX,OAAS,KAIhB,GAAItX,KAAKqY,kBAAmBO,cAAc5Y,KAAKqY,mBAC/C/C,EAAQO,QAAU,OAKpBrB,MAAO,SAASA,EAAO9T,GACrBV,KAAKsC,SAASmJ,QAAQ,CAAC+I,MAAOA,EAAO9T,SAAUA,KAKjD6U,SAAU,SAASjW,GACjB,IAAIwH,EAAU9G,KAAK2W,cAInB,GAAI7P,IAAY9G,KAAK6U,UAAY7U,KAAKsX,OAAQ,CAC5CxQ,EAAU9G,KAAKwW,QAAQxW,KAAKsX,OAAOS,eAGrC,GAAIjR,IAAY9G,KAAK6U,SAAU,OAAO,MACtC,GAAI7U,KAAKsX,OAAQtX,KAAKgV,SAASlO,GAC/B9G,KAAKuY,WAMPA,QAAS,SAAS1D,GAEhB,IAAK7U,KAAKmW,YAAa,OAAO,MAC9BtB,EAAW7U,KAAK6U,SAAW7U,KAAK2W,YAAY9B,GAC5C,OAAO5V,EAAEkM,KAAKnL,KAAKsC,SAAU,SAASW,GACpC,GAAIA,EAAQuR,MAAMvT,KAAK4T,GAAW,CAChC5R,EAAQvC,SAASmU,GACjB,OAAO,SAYbG,SAAU,SAASH,EAAUxS,GAC3B,IAAKiT,EAAQO,QAAS,OAAO,MAC7B,IAAKxT,GAAWA,IAAY,KAAMA,EAAU,CAACsB,UAAWtB,GAGxDwS,EAAW7U,KAAK2W,YAAY9B,GAAY,IAGxC,IAAIwB,EAAWrW,KAAKpB,KACpB,GAAIiW,IAAa,IAAMA,EAAS6B,OAAO,KAAO,IAAK,CACjDL,EAAWA,EAAS1W,MAAM,GAAI,IAAM,IAEtC,IAAI8I,EAAM4N,EAAWxB,EAGrBA,EAAWA,EAASjM,QAAQgN,EAAc,IAG1C,IAAIiD,EAAkB7Y,KAAKoW,eAAevB,GAE1C,GAAI7U,KAAK6U,WAAagE,EAAiB,OACvC7Y,KAAK6U,SAAWgE,EAGhB,GAAI7Y,KAAK4W,cAAe,CACtB5W,KAAK4U,QAAQvS,EAAQuG,QAAU,eAAiB,aAAa,GAAImG,SAAS+J,MAAOrQ,QAI5E,GAAIzI,KAAK6W,iBAAkB,CAChC7W,KAAK+Y,YAAY/Y,KAAKyV,SAAUZ,EAAUxS,EAAQuG,SAClD,GAAI5I,KAAKsX,QAAUzC,IAAa7U,KAAKwW,QAAQxW,KAAKsX,OAAOS,eAAgB,CACvE,IAAIH,EAAU5X,KAAKsX,OAAOS,cAK1B,IAAK1V,EAAQuG,QAAS,CACpBgP,EAAQ7I,SAASiJ,OACjBJ,EAAQ7I,SAASkJ,QAGnBjY,KAAK+Y,YAAYnB,EAAQnC,SAAUZ,EAAUxS,EAAQuG,cAKlD,CACL,OAAO5I,KAAKyV,SAASuD,OAAOvQ,GAE9B,GAAIpG,EAAQsB,QAAS,OAAO3D,KAAKuY,QAAQ1D,IAK3CkE,YAAa,SAAStD,EAAUZ,EAAUjM,GACxC,GAAIA,EAAS,CACX,IAAI2N,EAAOd,EAASc,KAAK3N,QAAQ,qBAAsB,IACvD6M,EAAS7M,QAAQ2N,EAAO,IAAM1B,OACzB,CAELY,EAASyC,KAAO,IAAMrD,MAO5BzV,EAASwV,QAAU,IAAIU,EAQvB,IAAIzQ,EAAS,SAASoU,EAAYC,GAChC,IAAIC,EAASnZ,KACb,IAAIoZ,EAKJ,GAAIH,GAAcha,EAAEkH,IAAI8S,EAAY,eAAgB,CAClDG,EAAQH,EAAWnQ,gBACd,CACLsQ,EAAQ,WAAY,OAAOD,EAAO1V,MAAMzD,KAAM0D,YAIhDzE,EAAE4F,OAAOuU,EAAOD,EAAQD,GAIxBE,EAAMvZ,UAAYZ,EAAEmN,OAAO+M,EAAOtZ,UAAWoZ,GAC7CG,EAAMvZ,UAAUiJ,YAAcsQ,EAI9BA,EAAMC,UAAYF,EAAOtZ,UAEzB,OAAOuZ,GAITtU,EAAMD,OAASmE,EAAWnE,OAASoP,EAAOpP,OAAS4I,EAAK5I,OAASyQ,EAAQzQ,OAASA,EAGlF,IAAI8D,EAAW,WACb,MAAM,IAAIqD,MAAM,mDAIlB,IAAIjE,EAAY,SAASJ,EAAOtF,GAC9B,IAAIF,EAAQE,EAAQF,MACpBE,EAAQF,MAAQ,SAAS0F,GACvB,GAAI1F,EAAOA,EAAMuC,KAAKrC,EAAQvB,QAAS6G,EAAOE,EAAMxF,GACpDsF,EAAMhE,QAAQ,QAASgE,EAAOE,EAAMxF,KAIxC,OAAOjD"} \ No newline at end of file diff --git a/backbone.js b/backbone.js index 3e09d0dcb0..fd64012a35 100644 --- a/backbone.js +++ b/backbone.js @@ -1,6 +1,6 @@ -// Backbone.js 1.4.0 +// Backbone.js 1.4.1 -// (c) 2010-2019 Jeremy Ashkenas and DocumentCloud +// (c) 2010-2022 Jeremy Ashkenas and DocumentCloud // Backbone may be freely distributed under the MIT license. // For all details and documentation: // http://backbonejs.org @@ -44,7 +44,7 @@ var slice = Array.prototype.slice; // Current version of the library. Keep in sync with `package.json`. - Backbone.VERSION = '1.4.0'; + Backbone.VERSION = '1.4.1'; // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns // the `$` variable. @@ -516,7 +516,11 @@ } // Update the `id`. - if (this.idAttribute in attrs) this.id = this.get(this.idAttribute); + if (this.idAttribute in attrs) { + var prevId = this.id; + this.id = this.get(this.idAttribute); + this.trigger('changeId', this, prevId, options); + } // Trigger all relevant attribute changes. if (!silent) { @@ -994,7 +998,7 @@ get: function(obj) { if (obj == null) return void 0; return this._byId[obj] || - this._byId[this.modelId(this._isModel(obj) ? obj.attributes : obj)] || + this._byId[this.modelId(this._isModel(obj) ? obj.attributes : obj, obj.idAttribute)] || obj.cid && this._byId[obj.cid]; }, @@ -1098,8 +1102,8 @@ }, // Define how to uniquely identify models in the collection. - modelId: function(attrs) { - return attrs[this.model.prototype.idAttribute || 'id']; + modelId: function(attrs, idAttribute) { + return attrs[idAttribute || this.model.prototype.idAttribute || 'id']; }, // Get an iterator of all models in this collection. @@ -1134,7 +1138,15 @@ } options = options ? _.clone(options) : {}; options.collection = this; - var model = new this.model(attrs, options); + + var model; + if (this.model.prototype) { + model = new this.model(attrs, options); + } else { + // ES class methods didn't have prototype + model = this.model(attrs, options); + } + if (!model.validationError) return model; this.trigger('invalid', this, model.validationError, options); return false; @@ -1154,7 +1166,7 @@ // Remove references before triggering 'remove' event to prevent an // infinite loop. #3693 delete this._byId[model.cid]; - var id = this.modelId(model.attributes); + var id = this.modelId(model.attributes, model.idAttribute); if (id != null) delete this._byId[id]; if (!options.silent) { @@ -1177,7 +1189,7 @@ // Internal method to create a model's ties to a collection. _addReference: function(model, options) { this._byId[model.cid] = model; - var id = this.modelId(model.attributes); + var id = this.modelId(model.attributes, model.idAttribute); if (id != null) this._byId[id] = model; model.on('all', this._onModelEvent, this); }, @@ -1185,7 +1197,7 @@ // Internal method to sever a model's ties to a collection. _removeReference: function(model, options) { delete this._byId[model.cid]; - var id = this.modelId(model.attributes); + var id = this.modelId(model.attributes, model.idAttribute); if (id != null) delete this._byId[id]; if (this === model.collection) delete model.collection; model.off('all', this._onModelEvent, this); @@ -1199,13 +1211,11 @@ if (model) { if ((event === 'add' || event === 'remove') && collection !== this) return; if (event === 'destroy') this.remove(model, options); - if (event === 'change') { - var prevId = this.modelId(model.previousAttributes()); - var id = this.modelId(model.attributes); - if (prevId !== id) { - if (prevId != null) delete this._byId[prevId]; - if (id != null) this._byId[id] = model; - } + if (event === 'changeId') { + var prevId = this.modelId(model.previousAttributes(), model.idAttribute); + var id = this.modelId(model.attributes, model.idAttribute); + if (prevId != null) delete this._byId[prevId]; + if (id != null) this._byId[id] = model; } } this.trigger.apply(this, arguments); @@ -1261,7 +1271,7 @@ if (this._kind === ITERATOR_VALUES) { value = model; } else { - var id = this._collection.modelId(model.attributes); + var id = this._collection.modelId(model.attributes, model.idAttribute); if (this._kind === ITERATOR_KEYS) { value = id; } else { // ITERATOR_KEYSVALUES @@ -1615,11 +1625,11 @@ // Map from CRUD to HTTP for our default `Backbone.sync` implementation. var methodMap = { - create: 'POST', - update: 'PUT', - patch: 'PATCH', - delete: 'DELETE', - read: 'GET' + 'create': 'POST', + 'update': 'PUT', + 'patch': 'PATCH', + 'delete': 'DELETE', + 'read': 'GET' }; // Set the default implementation of `Backbone.ajax` to proxy through to `$`. @@ -1712,11 +1722,11 @@ // against the current location hash. _routeToRegExp: function(route) { route = route.replace(escapeRegExp, '\\$&') - .replace(optionalParam, '(?:$1)?') - .replace(namedParam, function(match, optional) { - return optional ? match : '([^/?]+)'; - }) - .replace(splatParam, '([^?]*?)'); + .replace(optionalParam, '(?:$1)?') + .replace(namedParam, function(match, optional) { + return optional ? match : '([^/?]+)'; + }) + .replace(splatParam, '([^?]*?)'); return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$'); }, diff --git a/docs/backbone.html b/docs/backbone.html index 818fb98440..2ea96f3081 100644 --- a/docs/backbone.html +++ b/docs/backbone.html @@ -24,11 +24,12 @@

backbone.js

  • -
    - +
    + §
    -
    Backbone.js 1.4.0
    +              
    Backbone.js 1.4.1
     
    +
  • @@ -37,18 +38,19 @@

    backbone.js

  • -
    - +
    + §
    -
    (c) 2010-2019 Jeremy Ashkenas and DocumentCloud
    -Backbone may be freely distributed under the MIT license.
    -For all details and documentation:
    -http://backbonejs.org
    +              
    (c) 2010-2022 Jeremy Ashkenas and DocumentCloud
    +Backbone may be freely distributed under the MIT license.
    +For all details and documentation:
    +http://backbonejs.org
     
    +
    -(function(factory) {
    +(function(factory) {
  • @@ -56,16 +58,16 @@

    backbone.js

  • -
    - +
    + §

    Establish the root object, window (self) in the browser, or global on the server. We use self instead of window for WebWorker support.

    -
      var root = typeof self == 'object' && self.self === self && self ||
    -            typeof global == 'object' && global.global === global && global;
    +
      var root = typeof self == 'object' && self.self === self && self ||
    +            typeof global == 'object' && global.global === global && global;
  • @@ -73,15 +75,15 @@

    backbone.js

  • -
    - +
    + §

    Set up Backbone appropriately for the environment. Start with AMD.

    -
      if (typeof define === 'function' && define.amd) {
    -    define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
    +
      if (typeof define === 'function' && define.amd) {
    +    define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
  • @@ -89,15 +91,15 @@

    backbone.js

  • -
    - +
    + §

    Export global even in AMD case in case this script is loaded with others that may still expect a global Backbone.

    -
          root.Backbone = factory(root, exports, _, $);
    +            
          root.Backbone = factory(root, exports, _, $);
         });
  • @@ -106,17 +108,17 @@

    backbone.js

  • -
    - +
    + §

    Next for Node.js or CommonJS. jQuery may not be needed as a module.

    -
      } else if (typeof exports !== 'undefined') {
    -    var _ = require('underscore'), $;
    -    try { $ = require('jquery'); } catch (e) {}
    -    factory(root, exports, _, $);
    +
      } else if (typeof exports !== 'undefined') {
    +    var _ = require('underscore'), $;
    +    try { $ = require('jquery'); } catch (e) {}
    +    factory(root, exports, _, $);
  • @@ -124,18 +126,18 @@

    backbone.js

  • -
    - +
    + §

    Finally, as a browser global.

      } else {
    -    root.Backbone = factory(root, {}, root._, root.jQuery || root.Zepto || root.ender || root.$);
    +    root.Backbone = factory(root, {}, root._, root.jQuery || root.Zepto || root.ender || root.$);
       }
     
    -})(function(root, Backbone, _, $) {
    +})(function(root, Backbone, _, $) {
  • @@ -143,8 +145,8 @@

    backbone.js

  • -
    - +
    + §

    Initial Setup

    @@ -156,8 +158,8 @@

    Initial Setup

  • -
    - +
    + §
    @@ -168,15 +170,15 @@

    Initial Setup

  • -
    - +
    + §

    Save the previous value of the Backbone variable, so that it can be restored later on, if noConflict is used.

    -
      var previousBackbone = root.Backbone;
    +
      var previousBackbone = root.Backbone;
  • @@ -184,14 +186,14 @@

    Initial Setup

  • -
    - +
    + §

    Create a local reference to a common array method we’ll want to use later.

    -
      var slice = Array.prototype.slice;
    +
      var slice = Array.prototype.slice;
  • @@ -199,14 +201,14 @@

    Initial Setup

  • -
    - +
    + §

    Current version of the library. Keep in sync with package.json.

    -
      Backbone.VERSION = '1.4.0';
    +
      Backbone.VERSION = '1.4.1';
  • @@ -214,15 +216,15 @@

    Initial Setup

  • -
    - +
    + §

    For Backbone’s purposes, jQuery, Zepto, Ender, or My Library (kidding) owns the $ variable.

    -
      Backbone.$ = $;
    +
      Backbone.$ = $;
  • @@ -230,17 +232,17 @@

    Initial Setup

  • -
    - +
    + §

    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;
    +            
      Backbone.noConflict = function() {
    +    root.Backbone = previousBackbone;
    +    return this;
       };
  • @@ -249,8 +251,8 @@

    Initial Setup

  • -
    - +
    + §

    Turn on emulateHTTP to support legacy HTTP servers. Setting this option will fake "PATCH", "PUT" and "DELETE" requests via the _method parameter and @@ -258,7 +260,7 @@

    Initial Setup

    -
      Backbone.emulateHTTP = false;
    +
      Backbone.emulateHTTP = false;
  • @@ -266,8 +268,8 @@

    Initial Setup

  • -
    - +
    + §

    Turn on emulateJSON to support legacy servers that can’t deal with direct application/json requests … this will encode the body as @@ -276,7 +278,7 @@

    Initial Setup

    -
      Backbone.emulateJSON = false;
    +
      Backbone.emulateJSON = false;
  • @@ -284,10 +286,10 @@

    Initial Setup

  • -
    - +
    + §
    -

    Backbone.Events

    +

    Backbone.Events

    @@ -297,8 +299,8 @@

    Backbone.Events

  • -
    - +
    + §
    @@ -309,21 +311,22 @@

    Backbone.Events

  • -
    - +
    + §

    A module that can be mixed in to any object in order to provide it with a custom event channel. You may bind a callback to an event with on or remove with off; trigger-ing an event fires all callbacks in succession.

    var object = {};
    -_.extend(object, Backbone.Events);
    -object.on('expand', function(){ alert('expanded'); });
    -object.trigger('expand');
    +_.extend(object, Backbone.Events);
    +object.on('expand', function(){ alert('expanded'); });
    +object.trigger('expand');
     
    +
    -
      var Events = Backbone.Events = {};
    +
      var Events = Backbone.Events = {};
  • @@ -331,8 +334,8 @@

    Backbone.Events

  • -
    - +
    + §

    Regular expression used to split event strings.

    @@ -346,8 +349,8 @@

    Backbone.Events

  • -
    - +
    + §

    A private global variable to share between listeners and listenees.

    @@ -361,8 +364,8 @@

    Backbone.Events

  • -
    - +
    + §

    Iterates over the standard event, callback (as well as the fancy multiple space-separated events "change blur", callback and jQuery-style event @@ -370,9 +373,9 @@

    Backbone.Events

    -
      var eventsApi = function(iteratee, events, name, callback, opts) {
    +            
      var eventsApi = function(iteratee, events, name, callback, opts) {
         var i = 0, names;
    -    if (name && typeof name === 'object') {
    + if (name && typeof name === 'object') {
  • @@ -380,18 +383,18 @@

    Backbone.Events

  • -
    - +
    + §

    Handle event maps.

    -
          if (callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback;
    -      for (names = _.keys(name); i < names.length ; i++) {
    -        events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
    +            
          if (callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback;
    +      for (names = _.keys(name); i < names.length ; i++) {
    +        events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
           }
    -    } else if (name && eventSplitter.test(name)) {
    + } else if (name && eventSplitter.test(name)) {
  • @@ -399,15 +402,15 @@

    Backbone.Events

  • -
    - +
    + §

    Handle space-separated event names by delegating them individually.

    -
          for (names = name.split(eventSplitter); i < names.length; i++) {
    -        events = iteratee(events, names[i], callback, opts);
    +            
          for (names = name.split(eventSplitter); i < names.length; i++) {
    +        events = iteratee(events, names[i], callback, opts);
           }
         } else {
    @@ -417,14 +420,14 @@

    Backbone.Events

  • -
    - +
    + §

    Finally, standard events.

    -
          events = iteratee(events, name, callback, opts);
    +            
          events = iteratee(events, name, callback, opts);
         }
         return events;
       };
    @@ -435,24 +438,24 @@

    Backbone.Events

  • -
    - +
    + §

    Bind an event to a callback function. Passing "all" will bind the callback to all events fired.

    -
      Events.on = function(name, callback, context) {
    -    this._events = eventsApi(onApi, this._events || {}, name, callback, {
    -      context: context,
    -      ctx: this,
    -      listening: _listening
    +            
      Events.on = function(name, callback, context) {
    +    this._events = eventsApi(onApi, this._events || {}, name, callback, {
    +      context: context,
    +      ctx: this,
    +      listening: _listening
         });
     
         if (_listening) {
    -      var listeners = this._listeners || (this._listeners = {});
    -      listeners[_listening.id] = _listening;
    + var listeners = this._listeners || (this._listeners = {}); + listeners[_listening.id] = _listening;
  • @@ -460,18 +463,18 @@

    Backbone.Events

  • -
    - +
    + §

    Allow the listening to use a counter, instead of tracking callbacks for library interop

    -
          _listening.interop = false;
    +            
          _listening.interop = false;
         }
     
    -    return this;
    +    return this;
       };
  • @@ -480,8 +483,8 @@

    Backbone.Events

  • -
    - +
    + §

    Inversion-of-control versions of on. Tell this object to listen to an event in another object… keeping track of what it’s listening to @@ -489,10 +492,10 @@

    Backbone.Events

    -
      Events.listenTo = function(obj, name, callback) {
    -    if (!obj) return this;
    -    var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
    -    var listeningTo = this._listeningTo || (this._listeningTo = {});
    +            
      Events.listenTo = function(obj, name, callback) {
    +    if (!obj) return this;
    +    var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
    +    var listeningTo = this._listeningTo || (this._listeningTo = {});
         var listening = _listening = listeningTo[id];
  • @@ -501,8 +504,8 @@

    Backbone.Events

  • -
    - +
    + §

    This object is not listening to any other events on obj yet. Setup the necessary references to track the listening callbacks.

    @@ -510,8 +513,8 @@

    Backbone.Events

        if (!listening) {
    -      this._listenId || (this._listenId = _.uniqueId('l'));
    -      listening = _listening = listeningTo[id] = new Listening(this, obj);
    +      this._listenId || (this._listenId = _.uniqueId('l'));
    +      listening = _listening = listeningTo[id] = new Listening(this, obj);
         }
  • @@ -520,14 +523,14 @@

    Backbone.Events

  • -
    - +
    + §

    Bind callbacks on obj.

    -
        var error = tryCatchOn(obj, name, callback, this);
    +            
        var error = tryCatchOn(obj, name, callback, this);
         _listening = void 0;
     
         if (error) throw error;
    @@ -538,16 +541,16 @@

    Backbone.Events

  • -
    - +
    + §

    If the target obj is not Backbone.Events, track events manually.

    -
        if (listening.interop) listening.on(name, callback);
    +            
        if (listening.interop) listening.on(name, callback);
     
    -    return this;
    +    return this;
       };
  • @@ -556,20 +559,20 @@

    Backbone.Events

  • -
    - +
    + §

    The reducing API that adds a callback to the events object.

    -
      var onApi = function(events, name, callback, options) {
    +            
      var onApi = function(events, name, callback, options) {
         if (callback) {
           var handlers = events[name] || (events[name] = []);
    -      var context = options.context, ctx = options.ctx, listening = options.listening;
    -      if (listening) listening.count++;
    +      var context = options.context, ctx = options.ctx, listening = options.listening;
    +      if (listening) listening.count++;
     
    -      handlers.push({callback: callback, context: context, ctx: context || ctx, listening: listening});
    +      handlers.push({callback: callback, context: context, ctx: context || ctx, listening: listening});
         }
         return events;
       };
    @@ -580,17 +583,17 @@

    Backbone.Events

  • -
    - +
    + §

    An try-catch guarded #on function, to prevent poisoning the global _listening variable.

    -
      var tryCatchOn = function(obj, name, callback, context) {
    +            
      var tryCatchOn = function(obj, name, callback, context) {
         try {
    -      obj.on(name, callback, context);
    +      obj.on(name, callback, context);
         } catch (e) {
           return e;
         }
    @@ -602,8 +605,8 @@ 

    Backbone.Events

  • -
    - +
    + §

    Remove one or many callbacks. If context is null, removes all callbacks with that function. If callback is null, removes all @@ -612,14 +615,14 @@

    Backbone.Events

    -
      Events.off = function(name, callback, context) {
    -    if (!this._events) return this;
    -    this._events = eventsApi(offApi, this._events, name, callback, {
    -      context: context,
    -      listeners: this._listeners
    +            
      Events.off = function(name, callback, context) {
    +    if (!this._events) return this;
    +    this._events = eventsApi(offApi, this._events, name, callback, {
    +      context: context,
    +      listeners: this._listeners
         });
     
    -    return this;
    +    return this;
       };
  • @@ -628,20 +631,20 @@

    Backbone.Events

  • -
    - +
    + §

    Tell this object to stop listening to either specific events … or to every object it’s currently listening to.

    -
      Events.stopListening = function(obj, name, callback) {
    -    var listeningTo = this._listeningTo;
    -    if (!listeningTo) return this;
    +            
      Events.stopListening = function(obj, name, callback) {
    +    var listeningTo = this._listeningTo;
    +    if (!listeningTo) return this;
     
    -    var ids = obj ? [obj._listenId] : _.keys(listeningTo);
    -    for (var i = 0; i < ids.length; i++) {
    +    var ids = obj ? [obj._listenId] : _.keys(listeningTo);
    +    for (var i = 0; i < ids.length; i++) {
           var listening = listeningTo[ids[i]];
  • @@ -650,8 +653,8 @@

    Backbone.Events

  • -
    - +
    + §

    If listening doesn’t exist, this object is not currently listening to obj. Break out early.

    @@ -660,12 +663,12 @@

    Backbone.Events

          if (!listening) break;
     
    -      listening.obj.off(name, callback, this);
    -      if (listening.interop) listening.off(name, callback);
    +      listening.obj.off(name, callback, this);
    +      if (listening.interop) listening.off(name, callback);
         }
    -    if (_.isEmpty(listeningTo)) this._listeningTo = void 0;
    +    if (_.isEmpty(listeningTo)) this._listeningTo = void 0;
     
    -    return this;
    +    return this;
       };
  • @@ -674,17 +677,17 @@

    Backbone.Events

  • -
    - +
    + §

    The reducing API that removes a callback from the events object.

    -
      var offApi = function(events, name, callback, options) {
    +            
      var offApi = function(events, name, callback, options) {
         if (!events) return;
     
    -    var context = options.context, listeners = options.listeners;
    +    var context = options.context, listeners = options.listeners;
         var i = 0, names;
  • @@ -693,22 +696,22 @@

    Backbone.Events

  • -
    - +
    + §

    Delete all event listeners and “drop” events.

        if (!name && !context && !callback) {
    -      for (names = _.keys(listeners); i < names.length; i++) {
    -        listeners[names[i]].cleanup();
    +      for (names = _.keys(listeners); i < names.length; i++) {
    +        listeners[names[i]].cleanup();
           }
           return;
         }
     
    -    names = name ? [name] : _.keys(events);
    -    for (; i < names.length; i++) {
    +    names = name ? [name] : _.keys(events);
    +    for (; i < names.length; i++) {
           name = names[i];
           var handlers = events[name];
    @@ -718,8 +721,8 @@

    Backbone.Events

  • -
    - +
    + §

    Bail out if there are no events stored.

    @@ -733,25 +736,25 @@

    Backbone.Events

  • -
    - +
    + §

    Find any remaining events.

          var remaining = [];
    -      for (var j = 0; j < handlers.length; j++) {
    +      for (var j = 0; j < handlers.length; j++) {
             var handler = handlers[j];
             if (
    -          callback && callback !== handler.callback &&
    -            callback !== handler.callback._callback ||
    -              context && context !== handler.context
    +          callback && callback !== handler.callback &&
    +            callback !== handler.callback._callback ||
    +              context && context !== handler.context
             ) {
    -          remaining.push(handler);
    +          remaining.push(handler);
             } else {
    -          var listening = handler.listening;
    -          if (listening) listening.off(name, callback);
    +          var listening = handler.listening;
    +          if (listening) listening.off(name, callback);
             }
           }
    @@ -761,14 +764,14 @@

    Backbone.Events

  • -
    - +
    + §

    Replace events if there are any remaining. Otherwise, clean up.

    -
          if (remaining.length) {
    +            
          if (remaining.length) {
             events[name] = remaining;
           } else {
             delete events[name];
    @@ -784,8 +787,8 @@ 

    Backbone.Events

  • -
    - +
    + §

    Bind an event to only be triggered a single time. After the first time the callback is invoked, its listener will be removed. If multiple events @@ -794,7 +797,7 @@

    Backbone.Events

    -
      Events.once = function(name, callback, context) {
    +
      Events.once = function(name, callback, context) {
  • @@ -802,16 +805,16 @@

    Backbone.Events

  • -
    - +
    + §

    Map the event into a {event: once} object.

    -
        var events = eventsApi(onceMap, {}, name, callback, this.off.bind(this));
    -    if (typeof name === 'string' && context == null) callback = void 0;
    -    return this.on(events, callback, context);
    +            
        var events = eventsApi(onceMap, {}, name, callback, this.off.bind(this));
    +    if (typeof name === 'string' && context == null) callback = void 0;
    +    return this.on(events, callback, context);
       };
  • @@ -820,14 +823,14 @@

    Backbone.Events

  • -
    - +
    + §

    Inversion-of-control versions of once.

    -
      Events.listenToOnce = function(obj, name, callback) {
    +
      Events.listenToOnce = function(obj, name, callback) {
  • @@ -835,15 +838,15 @@

    Backbone.Events

  • -
    - +
    + §

    Map the event into a {event: once} object.

    -
        var events = eventsApi(onceMap, {}, name, callback, this.stopListening.bind(this, obj));
    -    return this.listenTo(obj, events);
    +            
        var events = eventsApi(onceMap, {}, name, callback, this.stopListening.bind(this, obj));
    +    return this.listenTo(obj, events);
       };
  • @@ -852,21 +855,21 @@

    Backbone.Events

  • -
    - +
    + §

    Reduces the event callbacks into a map of {event: onceWrapper}. offer unbinds the onceWrapper after it has been called.

    -
      var onceMap = function(map, name, callback, offer) {
    +            
      var onceMap = function(map, name, callback, offer) {
         if (callback) {
    -      var once = map[name] = _.once(function() {
    -        offer(name, once);
    -        callback.apply(this, arguments);
    +      var once = map[name] = _.once(function() {
    +        offer(name, once);
    +        callback.apply(this, arguments);
           });
    -      once._callback = callback;
    +      once._callback = callback;
         }
         return map;
       };
    @@ -877,8 +880,8 @@

    Backbone.Events

  • -
    - +
    + §

    Trigger one or many events, firing all bound callbacks. Callbacks are passed the same arguments as trigger is, apart from the event name @@ -887,15 +890,15 @@

    Backbone.Events

    -
      Events.trigger = function(name) {
    -    if (!this._events) return this;
    +            
      Events.trigger = function(name) {
    +    if (!this._events) return this;
     
    -    var length = Math.max(0, arguments.length - 1);
    -    var args = Array(length);
    -    for (var i = 0; i < length; i++) args[i] = arguments[i + 1];
    +    var length = Math.max(0, arguments.length - 1);
    +    var args = Array(length);
    +    for (var i = 0; i < length; i++) args[i] = arguments[i + 1];
     
    -    eventsApi(triggerApi, this._events, name, void 0, args);
    -    return this;
    +    eventsApi(triggerApi, this._events, name, void 0, args);
    +    return this;
       };
  • @@ -904,20 +907,20 @@

    Backbone.Events

  • -
    - +
    + §

    Handles triggering the appropriate event callbacks.

    -
      var triggerApi = function(objEvents, name, callback, args) {
    +            
      var triggerApi = function(objEvents, name, callback, args) {
         if (objEvents) {
           var events = objEvents[name];
    -      var allEvents = objEvents.all;
    -      if (events && allEvents) allEvents = allEvents.slice();
    -      if (events) triggerEvents(events, args);
    -      if (allEvents) triggerEvents(allEvents, [name].concat(args));
    +      var allEvents = objEvents.all;
    +      if (events && allEvents) allEvents = allEvents.slice();
    +      if (events) triggerEvents(events, args);
    +      if (allEvents) triggerEvents(allEvents, [name].concat(args));
         }
         return objEvents;
       };
    @@ -928,8 +931,8 @@

    Backbone.Events

  • -
    - +
    + §

    A difficult-to-believe, but optimized internal dispatch function for triggering events. Tries to keep the usual cases speedy (most internal @@ -937,14 +940,14 @@

    Backbone.Events

    -
      var triggerEvents = function(events, args) {
    -    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
    -    switch (args.length) {
    -      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
    -      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
    -      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
    -      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
    -      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
    +            
      var triggerEvents = function(events, args) {
    +    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
    +    switch (args.length) {
    +      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
    +      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
    +      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
    +      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
    +      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
         }
       };
    @@ -954,24 +957,24 @@

    Backbone.Events

  • -
    - +
    + §

    A listening class that tracks and cleans up memory bindings when all callbacks have been offed.

    -
      var Listening = function(listener, obj) {
    -    this.id = listener._listenId;
    -    this.listener = listener;
    -    this.obj = obj;
    -    this.interop = true;
    -    this.count = 0;
    -    this._events = void 0;
    +            
      var Listening = function(listener, obj) {
    +    this.id = listener._listenId;
    +    this.listener = listener;
    +    this.obj = obj;
    +    this.interop = true;
    +    this.count = 0;
    +    this._events = void 0;
       };
     
    -  Listening.prototype.on = Events.on;
    + Listening.prototype.on = Events.on;
  • @@ -979,8 +982,8 @@

    Backbone.Events

  • -
    - +
    + §

    Offs a callback (or several). Uses an optimized counter if the listenee uses Backbone.Events. @@ -989,19 +992,19 @@

    Backbone.Events

    -
      Listening.prototype.off = function(name, callback) {
    +            
      Listening.prototype.off = function(name, callback) {
         var cleanup;
    -    if (this.interop) {
    -      this._events = eventsApi(offApi, this._events, name, callback, {
    -        context: void 0,
    -        listeners: void 0
    +    if (this.interop) {
    +      this._events = eventsApi(offApi, this._events, name, callback, {
    +        context: void 0,
    +        listeners: void 0
           });
    -      cleanup = !this._events;
    +      cleanup = !this._events;
         } else {
    -      this.count--;
    -      cleanup = this.count === 0;
    +      this.count--;
    +      cleanup = this.count === 0;
         }
    -    if (cleanup) this.cleanup();
    +    if (cleanup) this.cleanup();
       };
  • @@ -1010,16 +1013,16 @@

    Backbone.Events

  • -
    - +
    + §

    Cleans up memory bindings between the listener and the listenee.

    -
      Listening.prototype.cleanup = function() {
    -    delete this.listener._listeningTo[this.obj._listenId];
    -    if (!this.interop) delete this.obj._listeners[this.id];
    +            
      Listening.prototype.cleanup = function() {
    +    delete this.listener._listeningTo[this.obj._listenId];
    +    if (!this.interop) delete this.obj._listeners[this.id];
       };
  • @@ -1028,15 +1031,15 @@

    Backbone.Events

  • -
    - +
    + §

    Aliases for backwards compatibility.

    -
      Events.bind   = Events.on;
    -  Events.unbind = Events.off;
    +
      Events.bind   = Events.on;
    +  Events.unbind = Events.off;
  • @@ -1044,15 +1047,15 @@

    Backbone.Events

  • -
    - +
    + §

    Allow the Backbone object to serve as a global event bus, for folks who want global “pubsub” in a convenient place.

    -
      _.extend(Backbone, Events);
    +
      _.extend(Backbone, Events);
  • @@ -1060,10 +1063,10 @@

    Backbone.Events

  • -
    - +
    + §
    -

    Backbone.Model

    +

    Backbone.Model

    @@ -1073,8 +1076,8 @@

    Backbone.Model

  • -
    - +
    + §
    @@ -1085,8 +1088,8 @@

    Backbone.Model

  • -
    - +
    + §

    Backbone Models are the basic data object in the framework – frequently representing a row in a table in a database on your server. @@ -1101,27 +1104,27 @@

    Backbone.Model

  • -
    - +
    + §

    Create a new model with the specified attributes. A client id (cid) is automatically generated and assigned for you.

    -
      var Model = Backbone.Model = function(attributes, options) {
    +            
      var Model = Backbone.Model = function(attributes, options) {
         var attrs = attributes || {};
         options || (options = {});
    -    this.preinitialize.apply(this, arguments);
    -    this.cid = _.uniqueId(this.cidPrefix);
    -    this.attributes = {};
    -    if (options.collection) this.collection = options.collection;
    -    if (options.parse) attrs = this.parse(attrs, options) || {};
    -    var defaults = _.result(this, 'defaults');
    -    attrs = _.defaults(_.extend({}, defaults, attrs), defaults);
    -    this.set(attrs, options);
    -    this.changed = {};
    -    this.initialize.apply(this, arguments);
    +    this.preinitialize.apply(this, arguments);
    +    this.cid = _.uniqueId(this.cidPrefix);
    +    this.attributes = {};
    +    if (options.collection) this.collection = options.collection;
    +    if (options.parse) attrs = this.parse(attrs, options) || {};
    +    var defaults = _.result(this, 'defaults');
    +    attrs = _.defaults(_.extend({}, defaults, attrs), defaults);
    +    this.set(attrs, options);
    +    this.changed = {};
    +    this.initialize.apply(this, arguments);
       };
  • @@ -1130,14 +1133,14 @@

    Backbone.Model

  • -
    - +
    + §

    Attach all inheritable methods to the Model prototype.

    -
      _.extend(Model.prototype, Events, {
    +
      _.extend(Model.prototype, Events, {
  • @@ -1145,14 +1148,14 @@

    Backbone.Model

  • -
    - +
    + §

    A hash of attributes whose current and previous value differ.

    -
        changed: null,
    +
        changed: null,
  • @@ -1160,14 +1163,14 @@

    Backbone.Model

  • -
    - +
    + §

    The value returned during the last failed validation.

    -
        validationError: null,
    +
        validationError: null,
  • @@ -1175,15 +1178,15 @@

    Backbone.Model

  • -
    - +
    + §

    The default name for the JSON id attribute is "id". MongoDB and CouchDB users may want to set this to "_id".

    -
        idAttribute: 'id',
    +
        idAttribute: 'id',
  • @@ -1191,15 +1194,15 @@

    Backbone.Model

  • -
    - +
    + §

    The prefix is used to create the client id which is used to identify models locally. You may want to override this if you’re experiencing name clashes with model ids.

    -
        cidPrefix: 'c',
    +
        cidPrefix: 'c',
  • @@ -1207,15 +1210,15 @@

    Backbone.Model

  • -
    - +
    + §

    preinitialize is an empty function by default. You can override it with a function or object. preinitialize will run before any instantiation logic is run in the Model.

    -
        preinitialize: function(){},
    +
        preinitialize: function(){},
  • @@ -1223,15 +1226,15 @@

    Backbone.Model

  • -
    - +
    + §

    Initialize is an empty function by default. Override it with your own initialization logic.

    -
        initialize: function(){},
    +
        initialize: function(){},
  • @@ -1239,15 +1242,15 @@

    Backbone.Model

  • -
    - +
    + §

    Return a copy of the model’s attributes object.

    -
        toJSON: function(options) {
    -      return _.clone(this.attributes);
    +            
        toJSON: function(options) {
    +      return _.clone(this.attributes);
         },
  • @@ -1256,16 +1259,16 @@

    Backbone.Model

  • -
    - +
    + §

    Proxy Backbone.sync by default – but override this if you need custom syncing semantics for this particular model.

    -
        sync: function() {
    -      return Backbone.sync.apply(this, arguments);
    +            
        sync: function() {
    +      return Backbone.sync.apply(this, arguments);
         },
  • @@ -1274,15 +1277,15 @@

    Backbone.Model

  • -
    - +
    + §

    Get the value of an attribute.

    -
        get: function(attr) {
    -      return this.attributes[attr];
    +            
        get: function(attr) {
    +      return this.attributes[attr];
         },
  • @@ -1291,15 +1294,15 @@

    Backbone.Model

  • -
    - +
    + §

    Get the HTML-escaped value of an attribute.

    -
        escape: function(attr) {
    -      return _.escape(this.get(attr));
    +            
        escape: function(attr) {
    +      return _.escape(this.get(attr));
         },
  • @@ -1308,16 +1311,16 @@

    Backbone.Model

  • -
    - +
    + §

    Returns true if the attribute contains a value that is not null or undefined.

    -
        has: function(attr) {
    -      return this.get(attr) != null;
    +            
        has: function(attr) {
    +      return this.get(attr) != null;
         },
  • @@ -1326,15 +1329,15 @@

    Backbone.Model

  • -
    - +
    + §

    Special-cased proxy to underscore’s _.matches method.

    -
        matches: function(attrs) {
    -      return !!_.iteratee(attrs, this)(this.attributes);
    +            
        matches: function(attrs) {
    +      return !!_.iteratee(attrs, this)(this.attributes);
         },
  • @@ -1343,8 +1346,8 @@

    Backbone.Model

  • -
    - +
    + §

    Set a hash of model attributes on the object, firing "change". This is the core primitive operation of a model, updating the data and notifying @@ -1352,8 +1355,8 @@

    Backbone.Model

    -
        set: function(key, val, options) {
    -      if (key == null) return this;
    +
        set: function(key, val, options) {
    +      if (key == null) return this;
  • @@ -1361,15 +1364,15 @@

    Backbone.Model

  • -
    - +
    + §

    Handle both "key", value and {key: value} -style arguments.

          var attrs;
    -      if (typeof key === 'object') {
    +      if (typeof key === 'object') {
             attrs = key;
             options = val;
           } else {
    @@ -1384,14 +1387,14 @@ 

    Backbone.Model

  • -
    - +
    + §

    Run validation.

    -
          if (!this._validate(attrs, options)) return false;
    +
          if (!this._validate(attrs, options)) return false;
  • @@ -1399,27 +1402,27 @@

    Backbone.Model

  • -
    - +
    + §

    Extract attributes and options.

    -
          var unset      = options.unset;
    -      var silent     = options.silent;
    +            
          var unset      = options.unset;
    +      var silent     = options.silent;
           var changes    = [];
    -      var changing   = this._changing;
    -      this._changing = true;
    +      var changing   = this._changing;
    +      this._changing = true;
     
           if (!changing) {
    -        this._previousAttributes = _.clone(this.attributes);
    -        this.changed = {};
    +        this._previousAttributes = _.clone(this.attributes);
    +        this.changed = {};
           }
     
    -      var current = this.attributes;
    -      var changed = this.changed;
    -      var prev    = this._previousAttributes;
    + var current = this.attributes; + var changed = this.changed; + var prev = this._previousAttributes;
  • @@ -1427,8 +1430,8 @@

    Backbone.Model

  • -
    - +
    + §

    For each set attribute, update or delete the current value.

    @@ -1436,8 +1439,8 @@

    Backbone.Model

          for (var attr in attrs) {
             val = attrs[attr];
    -        if (!_.isEqual(current[attr], val)) changes.push(attr);
    -        if (!_.isEqual(prev[attr], val)) {
    +        if (!_.isEqual(current[attr], val)) changes.push(attr);
    +        if (!_.isEqual(prev[attr], val)) {
               changed[attr] = val;
             } else {
               delete changed[attr];
    @@ -1451,14 +1454,18 @@ 

    Backbone.Model

  • -
    - +
    + §

    Update the id.

    -
          if (this.idAttribute in attrs) this.id = this.get(this.idAttribute);
    +
          if (this.idAttribute in attrs) {
    +        var prevId = this.id;
    +        this.id = this.get(this.idAttribute);
    +        this.trigger('changeId', this, prevId, options);
    +      }
  • @@ -1466,17 +1473,17 @@

    Backbone.Model

  • -
    - +
    + §

    Trigger all relevant attribute changes.

          if (!silent) {
    -        if (changes.length) this._pending = options;
    -        for (var i = 0; i < changes.length; i++) {
    -          this.trigger('change:' + changes[i], this, current[changes[i]], options);
    +        if (changes.length) this._pending = options;
    +        for (var i = 0; i < changes.length; i++) {
    +          this.trigger('change:' + changes[i], this, current[changes[i]], options);
             }
           }
    @@ -1486,25 +1493,25 @@

    Backbone.Model

  • -
    - +
    + §

    You might be wondering why there’s a while loop here. Changes can be recursively nested within "change" events.

    -
          if (changing) return this;
    +            
          if (changing) return this;
           if (!silent) {
    -        while (this._pending) {
    -          options = this._pending;
    -          this._pending = false;
    -          this.trigger('change', this, options);
    +        while (this._pending) {
    +          options = this._pending;
    +          this._pending = false;
    +          this.trigger('change', this, options);
             }
           }
    -      this._pending = false;
    -      this._changing = false;
    -      return this;
    +      this._pending = false;
    +      this._changing = false;
    +      return this;
         },
  • @@ -1513,16 +1520,16 @@

    Backbone.Model

  • -
    - +
    + §

    Remove an attribute from the model, firing "change". unset is a noop if the attribute doesn’t exist.

    -
        unset: function(attr, options) {
    -      return this.set(attr, void 0, _.extend({}, options, {unset: true}));
    +            
        unset: function(attr, options) {
    +      return this.set(attr, void 0, _.extend({}, options, {unset: true}));
         },
  • @@ -1531,17 +1538,17 @@

    Backbone.Model

  • -
    - +
    + §

    Clear all attributes on the model, firing "change".

    -
        clear: function(options) {
    +            
        clear: function(options) {
           var attrs = {};
    -      for (var key in this.attributes) attrs[key] = void 0;
    -      return this.set(attrs, _.extend({}, options, {unset: true}));
    +      for (var key in this.attributes) attrs[key] = void 0;
    +      return this.set(attrs, _.extend({}, options, {unset: true}));
         },
  • @@ -1550,17 +1557,17 @@

    Backbone.Model

  • -
    - +
    + §

    Determine if the model has changed since the last "change" event. If you specify an attribute name, determine if that attribute has changed.

    -
        hasChanged: function(attr) {
    -      if (attr == null) return !_.isEmpty(this.changed);
    -      return _.has(this.changed, attr);
    +            
        hasChanged: function(attr) {
    +      if (attr == null) return !_.isEmpty(this.changed);
    +      return _.has(this.changed, attr);
         },
  • @@ -1569,8 +1576,8 @@

    Backbone.Model

  • -
    - +
    + §

    Return an object containing all the attributes that have changed, or false if there are no changed attributes. Useful for determining what @@ -1581,14 +1588,14 @@

    Backbone.Model

    -
        changedAttributes: function(diff) {
    -      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
    -      var old = this._changing ? this._previousAttributes : this.attributes;
    +            
        changedAttributes: function(diff) {
    +      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
    +      var old = this._changing ? this._previousAttributes : this.attributes;
           var changed = {};
           var hasChanged;
           for (var attr in diff) {
             var val = diff[attr];
    -        if (_.isEqual(old[attr], val)) continue;
    +        if (_.isEqual(old[attr], val)) continue;
             changed[attr] = val;
             hasChanged = true;
           }
    @@ -1601,17 +1608,17 @@ 

    Backbone.Model

  • -
    - +
    + §

    Get the previous value of an attribute, recorded at the time the last "change" event was fired.

    -
        previous: function(attr) {
    -      if (attr == null || !this._previousAttributes) return null;
    -      return this._previousAttributes[attr];
    +            
        previous: function(attr) {
    +      if (attr == null || !this._previousAttributes) return null;
    +      return this._previousAttributes[attr];
         },
  • @@ -1620,16 +1627,16 @@

    Backbone.Model

  • -
    - +
    + §

    Get all of the attributes of the model at the time of the previous "change" event.

    -
        previousAttributes: function() {
    -      return _.clone(this._previousAttributes);
    +            
        previousAttributes: function() {
    +      return _.clone(this._previousAttributes);
         },
  • @@ -1638,26 +1645,26 @@

    Backbone.Model

  • -
    - +
    + §

    Fetch the model from the server, merging the response with the model’s local attributes. Any changed attributes will trigger a “change” event.

    -
        fetch: function(options) {
    -      options = _.extend({parse: true}, options);
    -      var model = this;
    -      var success = options.success;
    -      options.success = function(resp) {
    -        var serverAttrs = options.parse ? model.parse(resp, options) : resp;
    -        if (!model.set(serverAttrs, options)) return false;
    -        if (success) success.call(options.context, model, resp, options);
    -        model.trigger('sync', model, resp, options);
    +            
        fetch: function(options) {
    +      options = _.extend({parse: true}, options);
    +      var model = this;
    +      var success = options.success;
    +      options.success = function(resp) {
    +        var serverAttrs = options.parse ? model.parse(resp, options) : resp;
    +        if (!model.set(serverAttrs, options)) return false;
    +        if (success) success.call(options.context, model, resp, options);
    +        model.trigger('sync', model, resp, options);
           };
    -      wrapError(this, options);
    -      return this.sync('read', this, options);
    +      wrapError(this, options);
    +      return this.sync('read', this, options);
         },
  • @@ -1666,8 +1673,8 @@

    Backbone.Model

  • -
    - +
    + §

    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 @@ -1675,7 +1682,7 @@

    Backbone.Model

    -
        save: function(key, val, options) {
    +
        save: function(key, val, options) {
  • @@ -1683,23 +1690,23 @@

    Backbone.Model

  • -
    - +
    + §

    Handle both "key", value and {key: value} -style arguments.

          var attrs;
    -      if (key == null || typeof key === 'object') {
    +      if (key == null || typeof key === 'object') {
             attrs = key;
             options = val;
           } else {
             (attrs = {})[key] = val;
           }
     
    -      options = _.extend({validate: true, parse: true}, options);
    -      var wait = options.wait;
    + options = _.extend({validate: true, parse: true}, options); + var wait = options.wait;
  • @@ -1707,8 +1714,8 @@

    Backbone.Model

  • -
    - +
    + §

    If we’re not waiting and attributes exist, save acts as set(attr).save(null, opts) with validation. Otherwise, check if @@ -1717,8 +1724,8 @@

    Backbone.Model

          if (attrs && !wait) {
    -        if (!this.set(attrs, options)) return false;
    -      } else if (!this._validate(attrs, options)) {
    +        if (!this.set(attrs, options)) return false;
    +      } else if (!this._validate(attrs, options)) {
             return false;
           }
    @@ -1728,18 +1735,18 @@

    Backbone.Model

  • -
    - +
    + §

    After a successful server-side save, the client is (optionally) updated with the server-side state.

    -
          var model = this;
    -      var success = options.success;
    -      var attributes = this.attributes;
    -      options.success = function(resp) {
    +
          var model = this;
    +      var success = options.success;
    +      var attributes = this.attributes;
    +      options.success = function(resp) {
  • @@ -1747,21 +1754,21 @@

    Backbone.Model

  • -
    - +
    + §

    Ensure attributes are restored during synchronous saves.

    -
            model.attributes = attributes;
    -        var serverAttrs = options.parse ? model.parse(resp, options) : resp;
    -        if (wait) serverAttrs = _.extend({}, attrs, serverAttrs);
    -        if (serverAttrs && !model.set(serverAttrs, options)) return false;
    -        if (success) success.call(options.context, model, resp, options);
    -        model.trigger('sync', model, resp, options);
    +            
            model.attributes = attributes;
    +        var serverAttrs = options.parse ? model.parse(resp, options) : resp;
    +        if (wait) serverAttrs = _.extend({}, attrs, serverAttrs);
    +        if (serverAttrs && !model.set(serverAttrs, options)) return false;
    +        if (success) success.call(options.context, model, resp, options);
    +        model.trigger('sync', model, resp, options);
           };
    -      wrapError(this, options);
    + wrapError(this, options);
  • @@ -1769,18 +1776,18 @@

    Backbone.Model

  • -
    - +
    + §

    Set temporary attributes if {wait: true} to properly find new ids.

    -
          if (attrs && wait) this.attributes = _.extend({}, attributes, attrs);
    +            
          if (attrs && wait) this.attributes = _.extend({}, attributes, attrs);
     
    -      var method = this.isNew() ? 'create' : options.patch ? 'patch' : 'update';
    -      if (method === 'patch' && !options.attrs) options.attrs = attrs;
    -      var xhr = this.sync(method, this, options);
    + var method = this.isNew() ? 'create' : options.patch ? 'patch' : 'update'; + if (method === 'patch' && !options.attrs) options.attrs = attrs; + var xhr = this.sync(method, this, options);
  • @@ -1788,14 +1795,14 @@

    Backbone.Model

  • -
    - +
    + §

    Restore attributes.

    -
          this.attributes = attributes;
    +            
          this.attributes = attributes;
     
           return xhr;
         },
    @@ -1806,8 +1813,8 @@

    Backbone.Model

  • -
    - +
    + §

    Destroy this model on the server if it was already persisted. Optimistically removes the model from its collection, if it has one. @@ -1815,31 +1822,31 @@

    Backbone.Model

    -
        destroy: function(options) {
    -      options = options ? _.clone(options) : {};
    -      var model = this;
    -      var success = options.success;
    -      var wait = options.wait;
    +            
        destroy: function(options) {
    +      options = options ? _.clone(options) : {};
    +      var model = this;
    +      var success = options.success;
    +      var wait = options.wait;
     
    -      var destroy = function() {
    -        model.stopListening();
    -        model.trigger('destroy', model, model.collection, options);
    +      var destroy = function() {
    +        model.stopListening();
    +        model.trigger('destroy', model, model.collection, options);
           };
     
    -      options.success = function(resp) {
    -        if (wait) destroy();
    -        if (success) success.call(options.context, model, resp, options);
    -        if (!model.isNew()) model.trigger('sync', model, resp, options);
    +      options.success = function(resp) {
    +        if (wait) destroy();
    +        if (success) success.call(options.context, model, resp, options);
    +        if (!model.isNew()) model.trigger('sync', model, resp, options);
           };
     
           var xhr = false;
    -      if (this.isNew()) {
    -        _.defer(options.success);
    +      if (this.isNew()) {
    +        _.defer(options.success);
           } else {
    -        wrapError(this, options);
    -        xhr = this.sync('delete', this, options);
    +        wrapError(this, options);
    +        xhr = this.sync('delete', this, options);
           }
    -      if (!wait) destroy();
    +      if (!wait) destroy();
           return xhr;
         },
    @@ -1849,8 +1856,8 @@

    Backbone.Model

  • -
    - +
    + §

    Default URL for the model’s representation on the server – if you’re using Backbone’s restful methods, override this to change the endpoint @@ -1858,14 +1865,14 @@

    Backbone.Model

    -
        url: function() {
    +            
        url: function() {
           var base =
    -        _.result(this, 'urlRoot') ||
    -        _.result(this.collection, 'url') ||
    -        urlError();
    -      if (this.isNew()) return base;
    -      var id = this.get(this.idAttribute);
    -      return base.replace(/[^\/]$/, '$&/') + encodeURIComponent(id);
    +        _.result(this, 'urlRoot') ||
    +        _.result(this.collection, 'url') ||
    +        urlError();
    +      if (this.isNew()) return base;
    +      var id = this.get(this.idAttribute);
    +      return base.replace(/[^\/]$/, '$&/') + encodeURIComponent(id);
         },
  • @@ -1874,15 +1881,15 @@

    Backbone.Model

  • -
    - +
    + §

    parse converts a response into the hash of attributes to be set on the model. The default implementation is just to pass the response along.

    -
        parse: function(resp, options) {
    +            
        parse: function(resp, options) {
           return resp;
         },
    @@ -1892,15 +1899,15 @@

    Backbone.Model

  • -
    - +
    + §

    Create a new model with identical attributes to this one.

    -
        clone: function() {
    -      return new this.constructor(this.attributes);
    +            
        clone: function() {
    +      return new this.constructor(this.attributes);
         },
  • @@ -1909,15 +1916,15 @@

    Backbone.Model

  • -
    - +
    + §

    A model is new if it has never been saved to the server, and lacks an id.

    -
        isNew: function() {
    -      return !this.has(this.idAttribute);
    +            
        isNew: function() {
    +      return !this.has(this.idAttribute);
         },
  • @@ -1926,15 +1933,15 @@

    Backbone.Model

  • -
    - +
    + §

    Check if the model is currently in a valid state.

    -
        isValid: function(options) {
    -      return this._validate({}, _.extend({}, options, {validate: true}));
    +            
        isValid: function(options) {
    +      return this._validate({}, _.extend({}, options, {validate: true}));
         },
  • @@ -1943,20 +1950,20 @@

    Backbone.Model

  • -
    - +
    + §

    Run validation against the next complete set of model attributes, returning true if all is well. Otherwise, fire an "invalid" event.

    -
        _validate: function(attrs, options) {
    -      if (!options.validate || !this.validate) return true;
    -      attrs = _.extend({}, this.attributes, attrs);
    -      var error = this.validationError = this.validate(attrs, options) || null;
    +            
        _validate: function(attrs, options) {
    +      if (!options.validate || !this.validate) return true;
    +      attrs = _.extend({}, this.attributes, attrs);
    +      var error = this.validationError = this.validate(attrs, options) || null;
           if (!error) return true;
    -      this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
    +      this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
           return false;
         }
     
    @@ -1968,10 +1975,10 @@ 

    Backbone.Model

  • -
    - +
    + §
    -

    Backbone.Collection

    +

    Backbone.Collection

    @@ -1981,8 +1988,8 @@

    Backbone.Collection

  • -
    - +
    + §
    @@ -1993,8 +2000,8 @@

    Backbone.Collection

  • -
    - +
    + §

    If models tend to represent a single row of data, a Backbone Collection is more analogous to a table full of data … or a small slice or page of that @@ -2011,8 +2018,8 @@

    Backbone.Collection

  • -
    - +
    + §

    Create a new Collection, perhaps to contain a specific type of model. If a comparator is specified, the Collection will maintain @@ -2020,14 +2027,14 @@

    Backbone.Collection

    -
      var Collection = Backbone.Collection = function(models, options) {
    +            
      var Collection = Backbone.Collection = function(models, options) {
         options || (options = {});
    -    this.preinitialize.apply(this, arguments);
    -    if (options.model) this.model = options.model;
    -    if (options.comparator !== void 0) this.comparator = options.comparator;
    -    this._reset();
    -    this.initialize.apply(this, arguments);
    -    if (models) this.reset(models, _.extend({silent: true}, options));
    +    this.preinitialize.apply(this, arguments);
    +    if (options.model) this.model = options.model;
    +    if (options.comparator !== void 0) this.comparator = options.comparator;
    +    this._reset();
    +    this.initialize.apply(this, arguments);
    +    if (models) this.reset(models, _.extend({silent: true}, options));
       };
  • @@ -2036,15 +2043,15 @@

    Backbone.Collection

  • -
    - +
    + §

    Default options for Collection#set.

    -
      var setOptions = {add: true, remove: true, merge: true};
    -  var addOptions = {add: true, remove: false};
    +
      var setOptions = {add: true, remove: true, merge: true};
    +  var addOptions = {add: true, remove: false};
  • @@ -2052,21 +2059,21 @@

    Backbone.Collection

  • -
    - +
    + §

    Splices insert into array at index at.

    -
      var splice = function(array, insert, at) {
    -    at = Math.min(Math.max(at, 0), array.length);
    -    var tail = Array(array.length - at);
    -    var length = insert.length;
    +            
      var splice = function(array, insert, at) {
    +    at = Math.min(Math.max(at, 0), array.length);
    +    var tail = Array(array.length - at);
    +    var length = insert.length;
         var i;
    -    for (i = 0; i < tail.length; i++) tail[i] = array[i + at];
    +    for (i = 0; i < tail.length; i++) tail[i] = array[i + at];
         for (i = 0; i < length; i++) array[i + at] = insert[i];
    -    for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];
    +    for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];
       };
  • @@ -2075,14 +2082,14 @@

    Backbone.Collection

  • -
    - +
    + §

    Define the Collection’s inheritable methods.

    -
      _.extend(Collection.prototype, Events, {
    +
      _.extend(Collection.prototype, Events, {
  • @@ -2090,15 +2097,15 @@

    Backbone.Collection

  • -
    - +
    + §

    The default model for a collection is just a Backbone.Model. This should be overridden in most cases.

    -
        model: Model,
    +
        model: Model,
  • @@ -2106,15 +2113,15 @@

    Backbone.Collection

  • -
    - +
    + §

    preinitialize is an empty function by default. You can override it with a function or object. preinitialize will run before any instantiation logic is run in the Collection.

    -
        preinitialize: function(){},
    +
        preinitialize: function(){},
  • @@ -2122,15 +2129,15 @@

    Backbone.Collection

  • -
    - +
    + §

    Initialize is an empty function by default. Override it with your own initialization logic.

    -
        initialize: function(){},
    +
        initialize: function(){},
  • @@ -2138,16 +2145,16 @@

    Backbone.Collection

  • -
    - +
    + §

    The JSON representation of a Collection is an array of the models’ attributes.

    -
        toJSON: function(options) {
    -      return this.map(function(model) { return model.toJSON(options); });
    +            
        toJSON: function(options) {
    +      return this.map(function(model) { return model.toJSON(options); });
         },
  • @@ -2156,15 +2163,15 @@

    Backbone.Collection

  • -
    - +
    + §

    Proxy Backbone.sync by default.

    -
        sync: function() {
    -      return Backbone.sync.apply(this, arguments);
    +            
        sync: function() {
    +      return Backbone.sync.apply(this, arguments);
         },
  • @@ -2173,8 +2180,8 @@

    Backbone.Collection

  • -
    - +
    + §

    Add a model, or list of models to the set. models may be Backbone Models or raw JavaScript objects to be converted to Models, or any @@ -2182,8 +2189,8 @@

    Backbone.Collection

    -
        add: function(models, options) {
    -      return this.set(models, _.extend({merge: false}, options, addOptions));
    +            
        add: function(models, options) {
    +      return this.set(models, _.extend({merge: false}, options, addOptions));
         },
  • @@ -2192,21 +2199,21 @@

    Backbone.Collection

  • -
    - +
    + §

    Remove a model, or a list of models from the set.

    -
        remove: function(models, options) {
    -      options = _.extend({}, options);
    -      var singular = !_.isArray(models);
    -      models = singular ? [models] : models.slice();
    -      var removed = this._removeModels(models, options);
    -      if (!options.silent && removed.length) {
    -        options.changes = {added: [], merged: [], removed: removed};
    -        this.trigger('update', this, options);
    +            
        remove: function(models, options) {
    +      options = _.extend({}, options);
    +      var singular = !_.isArray(models);
    +      models = singular ? [models] : models.slice();
    +      var removed = this._removeModels(models, options);
    +      if (!options.silent && removed.length) {
    +        options.changes = {added: [], merged: [], removed: removed};
    +        this.trigger('update', this, options);
           }
           return singular ? removed[0] : removed;
         },
    @@ -2217,8 +2224,8 @@

    Backbone.Collection

  • -
    - +
    + §

    Update a collection by set-ing a new list of models, adding new ones, removing models that are no longer present, and merging models that @@ -2227,21 +2234,21 @@

    Backbone.Collection

    -
        set: function(models, options) {
    +            
        set: function(models, options) {
           if (models == null) return;
     
    -      options = _.extend({}, setOptions, options);
    -      if (options.parse && !this._isModel(models)) {
    -        models = this.parse(models, options) || [];
    +      options = _.extend({}, setOptions, options);
    +      if (options.parse && !this._isModel(models)) {
    +        models = this.parse(models, options) || [];
           }
     
    -      var singular = !_.isArray(models);
    -      models = singular ? [models] : models.slice();
    +      var singular = !_.isArray(models);
    +      models = singular ? [models] : models.slice();
     
    -      var at = options.at;
    +      var at = options.at;
           if (at != null) at = +at;
    -      if (at > this.length) at = this.length;
    -      if (at < 0) at += this.length + 1;
    +      if (at > this.length) at = this.length;
    +      if (at < 0) at += this.length + 1;
     
           var set = [];
           var toAdd = [];
    @@ -2249,13 +2256,13 @@ 

    Backbone.Collection

    var toRemove = []; var modelMap = {}; - var add = options.add; - var merge = options.merge; - var remove = options.remove; + var add = options.add; + var merge = options.merge; + var remove = options.remove; var sort = false; - var sortable = this.comparator && at == null && options.sort !== false; - var sortAttr = _.isString(this.comparator) ? this.comparator : null;
    + var sortable = this.comparator && at == null && options.sort !== false; + var sortAttr = _.isString(this.comparator) ? this.comparator : null;
  • @@ -2263,8 +2270,8 @@

    Backbone.Collection

  • -
    - +
    + §

    Turn bare objects into model references, and prevent invalid models from being added.

    @@ -2272,7 +2279,7 @@

    Backbone.Collection

          var model, i;
    -      for (i = 0; i < models.length; i++) {
    +      for (i = 0; i < models.length; i++) {
             model = models[i];
  • @@ -2281,26 +2288,26 @@

    Backbone.Collection

  • -
    - +
    + §

    If a duplicate is found, prevent it from being added and optionally merge it into the existing model.

    -
            var existing = this.get(model);
    +            
            var existing = this.get(model);
             if (existing) {
               if (merge && model !== existing) {
    -            var attrs = this._isModel(model) ? model.attributes : model;
    -            if (options.parse) attrs = existing.parse(attrs, options);
    -            existing.set(attrs, options);
    -            toMerge.push(existing);
    -            if (sortable && !sort) sort = existing.hasChanged(sortAttr);
    +            var attrs = this._isModel(model) ? model.attributes : model;
    +            if (options.parse) attrs = existing.parse(attrs, options);
    +            existing.set(attrs, options);
    +            toMerge.push(existing);
    +            if (sortable && !sort) sort = existing.hasChanged(sortAttr);
               }
    -          if (!modelMap[existing.cid]) {
    -            modelMap[existing.cid] = true;
    -            set.push(existing);
    +          if (!modelMap[existing.cid]) {
    +            modelMap[existing.cid] = true;
    +            set.push(existing);
               }
               models[i] = existing;
    @@ -2310,20 +2317,20 @@

    Backbone.Collection

  • -
    - +
    + §

    If this is a new, valid model, push it to the toAdd list.

            } else if (add) {
    -          model = models[i] = this._prepareModel(model, options);
    +          model = models[i] = this._prepareModel(model, options);
               if (model) {
    -            toAdd.push(model);
    -            this._addReference(model, options);
    -            modelMap[model.cid] = true;
    -            set.push(model);
    +            toAdd.push(model);
    +            this._addReference(model, options);
    +            modelMap[model.cid] = true;
    +            set.push(model);
               }
             }
           }
    @@ -2334,19 +2341,19 @@

    Backbone.Collection

  • -
    - +
    + §

    Remove stale models.

          if (remove) {
    -        for (i = 0; i < this.length; i++) {
    -          model = this.models[i];
    -          if (!modelMap[model.cid]) toRemove.push(model);
    +        for (i = 0; i < this.length; i++) {
    +          model = this.models[i];
    +          if (!modelMap[model.cid]) toRemove.push(model);
             }
    -        if (toRemove.length) this._removeModels(toRemove, options);
    +        if (toRemove.length) this._removeModels(toRemove, options);
           }
  • @@ -2355,8 +2362,8 @@

    Backbone.Collection

  • -
    - +
    + §

    See if sorting is needed, update length and splice in new models.

    @@ -2364,17 +2371,17 @@

    Backbone.Collection

          var orderChanged = false;
           var replace = !sortable && add && remove;
    -      if (set.length && replace) {
    -        orderChanged = this.length !== set.length || _.some(this.models, function(m, index) {
    +      if (set.length && replace) {
    +        orderChanged = this.length !== set.length || _.some(this.models, function(m, index) {
               return m !== set[index];
             });
    -        this.models.length = 0;
    -        splice(this.models, set, 0);
    -        this.length = this.models.length;
    -      } else if (toAdd.length) {
    +        this.models.length = 0;
    +        splice(this.models, set, 0);
    +        this.length = this.models.length;
    +      } else if (toAdd.length) {
             if (sortable) sort = true;
    -        splice(this.models, toAdd, at == null ? this.length : at);
    -        this.length = this.models.length;
    +        splice(this.models, toAdd, at == null ? this.length : at);
    +        this.length = this.models.length;
           }
  • @@ -2383,14 +2390,14 @@

    Backbone.Collection

  • -
    - +
    + §

    Silently sort the collection if appropriate.

    -
          if (sort) this.sort({silent: true});
    +
          if (sort) this.sort({silent: true});
  • @@ -2398,27 +2405,27 @@

    Backbone.Collection

  • -
    - +
    + §

    Unless silenced, it’s time to fire all appropriate add/sort/update events.

    -
          if (!options.silent) {
    -        for (i = 0; i < toAdd.length; i++) {
    -          if (at != null) options.index = at + i;
    +            
          if (!options.silent) {
    +        for (i = 0; i < toAdd.length; i++) {
    +          if (at != null) options.index = at + i;
               model = toAdd[i];
    -          model.trigger('add', model, this, options);
    +          model.trigger('add', model, this, options);
             }
    -        if (sort || orderChanged) this.trigger('sort', this, options);
    -        if (toAdd.length || toRemove.length || toMerge.length) {
    -          options.changes = {
    -            added: toAdd,
    -            removed: toRemove,
    -            merged: toMerge
    +        if (sort || orderChanged) this.trigger('sort', this, options);
    +        if (toAdd.length || toRemove.length || toMerge.length) {
    +          options.changes = {
    +            added: toAdd,
    +            removed: toRemove,
    +            merged: toMerge
               };
    -          this.trigger('update', this, options);
    +          this.trigger('update', this, options);
             }
           }
    @@ -2428,8 +2435,8 @@

    Backbone.Collection

  • -
    - +
    + §

    Return the added (or merged) model (or models).

    @@ -2444,8 +2451,8 @@

    Backbone.Collection

  • -
    - +
    + §

    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 @@ -2454,15 +2461,15 @@

    Backbone.Collection

    -
        reset: function(models, options) {
    -      options = options ? _.clone(options) : {};
    -      for (var i = 0; i < this.models.length; i++) {
    -        this._removeReference(this.models[i], options);
    +            
        reset: function(models, options) {
    +      options = options ? _.clone(options) : {};
    +      for (var i = 0; i < this.models.length; i++) {
    +        this._removeReference(this.models[i], options);
           }
    -      options.previousModels = this.models;
    -      this._reset();
    -      models = this.add(models, _.extend({silent: true}, options));
    -      if (!options.silent) this.trigger('reset', this, options);
    +      options.previousModels = this.models;
    +      this._reset();
    +      models = this.add(models, _.extend({silent: true}, options));
    +      if (!options.silent) this.trigger('reset', this, options);
           return models;
         },
    @@ -2472,15 +2479,15 @@

    Backbone.Collection

  • -
    - +
    + §

    Add a model to the end of the collection.

    -
        push: function(model, options) {
    -      return this.add(model, _.extend({at: this.length}, options));
    +            
        push: function(model, options) {
    +      return this.add(model, _.extend({at: this.length}, options));
         },
  • @@ -2489,16 +2496,16 @@

    Backbone.Collection

  • -
    - +
    + §

    Remove a model from the end of the collection.

    -
        pop: function(options) {
    -      var model = this.at(this.length - 1);
    -      return this.remove(model, options);
    +            
        pop: function(options) {
    +      var model = this.at(this.length - 1);
    +      return this.remove(model, options);
         },
  • @@ -2507,15 +2514,15 @@

    Backbone.Collection

  • -
    - +
    + §

    Add a model to the beginning of the collection.

    -
        unshift: function(model, options) {
    -      return this.add(model, _.extend({at: 0}, options));
    +            
        unshift: function(model, options) {
    +      return this.add(model, _.extend({at: 0}, options));
         },
  • @@ -2524,16 +2531,16 @@

    Backbone.Collection

  • -
    - +
    + §

    Remove a model from the beginning of the collection.

    -
        shift: function(options) {
    -      var model = this.at(0);
    -      return this.remove(model, options);
    +            
        shift: function(options) {
    +      var model = this.at(0);
    +      return this.remove(model, options);
         },
  • @@ -2542,15 +2549,15 @@

    Backbone.Collection

  • -
    - +
    + §

    Slice out a sub-array of models from the collection.

    -
        slice: function() {
    -      return slice.apply(this.models, arguments);
    +            
        slice: function() {
    +      return slice.apply(this.models, arguments);
         },
  • @@ -2559,19 +2566,19 @@

    Backbone.Collection

  • -
    - +
    + §

    Get a model from the set by id, cid, model object with id or cid properties, or an attributes object that is transformed through modelId.

    -
        get: function(obj) {
    +            
        get: function(obj) {
           if (obj == null) return void 0;
    -      return this._byId[obj] ||
    -        this._byId[this.modelId(this._isModel(obj) ? obj.attributes : obj)] ||
    -        obj.cid && this._byId[obj.cid];
    +      return this._byId[obj] ||
    +        this._byId[this.modelId(this._isModel(obj) ? obj.attributes : obj, obj.idAttribute)] ||
    +        obj.cid && this._byId[obj.cid];
         },
  • @@ -2580,15 +2587,15 @@

    Backbone.Collection

  • -
    - +
    + §

    Returns true if the model is in the collection.

    -
        has: function(obj) {
    -      return this.get(obj) != null;
    +            
        has: function(obj) {
    +      return this.get(obj) != null;
         },
  • @@ -2597,16 +2604,16 @@

    Backbone.Collection

  • -
    - +
    + §

    Get the model at the given index.

    -
        at: function(index) {
    -      if (index < 0) index += this.length;
    -      return this.models[index];
    +            
        at: function(index) {
    +      if (index < 0) index += this.length;
    +      return this.models[index];
         },
  • @@ -2615,16 +2622,16 @@

    Backbone.Collection

  • -
    - +
    + §

    Return models with matching attributes. Useful for simple cases of filter.

    -
        where: function(attrs, first) {
    -      return this[first ? 'find' : 'filter'](attrs);
    +            
        where: function(attrs, first) {
    +      return this[first ? 'find' : 'filter'](attrs);
         },
  • @@ -2633,16 +2640,16 @@

    Backbone.Collection

  • -
    - +
    + §

    Return the first model with matching attributes. Useful for simple cases of find.

    -
        findWhere: function(attrs) {
    -      return this.where(attrs, true);
    +            
        findWhere: function(attrs) {
    +      return this.where(attrs, true);
         },
  • @@ -2651,8 +2658,8 @@

    Backbone.Collection

  • -
    - +
    + §

    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 @@ -2660,13 +2667,13 @@

    Backbone.Collection

    -
        sort: function(options) {
    -      var comparator = this.comparator;
    -      if (!comparator) throw new Error('Cannot sort a set without a comparator');
    +            
        sort: function(options) {
    +      var comparator = this.comparator;
    +      if (!comparator) throw new Error('Cannot sort a set without a comparator');
           options || (options = {});
     
    -      var length = comparator.length;
    -      if (_.isFunction(comparator)) comparator = comparator.bind(this);
    + var length = comparator.length; + if (_.isFunction(comparator)) comparator = comparator.bind(this);
  • @@ -2674,20 +2681,20 @@

    Backbone.Collection

  • -
    - +
    + §

    Run sort based on type of comparator.

    -
          if (length === 1 || _.isString(comparator)) {
    -        this.models = this.sortBy(comparator);
    +            
          if (length === 1 || _.isString(comparator)) {
    +        this.models = this.sortBy(comparator);
           } else {
    -        this.models.sort(comparator);
    +        this.models.sort(comparator);
           }
    -      if (!options.silent) this.trigger('sort', this, options);
    -      return this;
    +      if (!options.silent) this.trigger('sort', this, options);
    +      return this;
         },
  • @@ -2696,15 +2703,15 @@

    Backbone.Collection

  • -
    - +
    + §

    Pluck an attribute from each model in the collection.

    -
        pluck: function(attr) {
    -      return this.map(attr + '');
    +            
        pluck: function(attr) {
    +      return this.map(attr + '');
         },
  • @@ -2713,8 +2720,8 @@

    Backbone.Collection

  • -
    - +
    + §

    Fetch the default set of models for this collection, resetting the collection when they arrive. If reset: true is passed, the response @@ -2722,18 +2729,18 @@

    Backbone.Collection

    -
        fetch: function(options) {
    -      options = _.extend({parse: true}, options);
    -      var success = options.success;
    -      var collection = this;
    -      options.success = function(resp) {
    -        var method = options.reset ? 'reset' : 'set';
    +            
        fetch: function(options) {
    +      options = _.extend({parse: true}, options);
    +      var success = options.success;
    +      var collection = this;
    +      options.success = function(resp) {
    +        var method = options.reset ? 'reset' : 'set';
             collection[method](resp, options);
    -        if (success) success.call(options.context, collection, resp, options);
    -        collection.trigger('sync', collection, resp, options);
    +        if (success) success.call(options.context, collection, resp, options);
    +        collection.trigger('sync', collection, resp, options);
           };
    -      wrapError(this, options);
    -      return this.sync('read', this, options);
    +      wrapError(this, options);
    +      return this.sync('read', this, options);
         },
  • @@ -2742,8 +2749,8 @@

    Backbone.Collection

  • -
    - +
    + §

    Create a new instance of a model in this collection. Add the model to the collection immediately, unless wait: true is passed, in which case we @@ -2751,19 +2758,19 @@

    Backbone.Collection

    -
        create: function(model, options) {
    -      options = options ? _.clone(options) : {};
    -      var wait = options.wait;
    -      model = this._prepareModel(model, options);
    +            
        create: function(model, options) {
    +      options = options ? _.clone(options) : {};
    +      var wait = options.wait;
    +      model = this._prepareModel(model, options);
           if (!model) return false;
    -      if (!wait) this.add(model, options);
    -      var collection = this;
    -      var success = options.success;
    -      options.success = function(m, resp, callbackOpts) {
    -        if (wait) collection.add(m, callbackOpts);
    -        if (success) success.call(callbackOpts.context, m, resp, callbackOpts);
    +      if (!wait) this.add(model, options);
    +      var collection = this;
    +      var success = options.success;
    +      options.success = function(m, resp, callbackOpts) {
    +        if (wait) collection.add(m, callbackOpts);
    +        if (success) success.call(callbackOpts.context, m, resp, callbackOpts);
           };
    -      model.save(null, options);
    +      model.save(null, options);
           return model;
         },
    @@ -2773,15 +2780,15 @@

    Backbone.Collection

  • -
    - +
    + §

    parse converts a response into a list of models to be added to the collection. The default implementation is just to pass it through.

    -
        parse: function(resp, options) {
    +            
        parse: function(resp, options) {
           return resp;
         },
    @@ -2791,18 +2798,18 @@

    Backbone.Collection

  • -
    - +
    + §

    Create a new collection with an identical list of models as this one.

    -
        clone: function() {
    -      return new this.constructor(this.models, {
    -        model: this.model,
    -        comparator: this.comparator
    -      });
    +            
        clone: function() {
    +      return new this.constructor(this.models, {
    +        model: this.model,
    +        comparator: this.comparator
    +      });
         },
  • @@ -2811,15 +2818,15 @@

    Backbone.Collection

  • -
    - +
    + §

    Define how to uniquely identify models in the collection.

    -
        modelId: function(attrs) {
    -      return attrs[this.model.prototype.idAttribute || 'id'];
    +            
        modelId: function(attrs, idAttribute) {
    +      return attrs[idAttribute || this.model.prototype.idAttribute || 'id'];
         },
  • @@ -2828,15 +2835,15 @@

    Backbone.Collection

  • -
    - +
    + §

    Get an iterator of all models in this collection.

    -
        values: function() {
    -      return new CollectionIterator(this, ITERATOR_VALUES);
    +            
        values: function() {
    +      return new CollectionIterator(this, ITERATOR_VALUES);
         },
  • @@ -2845,15 +2852,15 @@

    Backbone.Collection

  • -
    - +
    + §

    Get an iterator of all model IDs in this collection.

    -
        keys: function() {
    -      return new CollectionIterator(this, ITERATOR_KEYS);
    +            
        keys: function() {
    +      return new CollectionIterator(this, ITERATOR_KEYS);
         },
  • @@ -2862,15 +2869,15 @@

    Backbone.Collection

  • -
    - +
    + §

    Get an iterator of all [ID, model] tuples in this collection.

    -
        entries: function() {
    -      return new CollectionIterator(this, ITERATOR_KEYSVALUES);
    +            
        entries: function() {
    +      return new CollectionIterator(this, ITERATOR_KEYSVALUES);
         },
  • @@ -2879,18 +2886,18 @@

    Backbone.Collection

  • -
    - +
    + §

    Private method to reset all internal state. Called when the collection is first initialized or reset.

    -
        _reset: function() {
    -      this.length = 0;
    -      this.models = [];
    -      this._byId  = {};
    +            
        _reset: function() {
    +      this.length = 0;
    +      this.models = [];
    +      this._byId  = {};
         },
  • @@ -2899,75 +2906,96 @@

    Backbone.Collection

  • -
    - +
    + §

    Prepare a hash of attributes (or other model) to be added to this collection.

    -
        _prepareModel: function(attrs, options) {
    -      if (this._isModel(attrs)) {
    -        if (!attrs.collection) attrs.collection = this;
    +            
        _prepareModel: function(attrs, options) {
    +      if (this._isModel(attrs)) {
    +        if (!attrs.collection) attrs.collection = this;
             return attrs;
           }
    -      options = options ? _.clone(options) : {};
    -      options.collection = this;
    -      var model = new this.model(attrs, options);
    -      if (!model.validationError) return model;
    -      this.trigger('invalid', this, model.validationError, options);
    +      options = options ? _.clone(options) : {};
    +      options.collection = this;
    +
    +      var model;
    +      if (this.model.prototype) {
    +        model = new this.model(attrs, options);
    +      } else {
    + +
  • + + +
  • +
    + +
    + § +
    +

    ES class methods didn’t have prototype

    + +
    + +
            model = this.model(attrs, options);
    +      }
    +
    +      if (!model.validationError) return model;
    +      this.trigger('invalid', this, model.validationError, options);
           return false;
         },
  • -
  • +
  • -
    - +
    + §

    Internal method called by both remove and set.

    -
        _removeModels: function(models, options) {
    +            
        _removeModels: function(models, options) {
           var removed = [];
    -      for (var i = 0; i < models.length; i++) {
    -        var model = this.get(models[i]);
    +      for (var i = 0; i < models.length; i++) {
    +        var model = this.get(models[i]);
             if (!model) continue;
     
    -        var index = this.indexOf(model);
    -        this.models.splice(index, 1);
    -        this.length--;
    + var index = this.indexOf(model); + this.models.splice(index, 1); + this.length--;
  • -
  • +
  • -
    - +
    + §

    Remove references before triggering ‘remove’ event to prevent an infinite loop. #3693

    -
            delete this._byId[model.cid];
    -        var id = this.modelId(model.attributes);
    -        if (id != null) delete this._byId[id];
    +            
            delete this._byId[model.cid];
    +        var id = this.modelId(model.attributes, model.idAttribute);
    +        if (id != null) delete this._byId[id];
     
    -        if (!options.silent) {
    -          options.index = index;
    -          model.trigger('remove', model, this, options);
    +        if (!options.silent) {
    +          options.index = index;
    +          model.trigger('remove', model, this, options);
             }
     
    -        removed.push(model);
    -        this._removeReference(model, options);
    +        removed.push(model);
    +        this._removeReference(model, options);
           }
           return removed;
         },
    @@ -2975,70 +3003,70 @@

    Backbone.Collection

  • -
  • +
  • -
    - +
    + §

    Method for checking whether an object should be considered a model for the purposes of adding to the collection.

    -
        _isModel: function(model) {
    -      return model instanceof Model;
    +            
        _isModel: function(model) {
    +      return model instanceof Model;
         },
  • -
  • +
  • -
    - +
    + §

    Internal method to create a model’s ties to a collection.

    -
        _addReference: function(model, options) {
    -      this._byId[model.cid] = model;
    -      var id = this.modelId(model.attributes);
    -      if (id != null) this._byId[id] = model;
    -      model.on('all', this._onModelEvent, this);
    +            
        _addReference: function(model, options) {
    +      this._byId[model.cid] = model;
    +      var id = this.modelId(model.attributes, model.idAttribute);
    +      if (id != null) this._byId[id] = model;
    +      model.on('all', this._onModelEvent, this);
         },
  • -
  • +
  • -
    - +
    + §

    Internal method to sever a model’s ties to a collection.

    -
        _removeReference: function(model, options) {
    -      delete this._byId[model.cid];
    -      var id = this.modelId(model.attributes);
    -      if (id != null) delete this._byId[id];
    -      if (this === model.collection) delete model.collection;
    -      model.off('all', this._onModelEvent, this);
    +            
        _removeReference: function(model, options) {
    +      delete this._byId[model.cid];
    +      var id = this.modelId(model.attributes, model.idAttribute);
    +      if (id != null) delete this._byId[id];
    +      if (this === model.collection) delete model.collection;
    +      model.off('all', this._onModelEvent, this);
         },
  • -
  • +
  • -
    - +
    + §

    Internal method called every time a model in the set fires an event. Sets need to update their indexes when models change ids. All other @@ -3047,20 +3075,18 @@

    Backbone.Collection

    -
        _onModelEvent: function(event, model, collection, options) {
    +            
        _onModelEvent: function(event, model, collection, options) {
           if (model) {
    -        if ((event === 'add' || event === 'remove') && collection !== this) return;
    -        if (event === 'destroy') this.remove(model, options);
    -        if (event === 'change') {
    -          var prevId = this.modelId(model.previousAttributes());
    -          var id = this.modelId(model.attributes);
    -          if (prevId !== id) {
    -            if (prevId != null) delete this._byId[prevId];
    -            if (id != null) this._byId[id] = model;
    -          }
    +        if ((event === 'add' || event === 'remove') && collection !== this) return;
    +        if (event === 'destroy') this.remove(model, options);
    +        if (event === 'changeId') {
    +          var prevId = this.modelId(model.previousAttributes(), model.idAttribute);
    +          var id = this.modelId(model.attributes, model.idAttribute);
    +          if (prevId != null) delete this._byId[prevId];
    +          if (id != null) this._byId[id] = model;
             }
           }
    -      this.trigger.apply(this, arguments);
    +      this.trigger.apply(this, arguments);
         }
     
       });
    @@ -3068,11 +3094,11 @@

    Backbone.Collection

  • -
  • +
  • -
    - +
    + §

    Defining an @@iterator method implements JavaScript’s Iterable protocol. In modern ES2015 browsers, this value is found at Symbol.iterator.

    @@ -3080,19 +3106,19 @@

    Backbone.Collection

      /* global Symbol */
    -  var $$iterator = typeof Symbol === 'function' && Symbol.iterator;
    +  var $$iterator = typeof Symbol === 'function' && Symbol.iterator;
       if ($$iterator) {
    -    Collection.prototype[$$iterator] = Collection.prototype.values;
    +    Collection.prototype[$$iterator] = Collection.prototype.values;
       }
  • -
  • +
  • -
    - +
    + §

    CollectionIterator

    @@ -3101,11 +3127,11 @@

    CollectionIterator

  • -
  • +
  • -
    - +
    + §
    @@ -3113,11 +3139,11 @@

    CollectionIterator

  • -
  • +
  • -
    - +
    + §

    A CollectionIterator implements JavaScript’s Iterator protocol, allowing the use of for of loops in modern browsers and interoperation between @@ -3126,20 +3152,20 @@

    CollectionIterator

    -
      var CollectionIterator = function(collection, kind) {
    -    this._collection = collection;
    -    this._kind = kind;
    -    this._index = 0;
    +            
      var CollectionIterator = function(collection, kind) {
    +    this._collection = collection;
    +    this._kind = kind;
    +    this._index = 0;
       };
  • -
  • +
  • -
    - +
    + §

    This “enum” defines the three possible kinds of values which can be emitted by a CollectionIterator that correspond to the values(), keys() and entries() @@ -3147,117 +3173,117 @@

    CollectionIterator

    -
      var ITERATOR_VALUES = 1;
    -  var ITERATOR_KEYS = 2;
    -  var ITERATOR_KEYSVALUES = 3;
    +
      var ITERATOR_VALUES = 1;
    +  var ITERATOR_KEYS = 2;
    +  var ITERATOR_KEYSVALUES = 3;
  • -
  • +
  • -
    - +
    + §

    All Iterators should themselves be Iterable.

      if ($$iterator) {
    -    CollectionIterator.prototype[$$iterator] = function() {
    -      return this;
    +    CollectionIterator.prototype[$$iterator] = function() {
    +      return this;
         };
       }
     
    -  CollectionIterator.prototype.next = function() {
    -    if (this._collection) {
    + CollectionIterator.prototype.next = function() { + if (this._collection) {
  • -
  • +
  • -
    - +
    + §

    Only continue iterating if the iterated collection is long enough.

    -
          if (this._index < this._collection.length) {
    -        var model = this._collection.at(this._index);
    -        this._index++;
    +
          if (this._index < this._collection.length) {
    +        var model = this._collection.at(this._index);
    +        this._index++;
  • -
  • +
  • -
    - +
    + §

    Construct a value depending on what kind of values should be iterated.

            var value;
    -        if (this._kind === ITERATOR_VALUES) {
    +        if (this._kind === ITERATOR_VALUES) {
               value = model;
             } else {
    -          var id = this._collection.modelId(model.attributes);
    -          if (this._kind === ITERATOR_KEYS) {
    +          var id = this._collection.modelId(model.attributes, model.idAttribute);
    +          if (this._kind === ITERATOR_KEYS) {
                 value = id;
               } else { // ITERATOR_KEYSVALUES
                 value = [id, model];
               }
             }
    -        return {value: value, done: false};
    +        return {value: value, done: false};
           }
  • -
  • +
  • -
    - +
    + §

    Once exhausted, remove the reference to the collection so future calls to the next method always return done.

    -
          this._collection = void 0;
    +            
          this._collection = void 0;
         }
     
    -    return {value: void 0, done: true};
    +    return {value: void 0, done: true};
       };
  • -
  • +
  • -
    - +
    + §
    -

    Backbone.View

    +

    Backbone.View

  • -
  • +
  • -
    - +
    + §
    @@ -3265,11 +3291,11 @@

    Backbone.View

  • -
  • +
  • -
    - +
    + §

    Backbone Views are almost more convention than they are actual code. A View is simply a JavaScript object that represents a logical chunk of UI in the @@ -3284,33 +3310,33 @@

    Backbone.View

  • -
  • +
  • -
    - +
    + §

    Creating a Backbone.View creates its initial element outside of the DOM, if an existing element is not provided…

    -
      var View = Backbone.View = function(options) {
    -    this.cid = _.uniqueId('view');
    -    this.preinitialize.apply(this, arguments);
    -    _.extend(this, _.pick(options, viewOptions));
    -    this._ensureElement();
    -    this.initialize.apply(this, arguments);
    +            
      var View = Backbone.View = function(options) {
    +    this.cid = _.uniqueId('view');
    +    this.preinitialize.apply(this, arguments);
    +    _.extend(this, _.pick(options, viewOptions));
    +    this._ensureElement();
    +    this.initialize.apply(this, arguments);
       };
  • -
  • +
  • -
    - +
    + §

    Cached regex to split keys for delegate.

    @@ -3321,106 +3347,106 @@

    Backbone.View

  • -
  • +
  • -
    - +
    + §

    List of view options to be set as properties.

    -
      var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
    +
      var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
  • -
  • +
  • -
    - +
    + §

    Set up all inheritable Backbone.View properties and methods.

    -
      _.extend(View.prototype, Events, {
    +
      _.extend(View.prototype, Events, {
  • -
  • +
  • -
    - +
    + §

    The default tagName of a View’s element is "div".

    -
        tagName: 'div',
    +
        tagName: 'div',
  • -
  • +
  • -
    - +
    + §

    jQuery delegate for element lookup, scoped to DOM elements within the current view. This should be preferred to global lookups where possible.

    -
        $: function(selector) {
    -      return this.$el.find(selector);
    +            
        $: function(selector) {
    +      return this.$el.find(selector);
         },
  • -
  • +
  • -
    - +
    + §

    preinitialize is an empty function by default. You can override it with a function or object. preinitialize will run before any instantiation logic is run in the View

    -
        preinitialize: function(){},
    +
        preinitialize: function(){},
  • -
  • +
  • -
    - +
    + §

    Initialize is an empty function by default. Override it with your own initialization logic.

    -
        initialize: function(){},
    +
        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 @@ -3428,38 +3454,38 @@

    Backbone.View

    -
        render: function() {
    -      return this;
    +            
        render: function() {
    +      return this;
         },
  • -
  • +
  • -
    - +
    + §

    Remove this view by taking the element out of the DOM, and removing any applicable Backbone.Events listeners.

    -
        remove: function() {
    -      this._removeElement();
    -      this.stopListening();
    -      return this;
    +            
        remove: function() {
    +      this._removeElement();
    +      this.stopListening();
    +      return this;
         },
  • -
  • +
  • -
    - +
    + §

    Remove this view’s element from the document and all event listeners attached to it. Exposed for subclasses using an alternative DOM @@ -3467,39 +3493,39 @@

    Backbone.View

    -
        _removeElement: function() {
    -      this.$el.remove();
    +            
        _removeElement: function() {
    +      this.$el.remove();
         },
  • -
  • +
  • -
    - +
    + §

    Change the view’s element (this.el property) and re-delegate the view’s events on the new element.

    -
        setElement: function(element) {
    -      this.undelegateEvents();
    -      this._setElement(element);
    -      this.delegateEvents();
    -      return this;
    +            
        setElement: function(element) {
    +      this.undelegateEvents();
    +      this._setElement(element);
    +      this.delegateEvents();
    +      return this;
         },
  • -
  • +
  • -
    - +
    + §

    Creates the this.el and this.$el references for this view using the given el. el can be a CSS selector or an HTML string, a jQuery @@ -3509,55 +3535,56 @@

    Backbone.View

    -
        _setElement: function(el) {
    -      this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
    -      this.el = this.$el[0];
    +            
        _setElement: function(el) {
    +      this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
    +      this.el = this.$el[0];
         },
  • -
  • +
  • -
    - +
    + §

    Set callbacks, where this.events is a hash of

    {“event selector”: “callback”}

    {
    -  'mousedown .title':  'edit',
    -  'click .button':     'save',
    -  'click .open':       function(e) { ... }
    +  'mousedown .title':  'edit',
    +  'click .button':     'save',
    +  'click .open':       function(e) { ... }
     }
    -

    pairs. Callbacks will be bound to the view, with this set properly. +

  • +

    pairs. Callbacks will be bound to the view, with this set properly. Uses event delegation for efficiency. Omitting the selector binds the event to this.el.

    -
        delegateEvents: function(events) {
    -      events || (events = _.result(this, 'events'));
    -      if (!events) return this;
    -      this.undelegateEvents();
    +            
        delegateEvents: function(events) {
    +      events || (events = _.result(this, 'events'));
    +      if (!events) return this;
    +      this.undelegateEvents();
           for (var key in events) {
             var method = events[key];
    -        if (!_.isFunction(method)) method = this[method];
    +        if (!_.isFunction(method)) method = this[method];
             if (!method) continue;
    -        var match = key.match(delegateEventSplitter);
    -        this.delegate(match[1], match[2], method.bind(this));
    +        var match = key.match(delegateEventSplitter);
    +        this.delegate(match[1], match[2], method.bind(this));
           }
    -      return this;
    +      return this;
         },
  • -
  • +
  • -
    - +
    + §

    Add a single event listener to the view’s element (or a child element using selector). This only works for delegate-able events: not focus, @@ -3565,19 +3592,19 @@

    Backbone.View

    -
        delegate: function(eventName, selector, listener) {
    -      this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
    -      return this;
    +            
        delegate: function(eventName, selector, listener) {
    +      this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
    +      return this;
         },
  • -
  • +
  • -
    - +
    + §

    Clears all callbacks previously bound to the view by delegateEvents. You usually don’t need to use this, but may wish to if you have multiple @@ -3585,56 +3612,56 @@

    Backbone.View

    -
        undelegateEvents: function() {
    -      if (this.$el) this.$el.off('.delegateEvents' + this.cid);
    -      return this;
    +            
        undelegateEvents: function() {
    +      if (this.$el) this.$el.off('.delegateEvents' + this.cid);
    +      return this;
         },
  • -
  • +
  • -
    - +
    + §

    A finer-grained undelegateEvents for removing a single delegated event. selector and listener are both optional.

    -
        undelegate: function(eventName, selector, listener) {
    -      this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);
    -      return this;
    +            
        undelegate: function(eventName, selector, listener) {
    +      this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);
    +      return this;
         },
  • -
  • +
  • -
    - +
    + §

    Produces a DOM element to be assigned to your view. Exposed for subclasses using an alternative DOM manipulation API.

    -
        _createElement: function(tagName) {
    -      return document.createElement(tagName);
    +            
        _createElement: function(tagName) {
    +      return document.createElement(tagName);
         },
  • -
  • +
  • -
    - +
    + §

    Ensure that the View has a DOM element to render into. If this.el is a string, pass it through $(), take the first @@ -3643,34 +3670,34 @@

    Backbone.View

    -
        _ensureElement: function() {
    -      if (!this.el) {
    -        var attrs = _.extend({}, _.result(this, 'attributes'));
    -        if (this.id) attrs.id = _.result(this, 'id');
    -        if (this.className) attrs['class'] = _.result(this, 'className');
    -        this.setElement(this._createElement(_.result(this, 'tagName')));
    -        this._setAttributes(attrs);
    +            
        _ensureElement: function() {
    +      if (!this.el) {
    +        var attrs = _.extend({}, _.result(this, 'attributes'));
    +        if (this.id) attrs.id = _.result(this, 'id');
    +        if (this.className) attrs['class'] = _.result(this, 'className');
    +        this.setElement(this._createElement(_.result(this, 'tagName')));
    +        this._setAttributes(attrs);
           } else {
    -        this.setElement(_.result(this, 'el'));
    +        this.setElement(_.result(this, 'el'));
           }
         },
  • -
  • +
  • -
    - +
    + §

    Set attributes from a hash on this view’s element. Exposed for subclasses using an alternative DOM manipulation API.

    -
        _setAttributes: function(attributes) {
    -      this.$el.attr(attributes);
    +            
        _setAttributes: function(attributes) {
    +      this.$el.attr(attributes);
         }
     
       });
    @@ -3678,11 +3705,11 @@

    Backbone.View

  • -
  • +
  • -
    - +
    + §

    Proxy Backbone class methods to Underscore functions, wrapping the model’s attributes object or collection’s models array behind the scenes.

    @@ -3692,68 +3719,68 @@

    Backbone.View

    -
      var addMethod = function(base, length, method, attribute) {
    +            
      var addMethod = function(base, length, method, attribute) {
         switch (length) {
    -      case 1: return function() {
    -        return base[method](this[attribute]);
    +      case 1: return function() {
    +        return base[method](this[attribute]);
           };
    -      case 2: return function(value) {
    -        return base[method](this[attribute], value);
    +      case 2: return function(value) {
    +        return base[method](this[attribute], value);
           };
    -      case 3: return function(iteratee, context) {
    -        return base[method](this[attribute], cb(iteratee, this), context);
    +      case 3: return function(iteratee, context) {
    +        return base[method](this[attribute], cb(iteratee, this), context);
           };
    -      case 4: return function(iteratee, defaultVal, context) {
    -        return base[method](this[attribute], cb(iteratee, this), defaultVal, context);
    +      case 4: return function(iteratee, defaultVal, context) {
    +        return base[method](this[attribute], cb(iteratee, this), defaultVal, context);
           };
    -      default: return function() {
    -        var args = slice.call(arguments);
    -        args.unshift(this[attribute]);
    -        return base[method].apply(base, args);
    +      default: return function() {
    +        var args = slice.call(arguments);
    +        args.unshift(this[attribute]);
    +        return base[method].apply(base, args);
           };
         }
       };
     
    -  var addUnderscoreMethods = function(Class, base, methods, attribute) {
    -    _.each(methods, function(length, method) {
    -      if (base[method]) Class.prototype[method] = addMethod(base, length, method, attribute);
    +  var addUnderscoreMethods = function(Class, base, methods, attribute) {
    +    _.each(methods, function(length, method) {
    +      if (base[method]) Class.prototype[method] = addMethod(base, length, method, attribute);
         });
       };
  • -
  • +
  • -
    - +
    + §

    Support collection.sortBy('attr') and collection.findWhere({id: 1}).

    -
      var cb = function(iteratee, instance) {
    -    if (_.isFunction(iteratee)) return iteratee;
    -    if (_.isObject(iteratee) && !instance._isModel(iteratee)) return modelMatcher(iteratee);
    -    if (_.isString(iteratee)) return function(model) { return model.get(iteratee); };
    +            
      var cb = function(iteratee, instance) {
    +    if (_.isFunction(iteratee)) return iteratee;
    +    if (_.isObject(iteratee) && !instance._isModel(iteratee)) return modelMatcher(iteratee);
    +    if (_.isString(iteratee)) return function(model) { return model.get(iteratee); };
         return iteratee;
       };
    -  var modelMatcher = function(attrs) {
    -    var matcher = _.matches(attrs);
    -    return function(model) {
    -      return matcher(model.attributes);
    +  var modelMatcher = function(attrs) {
    +    var matcher = _.matches(attrs);
    +    return function(model) {
    +      return matcher(model.attributes);
         };
       };
  • -
  • +
  • -
    - +
    + §

    Underscore methods that we want to implement on the Collection. 90% of the core usefulness of Backbone Collections is actually implemented @@ -3761,86 +3788,86 @@

    Backbone.View

    -
      var collectionMethods = {forEach: 3, each: 3, map: 3, collect: 3, reduce: 0,
    -    foldl: 0, inject: 0, reduceRight: 0, foldr: 0, find: 3, detect: 3, filter: 3,
    -    select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,
    -    contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
    -    head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
    -    without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
    -    isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,
    -    sortBy: 3, indexBy: 3, findIndex: 3, findLastIndex: 3};
    +
      var collectionMethods = {forEach: 3, each: 3, map: 3, collect: 3, reduce: 0,
    +    foldl: 0, inject: 0, reduceRight: 0, foldr: 0, find: 3, detect: 3, filter: 3,
    +    select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,
    +    contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
    +    head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
    +    without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
    +    isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,
    +    sortBy: 3, indexBy: 3, findIndex: 3, findLastIndex: 3};
  • -
  • +
  • -
    - +
    + §

    Underscore methods that we want to implement on the Model, mapped to the number of arguments they take.

    -
      var modelMethods = {keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
    -    omit: 0, chain: 1, isEmpty: 1};
    +
      var modelMethods = {keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
    +    omit: 0, chain: 1, isEmpty: 1};
  • -
  • +
  • -
    - +
    + §

    Mix in each Underscore method as a proxy to Collection#models.

    -  _.each([
    -    [Collection, collectionMethods, 'models'],
    -    [Model, modelMethods, 'attributes']
    -  ], function(config) {
    -    var Base = config[0],
    +  _.each([
    +    [Collection, collectionMethods, 'models'],
    +    [Model, modelMethods, 'attributes']
    +  ], function(config) {
    +    var Base = config[0],
             methods = config[1],
             attribute = config[2];
     
    -    Base.mixin = function(obj) {
    -      var mappings = _.reduce(_.functions(obj), function(memo, name) {
    +    Base.mixin = function(obj) {
    +      var mappings = _.reduce(_.functions(obj), function(memo, name) {
             memo[name] = 0;
             return memo;
           }, {});
    -      addUnderscoreMethods(Base, obj, mappings, attribute);
    +      addUnderscoreMethods(Base, obj, mappings, attribute);
         };
     
    -    addUnderscoreMethods(Base, _, methods, attribute);
    +    addUnderscoreMethods(Base, _, methods, attribute);
       });
  • -
  • +
  • -
    - +
    + §
    -

    Backbone.sync

    +

    Backbone.sync

  • -
  • +
  • -
    - +
    + §
    @@ -3848,11 +3875,11 @@

    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 @@ -3872,234 +3899,234 @@

    Backbone.sync

    -
      Backbone.sync = function(method, model, options) {
    +            
      Backbone.sync = function(method, model, options) {
         var type = methodMap[method];
  • -
  • +
  • -
    - +
    + §

    Default options, unless specified.

    -
        _.defaults(options || (options = {}), {
    -      emulateHTTP: Backbone.emulateHTTP,
    -      emulateJSON: Backbone.emulateJSON
    +            
        _.defaults(options || (options = {}), {
    +      emulateHTTP: Backbone.emulateHTTP,
    +      emulateJSON: Backbone.emulateJSON
         });
  • -
  • +
  • -
    - +
    + §

    Default JSON-request options.

    -
        var params = {type: type, dataType: 'json'};
    +
        var params = {type: type, dataType: 'json'};
  • -
  • +
  • -
    - +
    + §

    Ensure that we have a URL.

    -
        if (!options.url) {
    -      params.url = _.result(model, 'url') || urlError();
    +            
        if (!options.url) {
    +      params.url = _.result(model, 'url') || urlError();
         }
  • -
  • +
  • -
    - +
    + §

    Ensure that we have the appropriate request data.

    -
        if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
    -      params.contentType = 'application/json';
    -      params.data = JSON.stringify(options.attrs || model.toJSON(options));
    +            
        if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
    +      params.contentType = 'application/json';
    +      params.data = JSON.stringify(options.attrs || model.toJSON(options));
         }
  • -
  • +
  • -
    - +
    + §

    For older servers, emulate JSON by encoding the request into an HTML-form.

    -
        if (options.emulateJSON) {
    -      params.contentType = 'application/x-www-form-urlencoded';
    -      params.data = params.data ? {model: params.data} : {};
    +            
        if (options.emulateJSON) {
    +      params.contentType = 'application/x-www-form-urlencoded';
    +      params.data = params.data ? {model: params.data} : {};
         }
  • -
  • +
  • -
    - +
    + §

    For older servers, emulate HTTP by mimicking the HTTP method with _method And an X-HTTP-Method-Override header.

    -
        if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
    -      params.type = 'POST';
    -      if (options.emulateJSON) params.data._method = type;
    -      var beforeSend = options.beforeSend;
    -      options.beforeSend = function(xhr) {
    -        xhr.setRequestHeader('X-HTTP-Method-Override', type);
    -        if (beforeSend) return beforeSend.apply(this, arguments);
    +            
        if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
    +      params.type = 'POST';
    +      if (options.emulateJSON) params.data._method = type;
    +      var beforeSend = options.beforeSend;
    +      options.beforeSend = function(xhr) {
    +        xhr.setRequestHeader('X-HTTP-Method-Override', type);
    +        if (beforeSend) return beforeSend.apply(this, arguments);
           };
         }
  • -
  • +
  • -
    - +
    + §

    Don’t process data on a non-GET request.

    -
        if (params.type !== 'GET' && !options.emulateJSON) {
    -      params.processData = false;
    +            
        if (params.type !== 'GET' && !options.emulateJSON) {
    +      params.processData = false;
         }
  • -
  • +
  • -
    - +
    + §

    Pass along textStatus and errorThrown from jQuery.

    -
        var error = options.error;
    -    options.error = function(xhr, textStatus, errorThrown) {
    -      options.textStatus = textStatus;
    -      options.errorThrown = errorThrown;
    -      if (error) error.call(options.context, xhr, textStatus, errorThrown);
    +            
        var error = options.error;
    +    options.error = function(xhr, textStatus, errorThrown) {
    +      options.textStatus = textStatus;
    +      options.errorThrown = errorThrown;
    +      if (error) error.call(options.context, xhr, textStatus, errorThrown);
         };
  • -
  • +
  • -
    - +
    + §

    Make the request, allowing the user to override any Ajax options.

    -
        var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
    -    model.trigger('request', model, xhr, options);
    +            
        var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
    +    model.trigger('request', model, xhr, options);
         return xhr;
       };
  • -
  • +
  • -
    - +
    + §

    Map from CRUD to HTTP for our default Backbone.sync implementation.

      var methodMap = {
    -    create: 'POST',
    -    update: 'PUT',
    -    patch: 'PATCH',
    -    delete: 'DELETE',
    -    read: 'GET'
    +    'create': 'POST',
    +    'update': 'PUT',
    +    'patch': 'PATCH',
    +    'delete': 'DELETE',
    +    'read': 'GET'
       };
  • -
  • +
  • -
    - +
    + §

    Set the default implementation of Backbone.ajax to proxy through to $. Override this if you’d like to use a different library.

    -
      Backbone.ajax = function() {
    -    return Backbone.$.ajax.apply(Backbone.$, arguments);
    +            
      Backbone.ajax = function() {
    +    return Backbone.$.ajax.apply(Backbone.$, arguments);
       };
  • -
  • +
  • -
    - +
    + §
    -

    Backbone.Router

    +

    Backbone.Router

  • -
  • +
  • -
    - +
    + §
    @@ -4107,33 +4134,33 @@

    Backbone.Router

  • -
  • +
  • -
    - +
    + §

    Routers map faux-URLs to actions, and fire events when routes are matched. Creating a new one sets its routes hash, if not set statically.

    -
      var Router = Backbone.Router = function(options) {
    +            
      var Router = Backbone.Router = function(options) {
         options || (options = {});
    -    this.preinitialize.apply(this, arguments);
    -    if (options.routes) this.routes = options.routes;
    -    this._bindRoutes();
    -    this.initialize.apply(this, arguments);
    +    this.preinitialize.apply(this, arguments);
    +    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.

    @@ -4148,129 +4175,130 @@

    Backbone.Router

  • -
  • +
  • -
    - +
    + §

    Set up all inheritable Backbone.Router properties and methods.

    -
      _.extend(Router.prototype, Events, {
    +
      _.extend(Router.prototype, Events, {
  • -
  • +
  • -
    - +
    + §

    preinitialize is an empty function by default. You can override it with a function or object. preinitialize will run before any instantiation logic is run in the Router.

    -
        preinitialize: function(){},
    +
        preinitialize: function(){},
  • -
  • +
  • -
    - +
    + §

    Initialize is an empty function by default. Override it with your own initialization logic.

    -
        initialize: function(){},
    +
        initialize: function(){},
  • -
  • +
  • -
    - +
    + §

    Manually bind a single named route to a callback. For example:

    -
    this.route('search/:query/p:num', 'search', function(query, num) {
    +
    this.route('search/:query/p:num', 'search', function(query, num) {
       ...
     });
     
    +
    -
        route: function(route, name, callback) {
    -      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
    -      if (_.isFunction(name)) {
    +            
        route: function(route, name, callback) {
    +      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
    +      if (_.isFunction(name)) {
             callback = name;
    -        name = '';
    +        name = '';
           }
    -      if (!callback) callback = this[name];
    -      var router = this;
    -      Backbone.history.route(route, function(fragment) {
    -        var args = router._extractParameters(route, fragment);
    -        if (router.execute(callback, args, name) !== false) {
    -          router.trigger.apply(router, ['route:' + name].concat(args));
    -          router.trigger('route', name, args);
    -          Backbone.history.trigger('route', router, name, args);
    +      if (!callback) callback = this[name];
    +      var router = this;
    +      Backbone.history.route(route, function(fragment) {
    +        var args = router._extractParameters(route, fragment);
    +        if (router.execute(callback, args, name) !== false) {
    +          router.trigger.apply(router, ['route:' + name].concat(args));
    +          router.trigger('route', name, args);
    +          Backbone.history.trigger('route', router, name, args);
             }
           });
    -      return this;
    +      return this;
         },
  • -
  • +
  • -
    - +
    + §

    Execute a route handler with the provided parameters. This is an excellent place to do pre-route setup or post-route cleanup.

    -
        execute: function(callback, args, name) {
    -      if (callback) callback.apply(this, args);
    +            
        execute: function(callback, args, name) {
    +      if (callback) callback.apply(this, args);
         },
  • -
  • +
  • -
    - +
    + §

    Simple proxy to Backbone.history to save a fragment into the history.

    -
        navigate: function(fragment, options) {
    -      Backbone.history.navigate(fragment, options);
    -      return this;
    +            
        navigate: function(fragment, options) {
    +      Backbone.history.navigate(fragment, options);
    +      return this;
         },
  • -
  • +
  • -
    - +
    + §

    Bind all defined routes to Backbone.history. We have to reverse the order of the routes here to support behavior where the most general @@ -4278,47 +4306,47 @@

    Backbone.Router

    -
        _bindRoutes: function() {
    -      if (!this.routes) return;
    -      this.routes = _.result(this, 'routes');
    -      var route, routes = _.keys(this.routes);
    -      while ((route = routes.pop()) != null) {
    -        this.route(route, this.routes[route]);
    +            
        _bindRoutes: function() {
    +      if (!this.routes) return;
    +      this.routes = _.result(this, 'routes');
    +      var route, routes = _.keys(this.routes);
    +      while ((route = routes.pop()) != null) {
    +        this.route(route, this.routes[route]);
           }
         },
  • -
  • +
  • -
    - +
    + §

    Convert a route string into a regular expression, suitable for matching against the current location hash.

    -
        _routeToRegExp: function(route) {
    -      route = route.replace(escapeRegExp, '\\$&')
    -        .replace(optionalParam, '(?:$1)?')
    -        .replace(namedParam, function(match, optional) {
    -          return optional ? match : '([^/?]+)';
    -        })
    -        .replace(splatParam, '([^?]*?)');
    -      return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
    +            
        _routeToRegExp: function(route) {
    +      route = route.replace(escapeRegExp, '\\$&')
    +      .replace(optionalParam, '(?:$1)?')
    +      .replace(namedParam, function(match, optional) {
    +        return optional ? match : '([^/?]+)';
    +      })
    +      .replace(splatParam, '([^?]*?)');
    +      return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
         },
  • -
  • +
  • -
    - +
    + §

    Given a route, and a URL fragment that it matches, return the array of extracted decoded parameters. Empty or unmatched parameters will be @@ -4326,24 +4354,24 @@

    Backbone.Router

    -
        _extractParameters: function(route, fragment) {
    -      var params = route.exec(fragment).slice(1);
    -      return _.map(params, function(param, i) {
    +
        _extractParameters: function(route, fragment) {
    +      var params = route.exec(fragment).slice(1);
    +      return _.map(params, function(param, i) {
  • -
  • +
  • -
    - +
    + §

    Don’t decode the search params.

    -
            if (i === params.length - 1) return param || null;
    +            
            if (i === params.length - 1) return param || null;
             return param ? decodeURIComponent(param) : null;
           });
         }
    @@ -4353,24 +4381,24 @@ 

    Backbone.Router

  • -
  • +
  • -
    - +
    + §
    -

    Backbone.History

    +

    Backbone.History

  • -
  • +
  • -
    - +
    + §
    @@ -4378,11 +4406,11 @@

    Backbone.History

  • -
  • +
  • -
    - +
    + §

    Handles cross-browser history management, based on either pushState and real URLs, or @@ -4392,37 +4420,37 @@

    Backbone.History

    -
      var History = Backbone.History = function() {
    -    this.handlers = [];
    -    this.checkUrl = this.checkUrl.bind(this);
    +
      var History = Backbone.History = function() {
    +    this.handlers = [];
    +    this.checkUrl = this.checkUrl.bind(this);
  • -
  • +
  • -
    - +
    + §

    Ensure that History can be used outside of the browser.

    -
        if (typeof window !== 'undefined') {
    -      this.location = window.location;
    -      this.history = window.history;
    +            
        if (typeof window !== 'undefined') {
    +      this.location = window.location;
    +      this.history = window.history;
         }
       };
  • -
  • +
  • -
    - +
    + §

    Cached regex for stripping a leading hash/slash and trailing space.

    @@ -4433,11 +4461,11 @@

    Backbone.History

  • -
  • +
  • -
    - +
    + §

    Cached regex for stripping leading and trailing slashes.

    @@ -4448,11 +4476,11 @@

    Backbone.History

  • -
  • +
  • -
    - +
    + §

    Cached regex for stripping urls of hash.

    @@ -4463,94 +4491,94 @@

    Backbone.History

  • -
  • +
  • -
    - +
    + §

    Has the history handling already been started?

    -
      History.started = false;
    +
      History.started = false;
  • -
  • +
  • -
    - +
    + §

    Set up all inheritable Backbone.History properties and methods.

    -
      _.extend(History.prototype, Events, {
    +
      _.extend(History.prototype, Events, {
  • -
  • +
  • -
    - +
    + §

    The default interval to poll for hash changes, if necessary, is twenty times a second.

    -
        interval: 50,
    +
        interval: 50,
  • -
  • +
  • -
    - +
    + §

    Are we at the app root?

    -
        atRoot: function() {
    -      var path = this.location.pathname.replace(/[^\/]$/, '$&/');
    -      return path === this.root && !this.getSearch();
    +            
        atRoot: function() {
    +      var path = this.location.pathname.replace(/[^\/]$/, '$&/');
    +      return path === this.root && !this.getSearch();
         },
  • -
  • +
  • -
    - +
    + §

    Does the pathname match the root?

    -
        matchRoot: function() {
    -      var path = this.decodeFragment(this.location.pathname);
    -      var rootPath = path.slice(0, this.root.length - 1) + '/';
    -      return rootPath === this.root;
    +            
        matchRoot: function() {
    +      var path = this.decodeFragment(this.location.pathname);
    +      var rootPath = path.slice(0, this.root.length - 1) + '/';
    +      return rootPath === this.root;
         },
  • -
  • +
  • -
    - +
    + §

    Unicode characters in location.pathname are percent encoded so they’re decoded for comparison. %25 should not be decoded since it may be part @@ -4558,191 +4586,191 @@

    Backbone.History

    -
        decodeFragment: function(fragment) {
    -      return decodeURI(fragment.replace(/%25/g, '%2525'));
    +            
        decodeFragment: function(fragment) {
    +      return decodeURI(fragment.replace(/%25/g, '%2525'));
         },
  • -
  • +
  • -
    - +
    + §

    In IE6, the hash fragment and search params are incorrect if the fragment contains ?.

    -
        getSearch: function() {
    -      var match = this.location.href.replace(/#.*/, '').match(/\?.+/);
    -      return match ? match[0] : '';
    +            
        getSearch: function() {
    +      var match = this.location.href.replace(/#.*/, '').match(/\?.+/);
    +      return match ? match[0] : '';
         },
  • -
  • +
  • -
    - +
    + §

    Gets the true hash value. Cannot use location.hash directly due to bug in Firefox where location.hash will always be decoded.

    -
        getHash: function(window) {
    -      var match = (window || this).location.href.match(/#(.*)$/);
    -      return match ? match[1] : '';
    +            
        getHash: function(window) {
    +      var match = (window || this).location.href.match(/#(.*)$/);
    +      return match ? match[1] : '';
         },
  • -
  • +
  • -
    - +
    + §

    Get the pathname and search params, without the root.

    -
        getPath: function() {
    -      var path = this.decodeFragment(
    -        this.location.pathname + this.getSearch()
    -      ).slice(this.root.length - 1);
    -      return path.charAt(0) === '/' ? path.slice(1) : path;
    +            
        getPath: function() {
    +      var path = this.decodeFragment(
    +        this.location.pathname + this.getSearch()
    +      ).slice(this.root.length - 1);
    +      return path.charAt(0) === '/' ? path.slice(1) : path;
         },
  • -
  • +
  • -
    - +
    + §

    Get the cross-browser normalized URL fragment from the path or hash.

    -
        getFragment: function(fragment) {
    +            
        getFragment: function(fragment) {
           if (fragment == null) {
    -        if (this._usePushState || !this._wantsHashChange) {
    -          fragment = this.getPath();
    +        if (this._usePushState || !this._wantsHashChange) {
    +          fragment = this.getPath();
             } else {
    -          fragment = this.getHash();
    +          fragment = this.getHash();
             }
           }
    -      return fragment.replace(routeStripper, '');
    +      return fragment.replace(routeStripper, '');
         },
  • -
  • +
  • -
    - +
    + §

    Start the hash change handling, returning true if the current URL matches an existing route, and false otherwise.

    -
        start: function(options) {
    -      if (History.started) throw new Error('Backbone.history has already been started');
    -      History.started = true;
    +
        start: function(options) {
    +      if (History.started) throw new Error('Backbone.history has already been started');
    +      History.started = true;
  • -
  • +
  • -
    - +
    + §

    Figure out the initial configuration. Do we need an iframe? Is pushState desired … is it available?

    -
          this.options          = _.extend({root: '/'}, this.options, options);
    -      this.root             = this.options.root;
    -      this._wantsHashChange = this.options.hashChange !== false;
    -      this._hasHashChange   = 'onhashchange' in window && (document.documentMode === void 0 || document.documentMode > 7);
    -      this._useHashChange   = this._wantsHashChange && this._hasHashChange;
    -      this._wantsPushState  = !!this.options.pushState;
    -      this._hasPushState    = !!(this.history && this.history.pushState);
    -      this._usePushState    = this._wantsPushState && this._hasPushState;
    -      this.fragment         = this.getFragment();
    +
          this.options          = _.extend({root: '/'}, this.options, options);
    +      this.root             = this.options.root;
    +      this._wantsHashChange = this.options.hashChange !== false;
    +      this._hasHashChange   = 'onhashchange' in window && (document.documentMode === void 0 || document.documentMode > 7);
    +      this._useHashChange   = this._wantsHashChange && this._hasHashChange;
    +      this._wantsPushState  = !!this.options.pushState;
    +      this._hasPushState    = !!(this.history && this.history.pushState);
    +      this._usePushState    = this._wantsPushState && this._hasPushState;
    +      this.fragment         = this.getFragment();
  • -
  • +
  • -
    - +
    + §

    Normalize root to always include a leading and trailing slash.

    -
          this.root = ('/' + this.root + '/').replace(rootStripper, '/');
    +
          this.root = ('/' + this.root + '/').replace(rootStripper, '/');
  • -
  • +
  • -
    - +
    + §

    Transition from hashChange to pushState or vice versa if both are requested.

    -
          if (this._wantsHashChange && this._wantsPushState) {
    +
          if (this._wantsHashChange && this._wantsPushState) {
  • -
  • +
  • -
    - +
    + §

    If we’ve started off with a route from a pushState-enabled browser, but we’re currently in a browser that doesn’t support it…

    -
            if (!this._hasPushState && !this.atRoot()) {
    -          var rootPath = this.root.slice(0, -1) || '/';
    -          this.location.replace(rootPath + '#' + this.getPath());
    +
            if (!this._hasPushState && !this.atRoot()) {
    +          var rootPath = this.root.slice(0, -1) || '/';
    +          this.location.replace(rootPath + '#' + this.getPath());
  • -
  • +
  • -
    - +
    + §

    Return immediately as browser will do redirect to new url

    @@ -4753,19 +4781,19 @@

    Backbone.History

  • -
  • +
  • -
    - +
    + §

    Or if we’ve started out with a hash-based route, but we’re currently in a browser where it could be pushState-based instead…

    -
            } else if (this._hasPushState && this.atRoot()) {
    -          this.navigate(this.getHash(), {replace: true});
    +            
            } else if (this._hasPushState && this.atRoot()) {
    +          this.navigate(this.getHash(), {replace: true});
             }
     
           }
    @@ -4773,11 +4801,11 @@

    Backbone.History

  • -
  • +
  • -
    - +
    + §

    Proxy an iframe to handle location events if the browser doesn’t support the hashchange event, HTML5 history, or the user wants @@ -4785,227 +4813,227 @@

    Backbone.History

    -
          if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) {
    -        this.iframe = document.createElement('iframe');
    -        this.iframe.src = 'javascript:0';
    -        this.iframe.style.display = 'none';
    -        this.iframe.tabIndex = -1;
    -        var body = document.body;
    +
          if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) {
    +        this.iframe = document.createElement('iframe');
    +        this.iframe.src = 'javascript:0';
    +        this.iframe.style.display = 'none';
    +        this.iframe.tabIndex = -1;
    +        var body = document.body;
  • -
  • +
  • -
    - +
    + §

    Using appendChild will throw on IE < 9 if the document is not ready.

    -
            var iWindow = body.insertBefore(this.iframe, body.firstChild).contentWindow;
    -        iWindow.document.open();
    -        iWindow.document.close();
    -        iWindow.location.hash = '#' + this.fragment;
    +            
            var iWindow = body.insertBefore(this.iframe, body.firstChild).contentWindow;
    +        iWindow.document.open();
    +        iWindow.document.close();
    +        iWindow.location.hash = '#' + this.fragment;
           }
  • -
  • +
  • -
    - +
    + §

    Add a cross-platform addEventListener shim for older browsers.

    -
          var addEventListener = window.addEventListener || function(eventName, listener) {
    -        return attachEvent('on' + eventName, listener);
    +            
          var addEventListener = window.addEventListener || function(eventName, listener) {
    +        return attachEvent('on' + eventName, listener);
           };
  • -
  • +
  • -
    - +
    + §

    Depending on whether we’re using pushState or hashes, and whether ‘onhashchange’ is supported, determine how we check the URL state.

    -
          if (this._usePushState) {
    -        addEventListener('popstate', this.checkUrl, false);
    -      } else if (this._useHashChange && !this.iframe) {
    -        addEventListener('hashchange', this.checkUrl, false);
    -      } else if (this._wantsHashChange) {
    -        this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
    +            
          if (this._usePushState) {
    +        addEventListener('popstate', this.checkUrl, false);
    +      } else if (this._useHashChange && !this.iframe) {
    +        addEventListener('hashchange', this.checkUrl, false);
    +      } else if (this._wantsHashChange) {
    +        this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
           }
     
    -      if (!this.options.silent) return this.loadUrl();
    +      if (!this.options.silent) return this.loadUrl();
         },
  • -
  • +
  • -
    - +
    + §

    Disable Backbone.history, perhaps temporarily. Not useful in a real app, but possibly useful for unit testing Routers.

    -
        stop: function() {
    +
        stop: function() {
  • -
  • +
  • -
    - +
    + §

    Add a cross-platform removeEventListener shim for older browsers.

    -
          var removeEventListener = window.removeEventListener || function(eventName, listener) {
    -        return detachEvent('on' + eventName, listener);
    +            
          var removeEventListener = window.removeEventListener || function(eventName, listener) {
    +        return detachEvent('on' + eventName, listener);
           };
  • -
  • +
  • -
    - +
    + §

    Remove window listeners.

    -
          if (this._usePushState) {
    -        removeEventListener('popstate', this.checkUrl, false);
    -      } else if (this._useHashChange && !this.iframe) {
    -        removeEventListener('hashchange', this.checkUrl, false);
    +            
          if (this._usePushState) {
    +        removeEventListener('popstate', this.checkUrl, false);
    +      } else if (this._useHashChange && !this.iframe) {
    +        removeEventListener('hashchange', this.checkUrl, false);
           }
  • -
  • +
  • -
    - +
    + §

    Clean up the iframe if necessary.

    -
          if (this.iframe) {
    -        document.body.removeChild(this.iframe);
    -        this.iframe = null;
    +            
          if (this.iframe) {
    +        document.body.removeChild(this.iframe);
    +        this.iframe = null;
           }
  • -
  • +
  • -
    - +
    + §

    Some environments will throw when clearing an undefined interval.

    -
          if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
    -      History.started = false;
    +            
          if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
    +      History.started = false;
         },
  • -
  • +
  • -
    - +
    + §

    Add a route to be tested when the fragment changes. Routes added later may override previous routes.

    -
        route: function(route, callback) {
    -      this.handlers.unshift({route: route, callback: callback});
    +            
        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();
    +
        checkUrl: function(e) {
    +      var current = this.getFragment();
  • -
  • +
  • -
    - +
    + §

    If the user pressed the back button, the iframe’s hash will have changed and we should use that for comparison.

    -
          if (current === this.fragment && this.iframe) {
    -        current = this.getHash(this.iframe.contentWindow);
    +            
          if (current === this.fragment && this.iframe) {
    +        current = this.getHash(this.iframe.contentWindow);
           }
     
    -      if (current === this.fragment) return false;
    -      if (this.iframe) this.navigate(current);
    -      this.loadUrl();
    +      if (current === this.fragment) return false;
    +      if (this.iframe) this.navigate(current);
    +      this.loadUrl();
         },
  • -
  • +
  • -
    - +
    + §

    Attempt to load the current URL fragment. If a route succeeds with a match, returns true. If no defined routes matches the fragment, @@ -5013,26 +5041,26 @@

    Backbone.History

    -
        loadUrl: function(fragment) {
    +
        loadUrl: function(fragment) {
  • -
  • +
  • -
    - +
    + §

    If the root doesn’t match, no routes can match either.

    -
          if (!this.matchRoot()) return false;
    -      fragment = this.fragment = this.getFragment(fragment);
    -      return _.some(this.handlers, function(handler) {
    -        if (handler.route.test(fragment)) {
    -          handler.callback(fragment);
    +            
          if (!this.matchRoot()) return false;
    +      fragment = this.fragment = this.getFragment(fragment);
    +      return _.some(this.handlers, function(handler) {
    +        if (handler.route.test(fragment)) {
    +          handler.callback(fragment);
               return true;
             }
           });
    @@ -5041,11 +5069,11 @@ 

    Backbone.History

  • -
  • +
  • -
    - +
    + §

    Save a fragment into the hash history, or replace the URL state if the ‘replace’ option is passed. You are responsible for properly URL-encoding @@ -5056,120 +5084,120 @@

    Backbone.History

    -
        navigate: function(fragment, options) {
    -      if (!History.started) return false;
    -      if (!options || options === true) options = {trigger: !!options};
    +
        navigate: function(fragment, options) {
    +      if (!History.started) return false;
    +      if (!options || options === true) options = {trigger: !!options};
  • -
  • +
  • -
    - +
    + §

    Normalize the fragment.

    -
          fragment = this.getFragment(fragment || '');
    +
          fragment = this.getFragment(fragment || '');
  • -
  • +
  • -
    - +
    + §

    Don’t include a trailing slash on the root.

    -
          var rootPath = this.root;
    -      if (fragment === '' || fragment.charAt(0) === '?') {
    -        rootPath = rootPath.slice(0, -1) || '/';
    +            
          var rootPath = this.root;
    +      if (fragment === '' || fragment.charAt(0) === '?') {
    +        rootPath = rootPath.slice(0, -1) || '/';
           }
           var url = rootPath + fragment;
  • -
  • +
  • -
    - +
    + §

    Strip the fragment of the query and hash for matching.

    -
          fragment = fragment.replace(pathStripper, '');
    +
          fragment = fragment.replace(pathStripper, '');
  • -
  • +
  • -
    - +
    + §

    Decode for matching.

    -
          var decodedFragment = this.decodeFragment(fragment);
    +            
          var decodedFragment = this.decodeFragment(fragment);
     
    -      if (this.fragment === decodedFragment) return;
    -      this.fragment = decodedFragment;
    + if (this.fragment === decodedFragment) return; + this.fragment = decodedFragment;
  • -
  • +
  • -
    - +
    + §

    If pushState is available, we use it to set the fragment as a real URL.

    -
          if (this._usePushState) {
    -        this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
    +
          if (this._usePushState) {
    +        this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
  • -
  • +
  • -
    - +
    + §

    If hash changes haven’t been explicitly disabled, update the hash fragment to store history.

    -
          } else if (this._wantsHashChange) {
    -        this._updateHash(this.location, fragment, options.replace);
    -        if (this.iframe && fragment !== this.getHash(this.iframe.contentWindow)) {
    -          var iWindow = this.iframe.contentWindow;
    +
          } else if (this._wantsHashChange) {
    +        this._updateHash(this.location, fragment, options.replace);
    +        if (this.iframe && fragment !== this.getHash(this.iframe.contentWindow)) {
    +          var iWindow = this.iframe.contentWindow;
  • -
  • +
  • -
    - +
    + §

    Opening and closing the iframe tricks IE7 and earlier to push a history entry on hash-tag change. When replace is true, we don’t @@ -5177,22 +5205,22 @@

    Backbone.History

    -
              if (!options.replace) {
    -            iWindow.document.open();
    -            iWindow.document.close();
    +            
              if (!options.replace) {
    +            iWindow.document.open();
    +            iWindow.document.close();
               }
     
    -          this._updateHash(iWindow.location, fragment, options.replace);
    +          this._updateHash(iWindow.location, fragment, options.replace);
             }
  • -
  • +
  • -
    - +
    + §

    If you’ve told us that you explicitly don’t want fallback hashchange- based history, then navigate becomes a page refresh.

    @@ -5200,45 +5228,45 @@

    Backbone.History

          } else {
    -        return this.location.assign(url);
    +        return this.location.assign(url);
           }
    -      if (options.trigger) return this.loadUrl(fragment);
    +      if (options.trigger) return this.loadUrl(fragment);
         },
  • -
  • +
  • -
    - +
    + §

    Update the hash location, either replacing the current entry, or adding a new one to the browser history.

    -
        _updateHash: function(location, fragment, replace) {
    +            
        _updateHash: function(location, fragment, replace) {
           if (replace) {
    -        var href = location.href.replace(/(javascript:|#).*$/, '');
    -        location.replace(href + '#' + fragment);
    +        var href = location.href.replace(/(javascript:|#).*$/, '');
    +        location.replace(href + '#' + fragment);
           } else {
  • -
  • +
  • -
    - +
    + §

    Some browsers require that hash contains a leading #.

    -
            location.hash = '#' + fragment;
    +            
            location.hash = '#' + fragment;
           }
         }
     
    @@ -5247,26 +5275,26 @@ 

    Backbone.History

  • -
  • +
  • -
    - +
    + §

    Create the default Backbone.history.

    -
      Backbone.history = new History;
    +
      Backbone.history = new History;
  • -
  • +
  • -
    - +
    + §

    Helpers

    @@ -5275,11 +5303,11 @@

    Helpers

  • -
  • +
  • -
    - +
    + §
    @@ -5287,11 +5315,11 @@

    Helpers

  • -
  • +
  • -
    - +
    + §

    Helper function to correctly set up the prototype chain for subclasses. Similar to goog.inherits, but uses a hash of prototype properties and @@ -5299,18 +5327,18 @@

    Helpers

    -
      var extend = function(protoProps, staticProps) {
    -    var parent = this;
    +            
      var extend = function(protoProps, staticProps) {
    +    var parent = this;
         var child;
  • -
  • +
  • -
    - +
    + §

    The constructor function for the new subclass is either defined by you (the “constructor” property in your extend definition), or defaulted @@ -5318,59 +5346,59 @@

    Helpers

    -
        if (protoProps && _.has(protoProps, 'constructor')) {
    -      child = protoProps.constructor;
    +            
        if (protoProps && _.has(protoProps, 'constructor')) {
    +      child = protoProps.constructor;
         } else {
    -      child = function(){ return parent.apply(this, arguments); };
    +      child = function(){ return parent.apply(this, arguments); };
         }
  • -
  • +
  • -
    - +
    + §

    Add static properties to the constructor function, if supplied.

    -
        _.extend(child, parent, staticProps);
    +
        _.extend(child, parent, staticProps);
  • -
  • +
  • -
    - +
    + §

    Set the prototype chain to inherit from parent, without calling parent‘s constructor function and add the prototype properties.

    -
        child.prototype = _.create(parent.prototype, protoProps);
    -    child.prototype.constructor = child;
    +
        child.prototype = _.create(parent.prototype, protoProps);
    +    child.prototype.constructor = child;
  • -
  • +
  • -
    - +
    + §

    Set a convenience property in case the parent’s prototype is needed later.

    -
        child.__super__ = parent.prototype;
    +            
        child.__super__ = parent.prototype;
     
         return child;
       };
    @@ -5378,57 +5406,57 @@

    Helpers

  • -
  • +
  • -
    - +
    + §

    Set up inheritance for the model, collection, router, view and history.

    -
      Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
    +
      Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
  • -
  • +
  • -
    - +
    + §

    Throw an error when a URL is needed, and none is supplied.

    -
      var urlError = function() {
    -    throw new Error('A "url" property or function must be specified');
    +            
      var urlError = function() {
    +    throw new Error('A "url" property or function must be specified');
       };
  • -
  • +
  • -
    - +
    + §

    Wrap an optional error callback with a fallback error event.

    -
      var wrapError = function(model, options) {
    -    var error = options.error;
    -    options.error = function(resp) {
    -      if (error) error.call(options.context, model, resp, options);
    -      model.trigger('error', model, resp, options);
    +            
      var wrapError = function(model, options) {
    +    var error = options.error;
    +    options.error = function(resp) {
    +      if (error) error.call(options.context, model, resp, options);
    +      model.trigger('error', model, resp, options);
         };
       };
     
    -  return Backbone;
    +  return Backbone;
     });
  • diff --git a/docs/backbone.localStorage.html b/docs/backbone.localStorage.html index 42c42c46cb..a7c8ddf2ac 100644 --- a/docs/backbone.localStorage.html +++ b/docs/backbone.localStorage.html @@ -1,464 +1,13 @@ - - backbone.localStorage.js - - - - + -
    -
    - - - -
      - -
    • -
      -

      backbone.localStorage.js

      -
      -
    • - - - -
    • -
      - -
      - -
      - -
      - -
      /**
      - * Backbone localStorage Adapter
      - * Version 1.1.0
      - *
      - * https://github.com/jeromegn/Backbone.localStorage
      - */
      -(function (root, factory) {
      -   if (typeof define === "function" && define.amd) {
      - -
    • - - -
    • -
      - -
      - -
      -

      AMD. Register as an anonymous module.

      - -
      - -
            define(["underscore","backbone"], function(_, Backbone) {
      - -
    • - - -
    • -
      - -
      - -
      -

      Use global variables if the locals are undefined.

      - -
      - -
              return factory(_ || root._, Backbone || root.Backbone);
      -      });
      -   } else {
      - -
    • - - -
    • -
      - -
      - -
      -

      RequireJS isn’t being used. Assume underscore and backbone are loaded in script tags

      - -
      - -
            factory(_, Backbone);
      -   }
      -}(this, function(_, Backbone) {
      - -
    • - - -
    • -
      - -
      - -
      -

      A simple module to replace Backbone.sync with localStorage-based -persistence. Models are given GUIDS, and saved into a JSON object. Simple -as that.

      - -
      - -
    • - - -
    • -
      - -
      - -
      -

      Hold reference to Underscore.js and Backbone.js in the closure in order -to make things work even if they are removed from the global namespace

      - -
      - -
    • - - -
    • -
      - -
      - -
      -

      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. -window.Store is deprecated, use Backbone.LocalStorage instead

      - -
      - -
      Backbone.LocalStorage = window.Store = function(name) {
      -  this.name = name;
      -  var store = this.localStorage().getItem(this.name);
      -  this.records = (store && store.split(",")) || [];
      -};
      -
      -_.extend(Backbone.LocalStorage.prototype, {
      - -
    • - - -
    • -
      - -
      - -
      -

      Save the current state of the Store to localStorage.

      - -
      - -
        save: function() {
      -    this.localStorage().setItem(this.name, this.records.join(","));
      -  },
      - -
    • - - -
    • -
      - -
      - -
      -

      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 = guid();
      -      model.set(model.idAttribute, model.id);
      -    }
      -    this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
      -    this.records.push(model.id.toString());
      -    this.save();
      -    return this.find(model);
      -  },
      - -
    • - - -
    • -
      - -
      - -
      -

      Update a model by replacing its copy in this.data.

      - -
      - -
        update: function(model) {
      -    this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
      -    if (!_.include(this.records, model.id.toString()))
      -      this.records.push(model.id.toString()); this.save();
      -    return this.find(model);
      -  },
      - -
    • - - -
    • -
      - -
      - -
      -

      Retrieve a model from this.data by id.

      - -
      - -
        find: function(model) {
      -    return this.jsonData(this.localStorage().getItem(this.name+"-"+model.id));
      -  },
      - -
    • - - -
    • -
      - -
      - -
      -

      Return the array of all models currently in storage.

      - -
      - -
        findAll: function() {
      -    return _(this.records).chain()
      -      .map(function(id){
      -        return this.jsonData(this.localStorage().getItem(this.name+"-"+id));
      -      }, this)
      -      .compact()
      -      .value();
      -  },
      - -
    • - - -
    • -
      - -
      - -
      -

      Delete a model from this.data, returning it.

      - -
      - -
        destroy: function(model) {
      -    if (model.isNew())
      -      return false
      -    this.localStorage().removeItem(this.name+"-"+model.id);
      -    this.records = _.reject(this.records, function(id){
      -      return id === model.id.toString();
      -    });
      -    this.save();
      -    return model;
      -  },
      -
      -  localStorage: function() {
      -    return localStorage;
      -  },
      - -
    • - - -
    • -
      - -
      - -
      -

      fix for “illegal access” error on Android when JSON.parse is passed null

      - -
      - -
        jsonData: function (data) {
      -      return data && JSON.parse(data);
      -  }
      -
      -});
      - -
    • - - -
    • -
      - -
      - -
      -

      localSync delegate to the model or collection’s -localStorage property, which should be an instance of Store. -window.Store.sync and Backbone.localSync is deprectated, use Backbone.LocalStorage.sync instead

      - -
      - -
      Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(method, model, options) {
      -  var store = model.localStorage || model.collection.localStorage;
      -
      -  var resp, errorMessage, syncDfd = $.Deferred && $.Deferred(); //If $ is having Deferred - use it.
      -
      -  try {
      -
      -    switch (method) {
      -      case "read":
      -        resp = model.id != undefined ? 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;
      -    }
      -
      -  } catch(error) {
      -    if (error.code === DOMException.QUOTA_EXCEEDED_ERR && window.localStorage.length === 0)
      -      errorMessage = "Private browsing is unsupported";
      -    else
      -      errorMessage = error.message;
      -  }
      -
      -  if (resp) {
      -    model.trigger("sync", model, resp, options);
      -    if (options && options.success)
      -      options.success(resp);
      -    if (syncDfd)
      -      syncDfd.resolve(resp);
      -
      -  } else {
      -    errorMessage = errorMessage ? errorMessage
      -                                : "Record Not Found";
      -
      -    if (options && options.error)
      -      options.error(errorMessage);
      -    if (syncDfd)
      -      syncDfd.reject(errorMessage);
      -  }
      - -
    • - - -
    • -
      - -
      - -
      -

      add compatibility with $.ajax -always execute callback for success and error

      - -
      - -
        if (options && options.complete) options.complete(resp);
      -
      -  return syncDfd && syncDfd.promise();
      -};
      -
      -Backbone.ajaxSync = Backbone.sync;
      -
      -Backbone.getSyncMethod = function(model) {
      -  if(model.localStorage || (model.collection && model.collection.localStorage)) {
      -    return Backbone.localSync;
      -  }
      -
      -  return Backbone.ajaxSync;
      -};
      - -
    • - - -
    • -
      - -
      - -
      -

      Override ‘Backbone.sync’ to default to localSync, -the original ‘Backbone.sync’ is still available in ‘Backbone.ajaxSync’

      - -
      - -
      Backbone.sync = function(method, model, options) {
      -  return Backbone.getSyncMethod(model).apply(this, [method, model, options]);
      -};
      -
      -return Backbone.LocalStorage;
      -}));
      - -
    • - -
    -
    +

    This annotated source has moved to examples/backbone.localStorage.html. You will be automatically redirected in two seconds.

    + diff --git a/docs/docco.css b/docs/docco.css index b60f6fa3df..c3d580fabb 100644 --- a/docs/docco.css +++ b/docs/docco.css @@ -213,7 +213,7 @@ ul.sections > li > div { /*---------------------- Low resolutions (> 320px) ---------------------*/ @media only screen and (min-width: 320px) { - .pilwrap { display: none; } + .sswrap { display: none; } ul.sections > li > div { display: block; @@ -330,12 +330,12 @@ ul.sections > li > div { box-shadow: none; } - .pilwrap { + .sswrap { position: relative; display: inline; } - .pilcrow { + .ss { font: 12px Arial; text-decoration: none; color: #454545; @@ -345,14 +345,14 @@ ul.sections > li > div { opacity: 0; -webkit-transition: opacity 0.2s linear; } - .for-h1 .pilcrow { + .for-h1 .ss { top: 47px; } - .for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow { + .for-h2 .ss, .for-h3 .ss, .for-h4 .ss { top: 35px; } - ul.sections > li > div.annotation:hover .pilcrow { + ul.sections > li > div.annotation:hover .ss { opacity: 1; } } diff --git a/docs/examples/backbone.localStorage.html b/docs/examples/backbone.localStorage.html new file mode 100644 index 0000000000..01b7f5c8d0 --- /dev/null +++ b/docs/examples/backbone.localStorage.html @@ -0,0 +1,464 @@ + + + + + backbone.localStorage.js + + + + + +
    +
    + + + +
      + +
    • +
      +

      backbone.localStorage.js

      +
      +
    • + + + +
    • +
      + +
      + § +
      + +
      + +
      /**
      + * Backbone localStorage Adapter
      + * Version 1.1.0
      + *
      + * https://github.com/jeromegn/Backbone.localStorage
      + */
      +(function (root, factory) {
      +   if (typeof define === "function" && define.amd) {
      + +
    • + + +
    • +
      + +
      + § +
      +

      AMD. Register as an anonymous module.

      + +
      + +
            define(["underscore","backbone"], function(_, Backbone) {
      + +
    • + + +
    • +
      + +
      + § +
      +

      Use global variables if the locals are undefined.

      + +
      + +
              return factory(_ || root._, Backbone || root.Backbone);
      +      });
      +   } else {
      + +
    • + + +
    • +
      + +
      + § +
      +

      RequireJS isn’t being used. Assume underscore and backbone are loaded in script tags

      + +
      + +
            factory(_, Backbone);
      +   }
      +}(this, function(_, Backbone) {
      + +
    • + + +
    • +
      + +
      + § +
      +

      A simple module to replace Backbone.sync with localStorage-based +persistence. Models are given GUIDS, and saved into a JSON object. Simple +as that.

      + +
      + +
    • + + +
    • +
      + +
      + § +
      +

      Hold reference to Underscore.js and Backbone.js in the closure in order +to make things work even if they are removed from the global namespace

      + +
      + +
    • + + +
    • +
      + +
      + § +
      +

      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. +window.Store is deprecated, use Backbone.LocalStorage instead

      + +
      + +
      Backbone.LocalStorage = window.Store = function(name) {
      +  this.name = name;
      +  var store = this.localStorage().getItem(this.name);
      +  this.records = (store && store.split(",")) || [];
      +};
      +
      +_.extend(Backbone.LocalStorage.prototype, {
      + +
    • + + +
    • +
      + +
      + § +
      +

      Save the current state of the Store to localStorage.

      + +
      + +
        save: function() {
      +    this.localStorage().setItem(this.name, this.records.join(","));
      +  },
      + +
    • + + +
    • +
      + +
      + § +
      +

      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 = guid();
      +      model.set(model.idAttribute, model.id);
      +    }
      +    this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
      +    this.records.push(model.id.toString());
      +    this.save();
      +    return this.find(model);
      +  },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Update a model by replacing its copy in this.data.

      + +
      + +
        update: function(model) {
      +    this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
      +    if (!_.include(this.records, model.id.toString()))
      +      this.records.push(model.id.toString()); this.save();
      +    return this.find(model);
      +  },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Retrieve a model from this.data by id.

      + +
      + +
        find: function(model) {
      +    return this.jsonData(this.localStorage().getItem(this.name+"-"+model.id));
      +  },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Return the array of all models currently in storage.

      + +
      + +
        findAll: function() {
      +    return _(this.records).chain()
      +      .map(function(id){
      +        return this.jsonData(this.localStorage().getItem(this.name+"-"+id));
      +      }, this)
      +      .compact()
      +      .value();
      +  },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Delete a model from this.data, returning it.

      + +
      + +
        destroy: function(model) {
      +    if (model.isNew())
      +      return false
      +    this.localStorage().removeItem(this.name+"-"+model.id);
      +    this.records = _.reject(this.records, function(id){
      +      return id === model.id.toString();
      +    });
      +    this.save();
      +    return model;
      +  },
      +
      +  localStorage: function() {
      +    return localStorage;
      +  },
      + +
    • + + +
    • +
      + +
      + § +
      +

      fix for “illegal access” error on Android when JSON.parse is passed null

      + +
      + +
        jsonData: function (data) {
      +      return data && JSON.parse(data);
      +  }
      +
      +});
      + +
    • + + +
    • +
      + +
      + § +
      +

      localSync delegate to the model or collection’s +localStorage property, which should be an instance of Store. +window.Store.sync and Backbone.localSync is deprectated, use Backbone.LocalStorage.sync instead

      + +
      + +
      Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(method, model, options) {
      +  var store = model.localStorage || model.collection.localStorage;
      +
      +  var resp, errorMessage, syncDfd = $.Deferred && $.Deferred(); //If $ is having Deferred - use it.
      +
      +  try {
      +
      +    switch (method) {
      +      case "read":
      +        resp = model.id != undefined ? 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;
      +    }
      +
      +  } catch(error) {
      +    if (error.code === DOMException.QUOTA_EXCEEDED_ERR && window.localStorage.length === 0)
      +      errorMessage = "Private browsing is unsupported";
      +    else
      +      errorMessage = error.message;
      +  }
      +
      +  if (resp) {
      +    model.trigger("sync", model, resp, options);
      +    if (options && options.success)
      +      options.success(resp);
      +    if (syncDfd)
      +      syncDfd.resolve(resp);
      +
      +  } else {
      +    errorMessage = errorMessage ? errorMessage
      +                                : "Record Not Found";
      +
      +    if (options && options.error)
      +      options.error(errorMessage);
      +    if (syncDfd)
      +      syncDfd.reject(errorMessage);
      +  }
      + +
    • + + +
    • +
      + +
      + § +
      +

      add compatibility with $.ajax +always execute callback for success and error

      + +
      + +
        if (options && options.complete) options.complete(resp);
      +
      +  return syncDfd && syncDfd.promise();
      +};
      +
      +Backbone.ajaxSync = Backbone.sync;
      +
      +Backbone.getSyncMethod = function(model) {
      +  if(model.localStorage || (model.collection && model.collection.localStorage)) {
      +    return Backbone.localSync;
      +  }
      +
      +  return Backbone.ajaxSync;
      +};
      + +
    • + + +
    • +
      + +
      + § +
      +

      Override ‘Backbone.sync’ to default to localSync, +the original ‘Backbone.sync’ is still available in ‘Backbone.ajaxSync’

      + +
      + +
      Backbone.sync = function(method, model, options) {
      +  return Backbone.getSyncMethod(model).apply(this, [method, model, options]);
      +};
      +
      +return Backbone.LocalStorage;
      +}));
      + +
    • + +
    +
    + + diff --git a/docs/examples/todos/todos.html b/docs/examples/todos/todos.html new file mode 100644 index 0000000000..77e2e1ae46 --- /dev/null +++ b/docs/examples/todos/todos.html @@ -0,0 +1,791 @@ + + + + + todos.js + + + + + +
    +
    + + + +
      + +
    • +
      +

      todos.js

      +
      +
    • + + + +
    • +
      + +
      + § +
      +

      An example Backbone application contributed by +Jérôme Gravel-Niquet. This demo uses a simple +LocalStorage adapter +to persist Backbone models within your browser.

      + +
      + +
    • + + +
    • +
      + +
      + § +
      +

      Load the application once the DOM is ready, using jQuery.ready:

      + +
      + +
      $(function(){
      + +
    • + + +
    • +
      + +
      + § +
      +

      Todo Model

      + +
      + +
    • + + +
    • +
      + +
      + § +
      + +
      + +
    • + + +
    • +
      + +
      + § +
      +

      Our basic Todo model has title, order, and done attributes.

      + +
      + +
        var Todo = Backbone.Model.extend({
      + +
    • + + +
    • +
      + +
      + § +
      +

      Default attributes for the todo item.

      + +
      + +
          defaults: function() {
      +      return {
      +        title: "empty todo...",
      +        order: Todos.nextOrder(),
      +        done: false
      +      };
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Toggle the done state of this todo item.

      + +
      + +
          toggle: function() {
      +      this.save({done: !this.get("done")});
      +    }
      +
      +  });
      + +
    • + + +
    • +
      + +
      + § +
      +

      Todo Collection

      + +
      + +
    • + + +
    • +
      + +
      + § +
      + +
      + +
    • + + +
    • +
      + +
      + § +
      +

      The collection of todos is backed by localStorage instead of a remote +server.

      + +
      + +
        var TodoList = Backbone.Collection.extend({
      + +
    • + + +
    • +
      + +
      + § +
      +

      Reference to this collection’s model.

      + +
      + +
          model: Todo,
      + +
    • + + +
    • +
      + +
      + § +
      +

      Save all of the todo items under the "todos-backbone" namespace.

      + +
      + +
          localStorage: new Backbone.LocalStorage("todos-backbone"),
      + +
    • + + +
    • +
      + +
      + § +
      +

      Filter down the list of all todo items that are finished.

      + +
      + +
          done: function() {
      +      return this.where({done: true});
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Filter down the list to only todo items that are still not finished.

      + +
      + +
          remaining: function() {
      +      return this.where({done: false});
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      We keep the Todos in sequential order, despite being saved by unordered +GUID in the database. This generates the next order number for new items.

      + +
      + +
          nextOrder: function() {
      +      if (!this.length) return 1;
      +      return this.last().get('order') + 1;
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Todos are sorted by their original insertion order.

      + +
      + +
          comparator: 'order'
      +
      +  });
      + +
    • + + +
    • +
      + +
      + § +
      +

      Create our global collection of Todos.

      + +
      + +
        var Todos = new TodoList;
      + +
    • + + +
    • +
      + +
      + § +
      +

      Todo Item View

      + +
      + +
    • + + +
    • +
      + +
      + § +
      + +
      + +
    • + + +
    • +
      + +
      + § +
      +

      The DOM element for a todo item…

      + +
      + +
        var TodoView = Backbone.View.extend({
      + +
    • + + +
    • +
      + +
      + § +
      +

      … is a list tag.

      + +
      + +
          tagName:  "li",
      + +
    • + + +
    • +
      + +
      + § +
      +

      Cache the template function for a single item.

      + +
      + +
          template: _.template($('#item-template').html()),
      + +
    • + + +
    • +
      + +
      + § +
      +

      The DOM events specific to an item.

      + +
      + +
          events: {
      +      "click .toggle"   : "toggleDone",
      +      "dblclick .view"  : "edit",
      +      "click a.destroy" : "clear",
      +      "keypress .edit"  : "updateOnEnter",
      +      "blur .edit"      : "close"
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      The TodoView listens for changes to its model, re-rendering. Since there’s +a one-to-one correspondence between a Todo and a TodoView in this +app, we set a direct reference on the model for convenience.

      + +
      + +
          initialize: function() {
      +      this.listenTo(this.model, 'change', this.render);
      +      this.listenTo(this.model, 'destroy', this.remove);
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Re-render the titles of the todo item.

      + +
      + +
          render: function() {
      +      this.$el.html(this.template(this.model.toJSON()));
      +      this.$el.toggleClass('done', this.model.get('done'));
      +      this.input = this.$('.edit');
      +      return this;
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Toggle the "done" state of the model.

      + +
      + +
          toggleDone: function() {
      +      this.model.toggle();
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Switch this view into "editing" mode, displaying the input field.

      + +
      + +
          edit: function() {
      +      this.$el.addClass("editing");
      +      this.input.focus();
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Close the "editing" mode, saving changes to the todo.

      + +
      + +
          close: function() {
      +      var value = this.input.val();
      +      if (!value) {
      +        this.clear();
      +      } else {
      +        this.model.save({title: value});
      +        this.$el.removeClass("editing");
      +      }
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      If you hit enter, we’re through editing the item.

      + +
      + +
          updateOnEnter: function(e) {
      +      if (e.keyCode == 13) this.close();
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Remove the item, destroy the model.

      + +
      + +
          clear: function() {
      +      this.model.destroy();
      +    }
      +
      +  });
      + +
    • + + +
    • +
      + +
      + § +
      +

      The Application

      + +
      + +
    • + + +
    • +
      + +
      + § +
      + +
      + +
    • + + +
    • +
      + +
      + § +
      +

      Our overall AppView is the top-level piece of UI.

      + +
      + +
        var AppView = Backbone.View.extend({
      + +
    • + + +
    • +
      + +
      + § +
      +

      Instead of generating a new element, bind to the existing skeleton of +the App already present in the HTML.

      + +
      + +
          el: $("#todoapp"),
      + +
    • + + +
    • +
      + +
      + § +
      +

      Our template for the line of statistics at the bottom of the app.

      + +
      + +
          statsTemplate: _.template($('#stats-template').html()),
      + +
    • + + +
    • +
      + +
      + § +
      +

      Delegated events for creating new items, and clearing completed ones.

      + +
      + +
          events: {
      +      "keypress #new-todo":  "createOnEnter",
      +      "click #clear-completed": "clearCompleted",
      +      "click #toggle-all": "toggleAllComplete"
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      At initialization we bind to the relevant events on the Todos +collection, when items are added or changed. Kick things off by +loading any preexisting todos that might be saved in localStorage.

      + +
      + +
          initialize: function() {
      +
      +      this.input = this.$("#new-todo");
      +      this.allCheckbox = this.$("#toggle-all")[0];
      +
      +      this.listenTo(Todos, 'add', this.addOne);
      +      this.listenTo(Todos, 'reset', this.addAll);
      +      this.listenTo(Todos, 'all', this.render);
      +
      +      this.footer = this.$('footer');
      +      this.main = $('#main');
      +
      +      Todos.fetch();
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Re-rendering the App just means refreshing the statistics – the rest +of the app doesn’t change.

      + +
      + +
          render: function() {
      +      var done = Todos.done().length;
      +      var remaining = Todos.remaining().length;
      +
      +      if (Todos.length) {
      +        this.main.show();
      +        this.footer.show();
      +        this.footer.html(this.statsTemplate({done: done, remaining: remaining}));
      +      } else {
      +        this.main.hide();
      +        this.footer.hide();
      +      }
      +
      +      this.allCheckbox.checked = !remaining;
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Add a single todo item to the list by creating a view for it, and +appending its element to the <ul>.

      + +
      + +
          addOne: function(todo) {
      +      var view = new TodoView({model: todo});
      +      this.$("#todo-list").append(view.render().el);
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Add all items in the Todos collection at once.

      + +
      + +
          addAll: function() {
      +      Todos.each(this.addOne, this);
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      If you hit return in the main input field, create new Todo model, +persisting it to localStorage.

      + +
      + +
          createOnEnter: function(e) {
      +      if (e.keyCode != 13) return;
      +      if (!this.input.val()) return;
      +
      +      Todos.create({title: this.input.val()});
      +      this.input.val('');
      +    },
      + +
    • + + +
    • +
      + +
      + § +
      +

      Clear all done todo items, destroying their models.

      + +
      + +
          clearCompleted: function() {
      +      _.invoke(Todos.done(), 'destroy');
      +      return false;
      +    },
      +
      +    toggleAllComplete: function () {
      +      var done = this.allCheckbox.checked;
      +      Todos.each(function (todo) { todo.save({'done': done}); });
      +    }
      +
      +  });
      + +
    • + + +
    • +
      + +
      + § +
      +

      Finally, we kick things off by creating the App.

      + +
      + +
        var App = new AppView;
      +
      +});
      + +
    • + +
    +
    + + diff --git a/docs/public/fonts/roboto-black.eot b/docs/public/fonts/roboto-black.eot old mode 100755 new mode 100644 diff --git a/docs/public/fonts/roboto-black.ttf b/docs/public/fonts/roboto-black.ttf old mode 100755 new mode 100644 diff --git a/docs/public/fonts/roboto-black.woff b/docs/public/fonts/roboto-black.woff old mode 100755 new mode 100644 diff --git a/docs/todos.html b/docs/todos.html index 1ac4e52b49..225010684a 100644 --- a/docs/todos.html +++ b/docs/todos.html @@ -1,791 +1,13 @@ - - todos.js - - - - + -
    -
    - - - -
      - -
    • -
      -

      todos.js

      -
      -
    • - - - -
    • -
      - -
      - -
      -

      An example Backbone application contributed by -Jérôme Gravel-Niquet. This demo uses a simple -LocalStorage adapter -to persist Backbone models within your browser.

      - -
      - -
    • - - -
    • -
      - -
      - -
      -

      Load the application once the DOM is ready, using jQuery.ready:

      - -
      - -
      $(function(){
      - -
    • - - -
    • -
      - -
      - -
      -

      Todo Model

      - -
      - -
    • - - -
    • -
      - -
      - -
      - -
      - -
    • - - -
    • -
      - -
      - -
      -

      Our basic Todo model has title, order, and done attributes.

      - -
      - -
        var Todo = Backbone.Model.extend({
      - -
    • - - -
    • -
      - -
      - -
      -

      Default attributes for the todo item.

      - -
      - -
          defaults: function() {
      -      return {
      -        title: "empty todo...",
      -        order: Todos.nextOrder(),
      -        done: false
      -      };
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      Toggle the done state of this todo item.

      - -
      - -
          toggle: function() {
      -      this.save({done: !this.get("done")});
      -    }
      -
      -  });
      - -
    • - - -
    • -
      - -
      - -
      -

      Todo Collection

      - -
      - -
    • - - -
    • -
      - -
      - -
      - -
      - -
    • - - -
    • -
      - -
      - -
      -

      The collection of todos is backed by localStorage instead of a remote -server.

      - -
      - -
        var TodoList = Backbone.Collection.extend({
      - -
    • - - -
    • -
      - -
      - -
      -

      Reference to this collection’s model.

      - -
      - -
          model: Todo,
      - -
    • - - -
    • -
      - -
      - -
      -

      Save all of the todo items under the "todos-backbone" namespace.

      - -
      - -
          localStorage: new Backbone.LocalStorage("todos-backbone"),
      - -
    • - - -
    • -
      - -
      - -
      -

      Filter down the list of all todo items that are finished.

      - -
      - -
          done: function() {
      -      return this.where({done: true});
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      Filter down the list to only todo items that are still not finished.

      - -
      - -
          remaining: function() {
      -      return this.where({done: false});
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      We keep the Todos in sequential order, despite being saved by unordered -GUID in the database. This generates the next order number for new items.

      - -
      - -
          nextOrder: function() {
      -      if (!this.length) return 1;
      -      return this.last().get('order') + 1;
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      Todos are sorted by their original insertion order.

      - -
      - -
          comparator: 'order'
      -
      -  });
      - -
    • - - -
    • -
      - -
      - -
      -

      Create our global collection of Todos.

      - -
      - -
        var Todos = new TodoList;
      - -
    • - - -
    • -
      - -
      - -
      -

      Todo Item View

      - -
      - -
    • - - -
    • -
      - -
      - -
      - -
      - -
    • - - -
    • -
      - -
      - -
      -

      The DOM element for a todo item…

      - -
      - -
        var TodoView = Backbone.View.extend({
      - -
    • - - -
    • -
      - -
      - -
      -

      … is a list tag.

      - -
      - -
          tagName:  "li",
      - -
    • - - -
    • -
      - -
      - -
      -

      Cache the template function for a single item.

      - -
      - -
          template: _.template($('#item-template').html()),
      - -
    • - - -
    • -
      - -
      - -
      -

      The DOM events specific to an item.

      - -
      - -
          events: {
      -      "click .toggle"   : "toggleDone",
      -      "dblclick .view"  : "edit",
      -      "click a.destroy" : "clear",
      -      "keypress .edit"  : "updateOnEnter",
      -      "blur .edit"      : "close"
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      The TodoView listens for changes to its model, re-rendering. Since there’s -a one-to-one correspondence between a Todo and a TodoView in this -app, we set a direct reference on the model for convenience.

      - -
      - -
          initialize: function() {
      -      this.listenTo(this.model, 'change', this.render);
      -      this.listenTo(this.model, 'destroy', this.remove);
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      Re-render the titles of the todo item.

      - -
      - -
          render: function() {
      -      this.$el.html(this.template(this.model.toJSON()));
      -      this.$el.toggleClass('done', this.model.get('done'));
      -      this.input = this.$('.edit');
      -      return this;
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      Toggle the "done" state of the model.

      - -
      - -
          toggleDone: function() {
      -      this.model.toggle();
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      Switch this view into "editing" mode, displaying the input field.

      - -
      - -
          edit: function() {
      -      this.$el.addClass("editing");
      -      this.input.focus();
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      Close the "editing" mode, saving changes to the todo.

      - -
      - -
          close: function() {
      -      var value = this.input.val();
      -      if (!value) {
      -        this.clear();
      -      } else {
      -        this.model.save({title: value});
      -        this.$el.removeClass("editing");
      -      }
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      If you hit enter, we’re through editing the item.

      - -
      - -
          updateOnEnter: function(e) {
      -      if (e.keyCode == 13) this.close();
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      Remove the item, destroy the model.

      - -
      - -
          clear: function() {
      -      this.model.destroy();
      -    }
      -
      -  });
      - -
    • - - -
    • -
      - -
      - -
      -

      The Application

      - -
      - -
    • - - -
    • -
      - -
      - -
      - -
      - -
    • - - -
    • -
      - -
      - -
      -

      Our overall AppView is the top-level piece of UI.

      - -
      - -
        var AppView = Backbone.View.extend({
      - -
    • - - -
    • -
      - -
      - -
      -

      Instead of generating a new element, bind to the existing skeleton of -the App already present in the HTML.

      - -
      - -
          el: $("#todoapp"),
      - -
    • - - -
    • -
      - -
      - -
      -

      Our template for the line of statistics at the bottom of the app.

      - -
      - -
          statsTemplate: _.template($('#stats-template').html()),
      - -
    • - - -
    • -
      - -
      - -
      -

      Delegated events for creating new items, and clearing completed ones.

      - -
      - -
          events: {
      -      "keypress #new-todo":  "createOnEnter",
      -      "click #clear-completed": "clearCompleted",
      -      "click #toggle-all": "toggleAllComplete"
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      At initialization we bind to the relevant events on the Todos -collection, when items are added or changed. Kick things off by -loading any preexisting todos that might be saved in localStorage.

      - -
      - -
          initialize: function() {
      -
      -      this.input = this.$("#new-todo");
      -      this.allCheckbox = this.$("#toggle-all")[0];
      -
      -      this.listenTo(Todos, 'add', this.addOne);
      -      this.listenTo(Todos, 'reset', this.addAll);
      -      this.listenTo(Todos, 'all', this.render);
      -
      -      this.footer = this.$('footer');
      -      this.main = $('#main');
      -
      -      Todos.fetch();
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      Re-rendering the App just means refreshing the statistics – the rest -of the app doesn’t change.

      - -
      - -
          render: function() {
      -      var done = Todos.done().length;
      -      var remaining = Todos.remaining().length;
      -
      -      if (Todos.length) {
      -        this.main.show();
      -        this.footer.show();
      -        this.footer.html(this.statsTemplate({done: done, remaining: remaining}));
      -      } else {
      -        this.main.hide();
      -        this.footer.hide();
      -      }
      -
      -      this.allCheckbox.checked = !remaining;
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      Add a single todo item to the list by creating a view for it, and -appending its element to the <ul>.

      - -
      - -
          addOne: function(todo) {
      -      var view = new TodoView({model: todo});
      -      this.$("#todo-list").append(view.render().el);
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      Add all items in the Todos collection at once.

      - -
      - -
          addAll: function() {
      -      Todos.each(this.addOne, this);
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      If you hit return in the main input field, create new Todo model, -persisting it to localStorage.

      - -
      - -
          createOnEnter: function(e) {
      -      if (e.keyCode != 13) return;
      -      if (!this.input.val()) return;
      -
      -      Todos.create({title: this.input.val()});
      -      this.input.val('');
      -    },
      - -
    • - - -
    • -
      - -
      - -
      -

      Clear all done todo items, destroying their models.

      - -
      - -
          clearCompleted: function() {
      -      _.invoke(Todos.done(), 'destroy');
      -      return false;
      -    },
      -
      -    toggleAllComplete: function () {
      -      var done = this.allCheckbox.checked;
      -      Todos.each(function (todo) { todo.save({'done': done}); });
      -    }
      -
      -  });
      - -
    • - - -
    • -
      - -
      - -
      -

      Finally, we kick things off by creating the App.

      - -
      - -
        var App = new AppView;
      -
      -});
      - -
    • - -
    -
    +

    This annotated source has moved to examples/todos/todos.html. You will be automatically redirected in two seconds.

    + diff --git a/index.html b/index.html index f747d600e3..50c4e837db 100644 --- a/index.html +++ b/index.html @@ -153,9 +153,6 @@ a img { border: 0; } - a.travis-badge { - display: block; - } h1, h2, h3, h4, h5, h6 { padding-top: 20px; } @@ -303,7 +300,7 @@