ember-data-source 1.0.0.beta.4 → 1.0.0.beta.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,18 +1,9 @@
1
1
  /*!
2
2
  * @overview Ember Data
3
- * @copyright Copyright 2011-2013 Tilde Inc. and contributors.
3
+ * @copyright Copyright 2011-2014 Tilde Inc. and contributors.
4
4
  * Portions Copyright 2011 LivingSocial Inc.
5
5
  * @license Licensed under MIT license (see license.js)
6
+ * @version 1.0.0-beta.5
6
7
  */
7
-
8
-
9
- // Version: 1.0.0-beta.4
10
-
11
- /*!
12
- * @overview Ember Data
13
- * @copyright Copyright 2011-2013 Tilde Inc. and contributors.
14
- * Portions Copyright 2011 LivingSocial Inc.
15
- * @license Licensed under MIT license (see license.js)
16
- */
17
- !function(){var e,t;!function(){var r={},i={};e=function(e,t,i){r[e]={deps:t,callback:i}},t=function(e){if(i[e])return i[e];i[e]={};var n,a,o,s,c;if(n=r[e],!n)throw new Error("Module '"+e+"' not found.");a=n.deps,o=n.callback,s=[];for(var d=0,u=a.length;u>d;d++)"exports"===a[d]?s.push(c={}):s.push(t(a[d]));var l=o.apply(this,s);return i[e]=c||l}}(),function(){var e;"undefined"==typeof e&&(e=Ember.Namespace.create({VERSION:"1.0.0-beta.4"}),"undefined"!=typeof window&&(window.DS=e),Ember.libraries&&Ember.libraries.registerCoreLibrary("Ember Data",e.VERSION))}(),function(){function e(e){return function(){return this[e].apply(this,arguments)}}var t=Ember.get,r=(Ember.set,Ember.isNone);DS.JSONSerializer=Ember.Object.extend({primaryKey:"id",applyTransforms:function(e,t){return e.eachTransformedAttribute(function(e,r){var i=this.transformFor(r);t[e]=i.deserialize(t[e])},this),t},normalize:function(e,t){return t?(this.applyTransforms(e,t),t):t},serialize:function(e,r){var i={};if(r&&r.includeId){var n=t(e,"id");n&&(i[t(this,"primaryKey")]=t(e,"id"))}return e.eachAttribute(function(t,r){this.serializeAttribute(e,i,t,r)},this),e.eachRelationship(function(t,r){"belongsTo"===r.kind?this.serializeBelongsTo(e,i,r):"hasMany"===r.kind&&this.serializeHasMany(e,i,r)},this),i},serializeAttribute:function(e,r,i,n){var a=t(this,"attrs"),o=t(e,i),s=n.type;if(s){var c=this.transformFor(s);o=c.serialize(o)}i=a&&a[i]||(this.keyForAttribute?this.keyForAttribute(i):i),r[i]=o},serializeBelongsTo:function(e,i,n){var a=n.key,o=t(e,a);a=this.keyForRelationship?this.keyForRelationship(a,"belongsTo"):a,i[a]=r(o)?o:t(o,"id"),n.options.polymorphic&&this.serializePolymorphicType(e,i,n)},serializeHasMany:function(e,r,i){var n=i.key,a=DS.RelationshipChange.determineRelationshipType(e.constructor,i);("manyToNone"===a||"manyToMany"===a)&&(r[n]=t(e,n).mapBy("id"))},serializePolymorphicType:Ember.K,extract:function(e,t,r,i,n){this.extractMeta(e,t,r);var a="extract"+n.charAt(0).toUpperCase()+n.substr(1);return this[a](e,t,r,i,n)},extractFindAll:e("extractArray"),extractFindQuery:e("extractArray"),extractFindMany:e("extractArray"),extractFindHasMany:e("extractArray"),extractCreateRecord:e("extractSave"),extractUpdateRecord:e("extractSave"),extractDeleteRecord:e("extractSave"),extractFind:e("extractSingle"),extractFindBelongsTo:e("extractSingle"),extractSave:e("extractSingle"),extractSingle:function(e,t,r){return this.normalize(t,r)},extractArray:function(e,t,r){return this.normalize(t,r)},extractMeta:function(e,t,r){r&&r.meta&&(e.metaForType(t,r.meta),delete r.meta)},transformFor:function(e){var t=this.container.lookup("transform:"+e);return t}})}(),function(){var e=Ember.get,t=Ember.String.capitalize,r=Ember.String.underscore,i=window.DS;i.DebugAdapter=Ember.DataAdapter.extend({getFilters:function(){return[{name:"isNew",desc:"New"},{name:"isModified",desc:"Modified"},{name:"isClean",desc:"Clean"}]},detect:function(e){return e!==i.Model&&i.Model.detect(e)},columnsForType:function(i){var n=[{name:"id",desc:"Id"}],a=0,o=this;return e(i,"attributes").forEach(function(e){if(a++>o.attributeLimit)return!1;var i=t(r(e).replace("_"," "));n.push({name:e,desc:i})}),n},getRecords:function(e){return this.get("store").all(e)},getRecordColumnValues:function(t){var r=this,i=0,n={id:e(t,"id")};return t.eachAttribute(function(a){if(i++>r.attributeLimit)return!1;var o=e(t,a);n[a]=o}),n},getRecordKeywords:function(t){var r=[],i=Ember.A(["id"]);return t.eachAttribute(function(e){i.push(e)}),i.forEach(function(i){r.push(e(t,i))}),r},getRecordFilterValues:function(e){return{isNew:e.get("isNew"),isModified:e.get("isDirty")&&!e.get("isNew"),isClean:!e.get("isDirty")}},getRecordColor:function(e){var t="black";return e.get("isNew")?t="green":e.get("isDirty")&&(t="blue"),t},observeRecord:function(e,t){var r=Ember.A(),i=this,n=Ember.A(["id","isNew","isDirty"]);e.eachAttribute(function(e){n.push(e)}),n.forEach(function(n){var a=function(){t(i.wrapRecord(e))};Ember.addObserver(e,n,a),r.push(function(){Ember.removeObserver(e,n,a)})});var a=function(){r.forEach(function(e){e()})};return a}})}(),function(){DS.Transform=Ember.Object.extend({serialize:Ember.required(),deserialize:Ember.required()})}(),function(){DS.BooleanTransform=DS.Transform.extend({deserialize:function(e){var t=typeof e;return"boolean"===t?e:"string"===t?null!==e.match(/^true$|^t$|^1$/i):"number"===t?1===e:!1},serialize:function(e){return Boolean(e)}})}(),function(){DS.DateTransform=DS.Transform.extend({deserialize:function(e){var t=typeof e;return"string"===t?new Date(Ember.Date.parse(e)):"number"===t?new Date(e):null===e||void 0===e?e:null},serialize:function(e){if(e instanceof Date){var t=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],r=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],i=function(e){return 10>e?"0"+e:""+e},n=e.getUTCFullYear(),a=e.getUTCMonth(),o=e.getUTCDate(),s=e.getUTCDay(),c=e.getUTCHours(),d=e.getUTCMinutes(),u=e.getUTCSeconds(),l=t[s],h=i(o),f=r[a];return l+", "+h+" "+f+" "+n+" "+i(c)+":"+i(d)+":"+i(u)+" GMT"}return null}})}(),function(){var e=Ember.isEmpty;DS.NumberTransform=DS.Transform.extend({deserialize:function(t){return e(t)?null:Number(t)},serialize:function(t){return e(t)?null:Number(t)}})}(),function(){var e=Ember.isNone;DS.StringTransform=DS.Transform.extend({deserialize:function(t){return e(t)?null:String(t)},serialize:function(t){return e(t)?null:String(t)}})}(),function(){Ember.set;Ember.onLoad("Ember.Application",function(e){e.initializer({name:"store",initialize:function(e,t){t.register("store:main",t.Store||DS.Store),t.register("serializer:_default",DS.JSONSerializer),t.register("serializer:_rest",DS.RESTSerializer),t.register("adapter:_rest",DS.RESTAdapter),e.lookup("store:main")}}),e.initializer({name:"transforms",before:"store",initialize:function(e,t){t.register("transform:boolean",DS.BooleanTransform),t.register("transform:date",DS.DateTransform),t.register("transform:number",DS.NumberTransform),t.register("transform:string",DS.StringTransform)}}),e.initializer({name:"dataAdapter",before:"store",initialize:function(e,t){t.register("dataAdapter:main",DS.DebugAdapter)}}),e.initializer({name:"injectStore",before:"store",initialize:function(e,t){t.inject("controller","store","store:main"),t.inject("route","store","store:main"),t.inject("serializer","store","store:main"),t.inject("dataAdapter","store","store:main")}})})}(),function(){Ember.Date=Ember.Date||{};var e=Date.parse,t=[1,4,5,6,7,10,11];Ember.Date.parse=function(r){var i,n,a=0;if(n=/^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(r)){for(var o,s=0;o=t[s];++s)n[o]=+n[o]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,"Z"!==n[8]&&void 0!==n[9]&&(a=60*n[10]+n[11],"+"===n[9]&&(a=0-a)),i=Date.UTC(n[1],n[2],n[3],n[4],n[5]+a,n[6],n[7])}else i=e?e(r):0/0;return i},(Ember.EXTEND_PROTOTYPES===!0||Ember.EXTEND_PROTOTYPES.Date)&&(Date.parse=Ember.Date.parse)}(),function(){{var e=Ember.get;Ember.set}DS.RecordArray=Ember.ArrayProxy.extend(Ember.Evented,{type:null,content:null,isLoaded:!1,isUpdating:!1,store:null,objectAtContent:function(t){var r=e(this,"content");return r.objectAt(t)},update:function(){if(!e(this,"isUpdating")){var t=e(this,"store"),r=e(this,"type");t.fetchAll(r,this)}},addRecord:function(t){e(this,"content").addObject(t)},removeRecord:function(t){e(this,"content").removeObject(t)},save:function(){var t="DS: RecordArray#save "+e(this,"type"),r=Ember.RSVP.all(this.invoke("save"),t).then(function(e){return Ember.A(e)},null,"DS: RecordArray#save apply Ember.NativeArray");return DS.PromiseArray.create({promise:r})}})}(),function(){var e=Ember.get;DS.FilteredRecordArray=DS.RecordArray.extend({filterFunction:null,isLoaded:!0,replace:function(){var t=e(this,"type").toString();throw new Error("The result of a client-side filter (on "+t+") is immutable.")},updateFilter:Ember.observer(function(){var t=e(this,"manager");t.updateFilter(this,e(this,"type"),e(this,"filterFunction"))},"filterFunction")})}(),function(){{var e=Ember.get;Ember.set}DS.AdapterPopulatedRecordArray=DS.RecordArray.extend({query:null,replace:function(){var t=e(this,"type").toString();throw new Error("The result of a server query (on "+t+") is immutable.")},load:function(t){var r=e(this,"store"),i=e(this,"type"),n=r.pushMany(i,t),a=r.metadataFor(i);this.setProperties({content:Ember.A(n),isLoaded:!0,meta:a}),Ember.run.once(this,"trigger","didLoad")}})}(),function(){var e=Ember.get,t=Ember.set,r=Ember.EnumerableUtils.map;DS.ManyArray=DS.RecordArray.extend({init:function(){this._super.apply(this,arguments),this._changesToSync=Ember.OrderedSet.create()},name:null,owner:null,isPolymorphic:!1,isLoaded:!1,promise:null,loadingRecordsCount:function(e){this.loadingRecordsCount=e},loadedRecord:function(){this.loadingRecordsCount--,0===this.loadingRecordsCount&&(t(this,"isLoaded",!0),this.trigger("didLoad"))},fetch:function(){var t=e(this,"content"),r=e(this,"store"),i=e(this,"owner"),n=Ember.RSVP.defer("DS: ManyArray#fetch "+e(this,"type")),a=t.filterProperty("isEmpty",!0);r.fetchMany(a,i,n)},replaceContent:function(e,t,i){i=r(i,function(e){return e},this),this._super(e,t,i)},arrangedContentDidChange:function(){Ember.run.once(this,"fetch")},arrayContentWillChange:function(t,r){var i=e(this,"owner"),n=e(this,"name");if(!i._suspendedRelationships)for(var a=t;t+r>a;a++){var o=e(this,"content").objectAt(a),s=DS.RelationshipChange.createChange(i,o,e(this,"store"),{parentType:i.constructor,changeType:"remove",kind:"hasMany",key:n});this._changesToSync.add(s)}return this._super.apply(this,arguments)},arrayContentDidChange:function(t,r,i){this._super.apply(this,arguments);var n=e(this,"owner"),a=e(this,"name"),o=e(this,"store");if(!n._suspendedRelationships){for(var s=t;t+i>s;s++){var c=e(this,"content").objectAt(s),d=DS.RelationshipChange.createChange(n,c,o,{parentType:n.constructor,changeType:"add",kind:"hasMany",key:a});d.hasManyName=a,this._changesToSync.add(d)}this._changesToSync.forEach(function(e){e.sync()}),this._changesToSync.clear()}},createRecord:function(t){var r,i=e(this,"owner"),n=e(i,"store"),a=e(this,"type");return r=n.createRecord.call(n,a,t),this.pushObject(r),r}})}(),function(){function e(e,r,a,o){return r.eachRelationship(function(r,s){if(a.links&&a.links[r])return o&&s.options.async&&(o._relationships[r]=null),void 0;var c=s.kind,d=a[r];null!=d&&("belongsTo"===c?t(e,a,r,s,d):"hasMany"===c&&(i(e,a,r,s,d),n(o,r,d)))}),a}function t(e,t,i,n,a){if(!(R(a)||a instanceof DS.Model)){var o;"number"==typeof a||"string"==typeof a?(o=r(n,i,t),t[i]=e.recordForId(o,a)):"object"==typeof a&&(t[i]=e.recordForId(a.type,a.id))}}function r(e,t,r){return e.options.polymorphic?r[t+"Type"]:e.type}function i(e,r,i,n,a){for(var o=0,s=a.length;s>o;o++)t(e,a,o,n,a[o])}function n(e,t,r){e&&r.pushObjects(e.get(t).filterBy("isNew"))}function a(e){return DS.PromiseObject.create({promise:e})}function o(e){return DS.PromiseArray.create({promise:e})}function s(e,t,r){return e.lookup("serializer:"+t)||e.lookup("serializer:application")||e.lookup("serializer:"+r)||e.lookup("serializer:_default")}function c(e){return e.lookup("serializer:application")||e.lookup("serializer:_default")}function d(e,t){var r=e.serializer,i=e.defaultSerializer,n=e.container;return n&&void 0===r&&(r=s(n,t.typeKey,i)),(null===r||void 0===r)&&(r={extract:function(e,t,r){return r}}),r}function u(e,t,r,i){var n=e.find(t,r,i),a=d(e,r);return T(n,"DS: Handle Adapter#find of "+r+" with id: "+i).then(function(e){return e=a.extract(t,r,e,i,"find"),t.push(r,e)},function(e){var n=t.getById(r,i);throw n.notFound(),e},"DS: Extract payload of '"+r+"'")}function l(e,t,r,i,n){var a=e.findMany(t,r,i,n),o=d(e,r);return T(a,"DS: Handle Adapter#findMany of "+r).then(function(e){e=o.extract(t,r,e,null,"findMany"),t.pushMany(r,e)},null,"DS: Extract payload of "+r)}function h(e,t,r,i,n){var a=e.findHasMany(t,r,i,n),o=d(e,n.type);return T(a,"DS: Handle Adapter#findHasMany of "+r+" : "+n.type).then(function(e){e=o.extract(t,n.type,e,null,"findHasMany");var i=t.pushMany(n.type,e);r.updateHasMany(n.key,i)},null,"DS: Extract payload of "+r+" : hasMany "+n.type)}function f(e,t,r,i,n){var a=e.findBelongsTo(t,r,i,n),o=d(e,n.type);return T(a,"DS: Handle Adapter#findBelongsTo of "+r+" : "+n.type).then(function(e){e=o.extract(t,n.type,e,null,"findBelongsTo");var r=t.push(n.type,e);return r.updateBelongsTo(n.key,r),r},null,"DS: Extract payload of "+r+" : "+n.type)}function p(e,t,r,i){var n=e.findAll(t,r,i),a=d(e,r);return T(n,"DS: Handle Adapter#findAll of "+r).then(function(e){return e=a.extract(t,r,e,null,"findAll"),t.pushMany(r,e),t.didUpdateAll(r),t.all(r)},null,"DS: Extract payload of findAll "+r)}function m(e,t,r,i,n){var a=e.findQuery(t,r,i,n),o=d(e,r);return T(a,"DS: Handle Adapter#findQuery of "+r).then(function(e){return e=o.extract(t,r,e,null,"findAll"),n.load(e),n},null,"DS: Extract payload of findQuery "+r)}function y(e,t,r,i){var n=i.constructor,a=e[r](t,n,i),o=d(e,n);return a.then(function(e){return e&&(e=o.extract(t,n,e,g(i,"id"),r)),t.didSaveRecord(i,e),i},function(e){throw e instanceof DS.InvalidError?t.recordWasInvalid(i,e.errors):t.recordWasError(i,e),e},"DS: Extract and notify about "+r+" completion of "+i)}var g=Ember.get,b=Ember.set,v=Ember.run.once,R=Ember.isNone,E=Ember.EnumerableUtils.forEach,S=Ember.EnumerableUtils.indexOf,D=Ember.EnumerableUtils.map,T=Ember.RSVP.resolve,A=Ember.copy,F=function(e){return null==e?null:e+""};DS.Store=Ember.Object.extend({init:function(){this.typeMaps={},this.recordArrayManager=DS.RecordArrayManager.create({store:this}),this._relationshipChanges={},this._pendingSave=[]},adapter:"_rest",serialize:function(e,t){return this.serializerFor(e.constructor.typeKey).serialize(e,t)},defaultAdapter:Ember.computed("adapter",function(){var e=g(this,"adapter");return"string"==typeof e&&(e=this.container.lookup("adapter:"+e)||this.container.lookup("adapter:application")||this.container.lookup("adapter:_rest")),DS.Adapter.detect(e)&&(e=e.create({container:this.container})),e}),createRecord:function(e,t){e=this.modelFor(e),t=A(t)||{},R(t.id)&&(t.id=this._generateId(e)),t.id=F(t.id);var r=this.buildRecord(e,t.id);return r.loadedData(),r.setProperties(t),r},_generateId:function(e){var t=this.adapterFor(e);return t&&t.generateIdForRecord?t.generateIdForRecord(this):null},deleteRecord:function(e){e.deleteRecord()},unloadRecord:function(e){e.unloadRecord()},find:function(e,t){return void 0===t?this.findAll(e):"object"===Ember.typeOf(t)?this.findQuery(e,t):this.findById(e,F(t))},findById:function(e,t){e=this.modelFor(e);var r=this.recordForId(e,t),i=this.fetchRecord(r)||T(r,"DS: Store#findById "+e+" with id: "+t);return a(i)},findByIds:function(e,t){var r=this;return o(Ember.RSVP.all(D(t,function(t){return r.findById(e,t)})).then(Ember.A,null,"DS: Store#findByIds of "+e+" complete"))},fetchRecord:function(e){if(R(e))return null;if(e._loadingPromise)return e._loadingPromise;if(!g(e,"isEmpty"))return null;var t=e.constructor,r=g(e,"id"),i=Ember.RSVP.defer("DS: Store#fetchRecord "+e);e.loadingData(i.promise);var n=this.adapterFor(t);return i.resolve(u(n,this,t,r)),i.promise},getById:function(e,t){return this.hasRecordForId(e,t)?this.recordForId(e,t):null},reloadRecord:function(e){var t=e.constructor,r=this.adapterFor(t),i=g(e,"id");return u(r,this,t,i)},fetchMany:function(e,t,r){if(e.length){var i=Ember.MapWithDefault.create({defaultValue:function(){return Ember.A()}});E(e,function(e){i.get(e.constructor).push(e)}),E(i,function(e,i){var n=i.mapProperty("id"),a=this.adapterFor(e);r.resolve(l(a,this,e,n,t))},this)}},hasRecordForId:function(e,t){return t=F(t),e=this.modelFor(e),!!this.typeMapFor(e).idToRecord[t]},recordForId:function(e,t){e=this.modelFor(e),t=F(t);var r=this.typeMapFor(e).idToRecord[t];return r||(r=this.buildRecord(e,t)),r},findMany:function(e,t,r,i){r=this.modelFor(r),t=Ember.A(t);var n=t.filterProperty("isEmpty",!0),a=this.recordArrayManager.createManyArray(r,t);return E(n,function(e){e.loadingData()}),a.loadingRecordsCount=n.length,n.length?(E(n,function(e){this.recordArrayManager.registerWaitingRecordArray(e,a)},this),this.fetchMany(n,e,i)):(i&&i.resolve(),a.set("isLoaded",!0),Ember.run.once(a,"trigger","didLoad")),a},findHasMany:function(e,t,r,i){var n=this.adapterFor(e.constructor),a=this.recordArrayManager.createManyArray(r.type,Ember.A([]));return i.resolve(h(n,this,e,t,r)),a},findBelongsTo:function(e,t,r,i){var n=this.adapterFor(e.constructor);i.resolve(f(n,this,e,t,r))},findQuery:function(e,t){e=this.modelFor(e);var r=DS.AdapterPopulatedRecordArray.create({type:e,query:t,content:Ember.A(),store:this}),i=this.adapterFor(e),n="DS: Store#findQuery "+e,a=Ember.RSVP.defer(n);return a.resolve(m(i,this,e,t,r)),o(a.promise)},findAll:function(e){return e=this.modelFor(e),this.fetchAll(e,this.all(e))},fetchAll:function(e,t){var r=this.adapterFor(e),i=this.typeMapFor(e).metadata.since,n=Ember.RSVP.defer("DS: Store#findAll "+e);return b(t,"isUpdating",!0),n.resolve(p(r,this,e,i)),o(n.promise)},didUpdateAll:function(e){var t=this.typeMapFor(e).findAllCache;b(t,"isUpdating",!1)},all:function(e){e=this.modelFor(e);var t=this.typeMapFor(e),r=t.findAllCache;if(r)return r;var i=DS.RecordArray.create({type:e,content:Ember.A(),store:this,isLoaded:!0});return this.recordArrayManager.registerFilteredRecordArray(i,e),t.findAllCache=i,i},unloadAll:function(e){e=this.modelFor(e);for(var t,r=this.typeMapFor(e),i=r.records;t=i.pop();)t.unloadRecord();r.findAllCache=null},filter:function(e,t,r){var i;3===arguments.length?i=this.findQuery(e,t):2===arguments.length&&(r=t),e=this.modelFor(e);var n=DS.FilteredRecordArray.create({type:e,content:Ember.A(),store:this,manager:this.recordArrayManager,filterFunction:r});return this.recordArrayManager.registerFilteredRecordArray(n,e,r),i?i.then(function(){return n},null,"DS: Store#filter of "+e):n},recordIsLoaded:function(e,t){return this.hasRecordForId(e,t)?!g(this.recordForId(e,t),"isEmpty"):!1},metadataFor:function(e){return e=this.modelFor(e),this.typeMapFor(e).metadata},dataWasUpdated:function(e,t){this.recordArrayManager.recordDidChange(t)},scheduleSave:function(e,t){e.adapterWillCommit(),this._pendingSave.push([e,t]),v(this,"flushPendingSave")},flushPendingSave:function(){var e=this._pendingSave.slice();this._pendingSave=[],E(e,function(e){var t,r=e[0],i=e[1],n=this.adapterFor(r.constructor);t=g(r,"isNew")?"createRecord":g(r,"isDeleted")?"deleteRecord":"updateRecord",i.resolve(y(n,this,t,r))},this)},didSaveRecord:function(t,r){r&&(r=e(this,t.constructor,r,t),this.updateId(t,r)),t.adapterDidCommit(r)},recordWasInvalid:function(e,t){e.adapterDidInvalidate(t)},recordWasError:function(e){e.adapterDidError()},updateId:function(e,t){var r=(g(e,"id"),F(t.id));this.typeMapFor(e.constructor).idToRecord[r]=e,b(e,"id",r)},typeMapFor:function(e){var t,r=g(this,"typeMaps"),i=Ember.guidFor(e);return(t=r[i])?t:(t={idToRecord:{},records:[],metadata:{}},r[i]=t,t)},_load:function(e,t,r){var i=F(t.id),n=this.recordForId(e,i);return n.setupData(t,r),this.recordArrayManager.recordDidChange(n),n},modelFor:function(e){var t;if("string"==typeof e){if(t=this.container.lookupFactory("model:"+e),!t)throw new Ember.Error("No model was found for '"+e+"'");t.typeKey=e}else t=e;return t.store=this,t},push:function(t,r,i){return t=this.modelFor(t),r=e(this,t,r),this._load(t,r,i),this.recordForId(t,r.id)},pushPayload:function(e,t){var r;t?r=this.serializerFor(e):(t=e,r=c(this.container)),r.pushPayload(this,t)},update:function(e,t){return this.push(e,t,!0)},pushMany:function(e,t){return D(t,function(t){return this.push(e,t)},this)},metaForType:function(e,t){e=this.modelFor(e),Ember.merge(this.typeMapFor(e).metadata,t)},buildRecord:function(e,t,r){var i=this.typeMapFor(e),n=i.idToRecord,a=e._create({id:t,store:this,container:this.container});return r&&a.setupData(r),t&&(n[t]=a),i.records.push(a),a},dematerializeRecord:function(e){var t=e.constructor,r=this.typeMapFor(t),i=g(e,"id");e.updateRecordArrays(),i&&delete r.idToRecord[i];var n=S(r.records,e);r.records.splice(n,1)},addRelationshipChangeFor:function(e,t,r,i,n){var a=e.clientId,o=r?r:r,s=t+i,c=this._relationshipChanges;a in c||(c[a]={}),o in c[a]||(c[a][o]={}),s in c[a][o]||(c[a][o][s]={}),c[a][o][s][n.changeType]=n},removeRelationshipChangeFor:function(e,t,r,i,n){var a=e.clientId,o=r?r.clientId:r,s=this._relationshipChanges,c=t+i;a in s&&o in s[a]&&c in s[a][o]&&delete s[a][o][c][n]},relationshipChangePairsFor:function(e){var t=[];if(!e)return t;var r=this._relationshipChanges[e.clientId];for(var i in r)if(r.hasOwnProperty(i))for(var n in r[i])r[i].hasOwnProperty(n)&&t.push(r[i][n]);return t},adapterFor:function(e){var t,r=this.container;return r&&(t=r.lookup("adapter:"+e.typeKey)||r.lookup("adapter:application")),t||g(this,"defaultAdapter")},serializerFor:function(e){e=this.modelFor(e);var t=this.adapterFor(e);return s(this.container,e.typeKey,t&&t.defaultSerializer)}}),DS.PromiseArray=Ember.ArrayProxy.extend(Ember.PromiseProxyMixin),DS.PromiseObject=Ember.ObjectProxy.extend(Ember.PromiseProxyMixin)}(),function(){function e(t){var r,i={};for(var n in t)r=t[n],i[n]=r&&"object"==typeof r?e(r):r;return i}function t(e,t){for(var r in t)e[r]=t[r];return e}function r(r){var i=e(c);return t(i,r)}function i(e,r,n){e=t(r?Ember.create(r):{},e),e.parentState=r,e.stateName=n;for(var a in e)e.hasOwnProperty(a)&&"parentState"!==a&&"stateName"!==a&&"object"==typeof e[a]&&(e[a]=i(e[a],e,n+"."+a));return e}var n=Ember.get,a=Ember.set,o=function(e){var t,r,i,n=Ember.keys(e);for(t=0,r=n.length;r>t;t++)if(i=n[t],e.hasOwnProperty(i)&&e[i])return!0;return!1},s=function(e,t){t.value===t.originalValue?(delete e._attributes[t.name],e.send("propertyWasReset",t.name)):t.value!==t.oldValue&&e.send("becomeDirty"),e.updateRecordArraysLater()},c={initialState:"uncommitted",isDirty:!0,uncommitted:{didSetProperty:s,propertyWasReset:function(e){var t=!1;for(var r in e._attributes){t=!0;break}t||e.send("rolledBack")},pushedData:Ember.K,becomeDirty:Ember.K,willCommit:function(e){e.transitionTo("inFlight")},reloadRecord:function(e,t){t(n(e,"store").reloadRecord(e))},rolledBack:function(e){e.transitionTo("loaded.saved")},becameInvalid:function(e){e.transitionTo("invalid")},rollback:function(e){e.rollback()}},inFlight:{isSaving:!0,didSetProperty:s,becomeDirty:Ember.K,pushedData:Ember.K,willCommit:Ember.K,didCommit:function(e){var t=n(this,"dirtyType");e.transitionTo("saved"),e.send("invokeLifecycleCallbacks",t)},becameInvalid:function(e,t){a(e,"errors",t),e.transitionTo("invalid"),e.send("invokeLifecycleCallbacks")},becameError:function(e){e.transitionTo("uncommitted"),e.triggerLater("becameError",e)}},invalid:{isValid:!1,deleteRecord:function(e){e.transitionTo("deleted.uncommitted"),e.clearRelationships()},didSetProperty:function(e,t){var r=n(e,"errors"),i=t.name;a(r,i,null),o(r)||e.send("becameValid"),s(e,t)},becomeDirty:Ember.K,rollback:function(e){e.send("becameValid"),e.send("rollback")},becameValid:function(e){e.transitionTo("uncommitted")},invokeLifecycleCallbacks:function(e){e.triggerLater("becameInvalid",e)}}},d=r({dirtyType:"created",isNew:!0});d.uncommitted.rolledBack=function(e){e.transitionTo("deleted.saved")};var u=r({dirtyType:"updated"});d.uncommitted.deleteRecord=function(e){e.clearRelationships(),e.transitionTo("deleted.saved")},d.uncommitted.rollback=function(e){c.uncommitted.rollback.apply(this,arguments),e.transitionTo("deleted.saved")},u.uncommitted.deleteRecord=function(e){e.transitionTo("deleted.uncommitted"),e.clearRelationships()};var l={isEmpty:!1,isLoading:!1,isLoaded:!1,isDirty:!1,isSaving:!1,isDeleted:!1,isNew:!1,isValid:!0,rolledBack:Ember.K,propertyWasReset:Ember.K,empty:{isEmpty:!0,loadingData:function(e,t){e._loadingPromise=t,e.transitionTo("loading")},loadedData:function(e){e.transitionTo("loaded.created.uncommitted"),e.suspendRelationshipObservers(function(){e.notifyPropertyChange("data")})},pushedData:function(e){e.transitionTo("loaded.saved"),e.triggerLater("didLoad")}},loading:{isLoading:!0,exit:function(e){e._loadingPromise=null},pushedData:function(e){e.transitionTo("loaded.saved"),e.triggerLater("didLoad"),a(e,"isError",!1)},becameError:function(e){e.triggerLater("becameError",e)},notFound:function(e){e.transitionTo("empty")}},loaded:{initialState:"saved",isLoaded:!0,saved:{setup:function(e){var t=e._attributes,r=!1;for(var i in t)if(t.hasOwnProperty(i)){r=!0;break}r&&e.adapterDidDirty()},didSetProperty:s,pushedData:Ember.K,becomeDirty:function(e){e.transitionTo("updated.uncommitted")},willCommit:function(e){e.transitionTo("updated.inFlight")},reloadRecord:function(e,t){t(n(e,"store").reloadRecord(e))},deleteRecord:function(e){e.transitionTo("deleted.uncommitted"),e.clearRelationships()},unloadRecord:function(e){e.clearRelationships(),e.transitionTo("deleted.saved")},didCommit:function(e){e.send("invokeLifecycleCallbacks",n(e,"lastDirtyType"))},notFound:Ember.K},created:d,updated:u},deleted:{initialState:"uncommitted",dirtyType:"deleted",isDeleted:!0,isLoaded:!0,isDirty:!0,setup:function(e){e.updateRecordArrays()},uncommitted:{willCommit:function(e){e.transitionTo("inFlight")},rollback:function(e){e.rollback()},becomeDirty:Ember.K,deleteRecord:Ember.K,rolledBack:function(e){e.transitionTo("loaded.saved")}},inFlight:{isSaving:!0,willCommit:Ember.K,didCommit:function(e){e.transitionTo("saved"),e.send("invokeLifecycleCallbacks")},becameError:function(e){e.transitionTo("uncommitted"),e.triggerLater("becameError",e)}},saved:{isDirty:!1,setup:function(e){var t=n(e,"store");t.dematerializeRecord(e)},invokeLifecycleCallbacks:function(e){e.triggerLater("didDelete",e),e.triggerLater("didCommit",e)}}},invokeLifecycleCallbacks:function(e,t){"created"===t?e.triggerLater("didCreate",e):e.triggerLater("didUpdate",e),e.triggerLater("didCommit",e)}};l=i(l,null,"root"),DS.RootState=l}(),function(){var e=Ember.get,t=Ember.set,r=Ember.merge,i=Ember.run.once,n=Ember.computed("currentState",function(t){return e(e(this,"currentState"),t)}).readOnly();DS.Model=Ember.Object.extend(Ember.Evented,{isEmpty:n,isLoading:n,isLoaded:n,isDirty:n,isSaving:n,isDeleted:n,isNew:n,isValid:n,dirtyType:n,isError:!1,isReloading:!1,clientId:null,id:null,transaction:null,currentState:null,errors:null,serialize:function(t){var r=e(this,"store");return r.serialize(this,t)},toJSON:function(e){var t=DS.JSONSerializer.create({container:this.container});return t.serialize(this,e)},didLoad:Ember.K,didUpdate:Ember.K,didCreate:Ember.K,didDelete:Ember.K,becameInvalid:Ember.K,becameError:Ember.K,data:Ember.computed(function(){return this._data=this._data||{},this._data}).property(),_data:null,init:function(){t(this,"currentState",DS.RootState.empty),this._super(),this._setup()},_setup:function(){this._changesToSync={},this._deferredTriggers=[],this._data={},this._attributes={},this._inFlightAttributes={},this._relationships={}},send:function(t,r){var i=e(this,"currentState");return i[t]||this._unhandledEvent(i,t,r),i[t](this,r)},transitionTo:function(r){var i=r.split(".",1),n=e(this,"currentState"),a=n;do a.exit&&a.exit(this),a=a.parentState;while(!a.hasOwnProperty(i));var o,s,c=r.split("."),d=[],u=[];for(o=0,s=c.length;s>o;o++)a=a[c[o]],a.enter&&u.push(a),a.setup&&d.push(a);for(o=0,s=u.length;s>o;o++)u[o].enter(this);for(t(this,"currentState",a),o=0,s=d.length;s>o;o++)d[o].setup(this);this.updateRecordArraysLater()},_unhandledEvent:function(e,t,r){var i="Attempted to handle event `"+t+"` ";throw i+="on "+String(this)+" while in state ",i+=e.stateName+". ",void 0!==r&&(i+="Called with "+Ember.inspect(r)+"."),new Ember.Error(i)},withTransaction:function(t){var r=e(this,"transaction");r&&t(r)},loadingData:function(e){this.send("loadingData",e)},loadedData:function(){this.send("loadedData")},notFound:function(){this.send("notFound")},pushedData:function(){this.send("pushedData")},deleteRecord:function(){this.send("deleteRecord")},destroyRecord:function(){return this.deleteRecord(),this.save()},unloadRecord:function(){this.send("unloadRecord")},clearRelationships:function(){this.eachRelationship(function(e,r){if("belongsTo"===r.kind)t(this,e,null);else if("hasMany"===r.kind){var i=this._relationships[r.name];i&&i.clear()}},this)},updateRecordArrays:function(){e(this,"store").dataWasUpdated(this.constructor,this)},changedAttributes:function(){var t,r=e(this,"_data"),i=e(this,"_attributes"),n={};for(t in i)n[t]=[r[t],i[t]];return n},adapterWillCommit:function(){this.send("willCommit")},adapterDidCommit:function(e){t(this,"isError",!1),e?this._data=e:Ember.mixin(this._data,this._inFlightAttributes),this._inFlightAttributes={},this.send("didCommit"),this.updateRecordArraysLater(),e&&this.suspendRelationshipObservers(function(){this.notifyPropertyChange("data")})},adapterDidDirty:function(){this.send("becomeDirty"),this.updateRecordArraysLater()},dataDidChange:Ember.observer(function(){this.reloadHasManys()},"data"),reloadHasManys:function(){var t=e(this.constructor,"relationshipsByName");this.updateRecordArraysLater(),t.forEach(function(e,t){this._data.links&&this._data.links[e]||"hasMany"===t.kind&&this.hasManyDidChange(t.key)},this)},hasManyDidChange:function(e){var r=this._relationships[e];if(r){var i=this._data[e]||[];t(r,"content",Ember.A(i)),t(r,"isLoaded",!0),r.trigger("didLoad")}},updateRecordArraysLater:function(){Ember.run.once(this,this.updateRecordArrays)},setupData:function(e,t){t?Ember.merge(this._data,e):this._data=e;var r=this._relationships;this.eachRelationship(function(t,i){e.links&&e.links[t]||i.options.async&&(r[t]=null)}),e&&this.pushedData(),this.suspendRelationshipObservers(function(){this.notifyPropertyChange("data")})},materializeId:function(e){t(this,"id",e)},materializeAttributes:function(e){r(this._data,e)},materializeAttribute:function(e,t){this._data[e]=t},updateHasMany:function(e,t){this._data[e]=t,this.hasManyDidChange(e)},updateBelongsTo:function(e,t){this._data[e]=t},rollback:function(){this._attributes={},e(this,"isError")&&(this._inFlightAttributes={},t(this,"isError",!1)),e(this,"isValid")||(this._inFlightAttributes={},this.send("becameValid")),this.send("rolledBack"),this.suspendRelationshipObservers(function(){this.notifyPropertyChange("data")})},toStringExtension:function(){return e(this,"id")},suspendRelationshipObservers:function(t,r){var i=e(this.constructor,"relationshipNames").belongsTo,n=this;try{this._suspendedRelationships=!0,Ember._suspendObservers(n,i,null,"belongsToDidChange",function(){Ember._suspendBeforeObservers(n,i,null,"belongsToWillChange",function(){t.call(r||n)})})}finally{this._suspendedRelationships=!1}},save:function(){var e="DS: Model#save "+this,t=Ember.RSVP.defer(e);return this.get("store").scheduleSave(this,t),this._inFlightAttributes=this._attributes,this._attributes={},DS.PromiseObject.create({promise:t.promise})},reload:function(){t(this,"isReloading",!0);var e=this,r="DS: Model#reload of "+this,i=new Ember.RSVP.Promise(function(t){e.send("reloadRecord",t)},r).then(function(){return e.set("isReloading",!1),e.set("isError",!1),e},function(t){throw e.set("isError",!0),t},"DS: Model#reload complete, update flags");return DS.PromiseObject.create({promise:i})},adapterDidUpdateAttribute:function(e,t){void 0!==t?(this._data[e]=t,this.notifyPropertyChange(e)):this._data[e]=this._inFlightAttributes[e],this.updateRecordArraysLater()},adapterDidInvalidate:function(e){this.send("becameInvalid",e)},adapterDidError:function(){this.send("becameError"),t(this,"isError",!0)},trigger:function(e){Ember.tryInvoke(this,e,[].slice.call(arguments,1)),this._super.apply(this,arguments)},triggerLater:function(){this._deferredTriggers.push(arguments),i(this,"_triggerDeferredTriggers")},_triggerDeferredTriggers:function(){for(var e=0,t=this._deferredTriggers.length;t>e;e++)this.trigger.apply(this,this._deferredTriggers[e]);this._deferredTriggers=[]}}),DS.Model.reopenClass({_create:DS.Model.create,create:function(){throw new Ember.Error("You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.")}})}(),function(){function e(e,t){return"function"==typeof t.defaultValue?t.defaultValue():t.defaultValue}function t(e,t){return e._attributes.hasOwnProperty(t)||e._inFlightAttributes.hasOwnProperty(t)||e._data.hasOwnProperty(t)}function r(e,t){return e._attributes.hasOwnProperty(t)?e._attributes[t]:e._inFlightAttributes.hasOwnProperty(t)?e._inFlightAttributes[t]:e._data[t]}var i=Ember.get;DS.Model.reopenClass({attributes:Ember.computed(function(){var e=Ember.Map.create();return this.eachComputedProperty(function(t,r){r.isAttribute&&(r.name=t,e.set(t,r))}),e}),transformedAttributes:Ember.computed(function(){var e=Ember.Map.create();return this.eachAttribute(function(t,r){r.type&&e.set(t,r.type)}),e}),eachAttribute:function(e,t){i(this,"attributes").forEach(function(r,i){e.call(t,r,i)
18
- },t)},eachTransformedAttribute:function(e,t){i(this,"transformedAttributes").forEach(function(r,i){e.call(t,r,i)})}}),DS.Model.reopen({eachAttribute:function(e,t){this.constructor.eachAttribute(e,t)}}),DS.attr=function(i,n){n=n||{};var a={type:i,isAttribute:!0,options:n};return Ember.computed(function(i,a){if(arguments.length>1){var o=this._attributes[i]||this._inFlightAttributes[i]||this._data[i];return this.send("didSetProperty",{name:i,oldValue:o,originalValue:this._data[i],value:a}),this._attributes[i]=a,a}return t(this,i)?r(this,i):e(this,n,i)}).property("data").meta(a)}}(),function(){var e=DS.AttributeChange=function(e){this.record=e.record,this.store=e.store,this.name=e.name,this.value=e.value,this.oldValue=e.oldValue};e.createChange=function(t){return new e(t)},e.prototype={sync:function(){this.value!==this.oldValue&&(this.record.send("becomeDirty"),this.record.updateRecordArraysLater()),this.destroy()},destroy:function(){delete this.record._changesToSync[this.name]}}}(),function(){function e(e){return"object"==typeof e&&(!e.then||"function"!=typeof e.then)}var t=Ember.get,r=Ember.set,i=Ember.EnumerableUtils.forEach;DS.RelationshipChange=function(e){this.parentRecord=e.parentRecord,this.childRecord=e.childRecord,this.firstRecord=e.firstRecord,this.firstRecordKind=e.firstRecordKind,this.firstRecordName=e.firstRecordName,this.secondRecord=e.secondRecord,this.secondRecordKind=e.secondRecordKind,this.secondRecordName=e.secondRecordName,this.changeType=e.changeType,this.store=e.store,this.committed={}},DS.RelationshipChangeAdd=function(e){DS.RelationshipChange.call(this,e)},DS.RelationshipChangeRemove=function(e){DS.RelationshipChange.call(this,e)},DS.RelationshipChange.create=function(e){return new DS.RelationshipChange(e)},DS.RelationshipChangeAdd.create=function(e){return new DS.RelationshipChangeAdd(e)},DS.RelationshipChangeRemove.create=function(e){return new DS.RelationshipChangeRemove(e)},DS.OneToManyChange={},DS.OneToNoneChange={},DS.ManyToNoneChange={},DS.OneToOneChange={},DS.ManyToManyChange={},DS.RelationshipChange._createChange=function(e){return"add"===e.changeType?DS.RelationshipChangeAdd.create(e):"remove"===e.changeType?DS.RelationshipChangeRemove.create(e):void 0},DS.RelationshipChange.determineRelationshipType=function(e,t){var r,i,n=t.key,a=t.kind,o=e.inverseFor(n);return o&&(r=o.name,i=o.kind),o?"belongsTo"===i?"belongsTo"===a?"oneToOne":"manyToOne":"belongsTo"===a?"oneToMany":"manyToMany":"belongsTo"===a?"oneToNone":"manyToNone"},DS.RelationshipChange.createChange=function(e,t,r,i){var n,a=e.constructor;return n=DS.RelationshipChange.determineRelationshipType(a,i),"oneToMany"===n?DS.OneToManyChange.createChange(e,t,r,i):"manyToOne"===n?DS.OneToManyChange.createChange(t,e,r,i):"oneToNone"===n?DS.OneToNoneChange.createChange(e,t,r,i):"manyToNone"===n?DS.ManyToNoneChange.createChange(e,t,r,i):"oneToOne"===n?DS.OneToOneChange.createChange(e,t,r,i):"manyToMany"===n?DS.ManyToManyChange.createChange(e,t,r,i):void 0},DS.OneToNoneChange.createChange=function(e,t,r,i){var n=i.key,a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,store:r,changeType:i.changeType,firstRecordName:n,firstRecordKind:"belongsTo"});return r.addRelationshipChangeFor(e,n,t,null,a),a},DS.ManyToNoneChange.createChange=function(e,t,r,i){var n=i.key,a=DS.RelationshipChange._createChange({parentRecord:e,childRecord:t,secondRecord:e,store:r,changeType:i.changeType,secondRecordName:i.key,secondRecordKind:"hasMany"});return r.addRelationshipChangeFor(e,n,t,null,a),a},DS.ManyToManyChange.createChange=function(e,t,r,i){var n=i.key,a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,secondRecord:t,firstRecordKind:"hasMany",secondRecordKind:"hasMany",store:r,changeType:i.changeType,firstRecordName:n});return r.addRelationshipChangeFor(e,n,t,null,a),a},DS.OneToOneChange.createChange=function(e,t,r,i){var n;i.parentType?n=i.parentType.inverseFor(i.key).name:i.key&&(n=i.key);var a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,secondRecord:t,firstRecordKind:"belongsTo",secondRecordKind:"belongsTo",store:r,changeType:i.changeType,firstRecordName:n});return r.addRelationshipChangeFor(e,n,t,null,a),a},DS.OneToOneChange.maintainInvariant=function(e,r,i,n){if("add"===e.changeType&&r.recordIsMaterialized(i)){var a=t(i,n);if(a){var o=DS.OneToOneChange.createChange(i,a,r,{parentType:e.parentType,hasManyName:e.hasManyName,changeType:"remove",key:e.key});r.addRelationshipChangeFor(i,n,e.parentRecord,null,o),o.sync()}}},DS.OneToManyChange.createChange=function(e,t,r,i){var n;i.parentType?(n=i.parentType.inverseFor(i.key).name,DS.OneToManyChange.maintainInvariant(i,r,e,n)):i.key&&(n=i.key);var a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,secondRecord:t,firstRecordKind:"belongsTo",secondRecordKind:"hasMany",store:r,changeType:i.changeType,firstRecordName:n});return r.addRelationshipChangeFor(e,n,t,a.getSecondRecordName(),a),a},DS.OneToManyChange.maintainInvariant=function(e,r,i,n){if("add"===e.changeType&&i){var a=t(i,n);if(a){var o=DS.OneToManyChange.createChange(i,a,r,{parentType:e.parentType,hasManyName:e.hasManyName,changeType:"remove",key:e.key});r.addRelationshipChangeFor(i,n,e.parentRecord,o.getSecondRecordName(),o),o.sync()}}},DS.RelationshipChange.prototype={getSecondRecordName:function(){var e,t=this.secondRecordName;if(!t){if(e=this.secondRecord,!e)return;var r=this.firstRecord.constructor,i=r.inverseFor(this.firstRecordName);this.secondRecordName=i.name}return this.secondRecordName},getFirstRecordName:function(){var e=this.firstRecordName;return e},destroy:function(){var e=this.childRecord,t=this.getFirstRecordName(),r=this.getSecondRecordName(),i=this.store;i.removeRelationshipChangeFor(e,t,this.parentRecord,r,this.changeType)},getSecondRecord:function(){return this.secondRecord},getFirstRecord:function(){return this.firstRecord},coalesce:function(){var e=this.store.relationshipChangePairsFor(this.firstRecord);i(e,function(e){var t=e.add,r=e.remove;t&&r&&(t.destroy(),r.destroy())})}},DS.RelationshipChangeAdd.prototype=Ember.create(DS.RelationshipChange.create({})),DS.RelationshipChangeRemove.prototype=Ember.create(DS.RelationshipChange.create({})),DS.RelationshipChangeAdd.prototype.changeType="add",DS.RelationshipChangeAdd.prototype.sync=function(){var i=this.getSecondRecordName(),n=this.getFirstRecordName(),a=this.getFirstRecord(),o=this.getSecondRecord();o instanceof DS.Model&&a instanceof DS.Model&&("belongsTo"===this.secondRecordKind?o.suspendRelationshipObservers(function(){r(o,i,a)}):"hasMany"===this.secondRecordKind&&o.suspendRelationshipObservers(function(){var r=t(o,i);e(r)&&r.addObject(a)})),a instanceof DS.Model&&o instanceof DS.Model&&t(a,n)!==o&&("belongsTo"===this.firstRecordKind?a.suspendRelationshipObservers(function(){r(a,n,o)}):"hasMany"===this.firstRecordKind&&a.suspendRelationshipObservers(function(){var r=t(a,n);e(r)&&r.addObject(o)})),this.coalesce()},DS.RelationshipChangeRemove.prototype.changeType="remove",DS.RelationshipChangeRemove.prototype.sync=function(){var i=this.getSecondRecordName(),n=this.getFirstRecordName(),a=this.getFirstRecord(),o=this.getSecondRecord();o instanceof DS.Model&&a instanceof DS.Model&&("belongsTo"===this.secondRecordKind?o.suspendRelationshipObservers(function(){r(o,i,null)}):"hasMany"===this.secondRecordKind&&o.suspendRelationshipObservers(function(){var r=t(o,i);e(r)&&r.removeObject(a)})),a instanceof DS.Model&&t(a,n)&&("belongsTo"===this.firstRecordKind?a.suspendRelationshipObservers(function(){r(a,n,null)}):"hasMany"===this.firstRecordKind&&a.suspendRelationshipObservers(function(){var r=t(a,n);e(r)&&r.removeObject(o)})),this.coalesce()}}(),function(){function e(e,i,n){return Ember.computed(function(e,i){var a=t(this,"data"),o=t(this,"store"),s="DS: Async belongsTo "+this+" : "+e;if(2===arguments.length)return void 0===i?null:DS.PromiseObject.create({promise:Ember.RSVP.resolve(i,s)});var c=a.links&&a.links[e],d=a[e];if(r(d)){if(c){var u=Ember.RSVP.defer("DS: Async belongsTo (link) "+this+" : "+e);return o.findBelongsTo(this,c,n,u),DS.PromiseObject.create({promise:u.promise})}return null}var l=o.fetchRecord(d)||Ember.RSVP.resolve(d,s);return DS.PromiseObject.create({promise:l})}).property("data").meta(n)}var t=Ember.get,r=(Ember.set,Ember.isNone);DS.belongsTo=function(i,n){"object"==typeof i&&(n=i,i=void 0),n=n||{};var a={type:i,isRelationship:!0,options:n,kind:"belongsTo"};return n.async?e(i,n,a):Ember.computed(function(e,n){var a,o,s=t(this,"data"),c=t(this,"store");return o="string"==typeof i?c.modelFor(i):i,2===arguments.length?void 0===n?null:n:(a=s[e],r(a)?null:(c.fetchRecord(a),a))}).property("data").meta(a)},DS.Model.reopen({belongsToWillChange:Ember.beforeObserver(function(e,r){if(t(e,"isLoaded")){var i=t(e,r);if(i){var n=t(e,"store"),a=DS.RelationshipChange.createChange(e,i,n,{key:r,kind:"belongsTo",changeType:"remove"});a.sync(),this._changesToSync[r]=a}}}),belongsToDidChange:Ember.immediateObserver(function(e,r){if(t(e,"isLoaded")){var i=t(e,r);if(i){var n=t(e,"store"),a=DS.RelationshipChange.createChange(e,i,n,{key:r,kind:"belongsTo",changeType:"add"});a.sync()}}delete this._changesToSync[r]})})}(),function(){function e(e,r,i){return Ember.computed(function(e){var a=this._relationships[e],o="DS: Async hasMany "+this+" : "+e;if(!a){var s=Ember.RSVP.defer(o);a=t(this,e,r,function(t,r){var a,o=r.links&&r.links[e];return a=o?t.findHasMany(this,o,i,s):t.findMany(this,r[e],i.type,s),n(a,"promise",s.promise),a})}var c=a.get("promise").then(function(){return a},null,"DS: Async hasMany records received");return DS.PromiseArray.create({promise:c})}).property("data").meta(i)}function t(e,t,r,n){var o=e._relationships;if(o[t])return o[t];var s=i(e,"data"),c=i(e,"store"),d=o[t]=n.call(e,c,s);return a(d,{owner:e,name:t,isPolymorphic:r.polymorphic})}function r(r,i){i=i||{};var n={type:r,isRelationship:!0,options:i,kind:"hasMany"};return i.async?e(r,i,n):Ember.computed(function(e){return t(this,e,i,function(t,r){r[e];return t.findMany(this,r[e],n.type)})}).property("data").meta(n)}var i=Ember.get,n=Ember.set,a=Ember.setProperties;DS.hasMany=function(e,t){return"object"==typeof e&&(t=e,e=void 0),r(e,t)}}(),function(){{var e=Ember.get;Ember.set}DS.Model.reopen({didDefineProperty:function(e,t,r){if(r instanceof Ember.Descriptor){var i=r.meta();i.isRelationship&&"belongsTo"===i.kind&&(Ember.addObserver(e,t,null,"belongsToDidChange"),Ember.addBeforeObserver(e,t,null,"belongsToWillChange")),i.parentType=e.constructor}}}),DS.Model.reopenClass({typeForRelationship:function(t){var r=e(this,"relationshipsByName").get(t);return r&&r.type},inverseFor:function(t){function r(t,i,n){n=n||[];var a=e(i,"relationships");if(a){var o=a.get(t);return o&&n.push.apply(n,a.get(t)),t.superclass&&r(t.superclass,i,n),n}}var i=this.typeForRelationship(t);if(!i)return null;var n=this.metaForProperty(t).options;if(null===n.inverse)return null;var a,o;if(n.inverse)a=n.inverse,o=Ember.get(i,"relationshipsByName").get(a).kind;else{var s=r(this,i);if(0===s.length)return null;a=s[0].name,o=s[0].kind}return{type:i,name:a,kind:o}},relationships:Ember.computed(function(){var e=new Ember.MapWithDefault({defaultValue:function(){return[]}});return this.eachComputedProperty(function(t,r){if(r.isRelationship){"string"==typeof r.type&&(r.type=this.store.modelFor(r.type));var i=e.get(r.type);i.push({name:t,kind:r.kind})}}),e}),relationshipNames:Ember.computed(function(){var e={hasMany:[],belongsTo:[]};return this.eachComputedProperty(function(t,r){r.isRelationship&&e[r.kind].push(t)}),e}),relatedTypes:Ember.computed(function(){var t,r=Ember.A();return this.eachComputedProperty(function(i,n){n.isRelationship&&(t=n.type,"string"==typeof t&&(t=e(this,t,!1)||this.store.modelFor(t)),r.contains(t)||r.push(t))}),r}),relationshipsByName:Ember.computed(function(){var e,t=Ember.Map.create();return this.eachComputedProperty(function(r,i){i.isRelationship&&(i.key=r,e=i.type,e||"hasMany"!==i.kind?e||(e=r):e=Ember.String.singularize(r),"string"==typeof e&&(i.type=this.store.modelFor(e)),t.set(r,i))}),t}),fields:Ember.computed(function(){var e=Ember.Map.create();return this.eachComputedProperty(function(t,r){r.isRelationship?e.set(t,r.kind):r.isAttribute&&e.set(t,"attribute")}),e}),eachRelationship:function(t,r){e(this,"relationshipsByName").forEach(function(e,i){t.call(r,e,i)})},eachRelatedType:function(t,r){e(this,"relatedTypes").forEach(function(e){t.call(r,e)})}}),DS.Model.reopen({eachRelationship:function(e,t){this.constructor.eachRelationship(e,t)}})}(),function(){var e=Ember.get,t=(Ember.set,Ember.run.once),r=Ember.EnumerableUtils.forEach;DS.RecordArrayManager=Ember.Object.extend({init:function(){this.filteredRecordArrays=Ember.MapWithDefault.create({defaultValue:function(){return[]}}),this.changedRecords=[]},recordDidChange:function(e){this.changedRecords.push(e),t(this,this.updateRecordArrays)},recordArraysForRecord:function(e){return e._recordArrays=e._recordArrays||Ember.OrderedSet.create(),e._recordArrays},updateRecordArrays:function(){r(this.changedRecords,function(t){e(t,"isDeleted")?this._recordWasDeleted(t):this._recordWasChanged(t)},this),this.changedRecords=[]},_recordWasDeleted:function(e){var t=e._recordArrays;t&&r(t,function(t){t.removeRecord(e)})},_recordWasChanged:function(t){var i,n=t.constructor,a=this.filteredRecordArrays.get(n);r(a,function(r){i=e(r,"filterFunction"),this.updateRecordArray(r,i,n,t)},this);var o=t._loadingRecordArrays;if(o){for(var s=0,c=o.length;c>s;s++)o[s].loadedRecord();t._loadingRecordArrays=[]}},updateRecordArray:function(e,t,r,i){var n;n=t?t(i):!0;var a=this.recordArraysForRecord(i);n?(a.add(e),e.addRecord(i)):n||(a.remove(e),e.removeRecord(i))},updateFilter:function(t,r,i){for(var n,a=this.store.typeMapFor(r),o=a.records,s=0,c=o.length;c>s;s++)n=o[s],e(n,"isDeleted")||e(n,"isEmpty")||this.updateRecordArray(t,i,r,n)},createManyArray:function(e,t){var i=DS.ManyArray.create({type:e,content:t,store:this.store});return r(t,function(e){var t=this.recordArraysForRecord(e);t.add(i)},this),i},registerFilteredRecordArray:function(e,t,r){var i=this.filteredRecordArrays.get(t);i.push(e),this.updateFilter(e,t,r)},registerWaitingRecordArray:function(e,t){var r=e._loadingRecordArrays||[];r.push(t),e._loadingRecordArrays=r}})}(),function(){var e=Ember.get,t=(Ember.set,Ember.ArrayPolyfills.map),r=["description","fileName","lineNumber","message","name","number","stack"];DS.InvalidError=function(e){var t=Error.prototype.constructor.call(this,"The backend rejected the commit because it was invalid: "+Ember.inspect(e));this.errors=e;for(var i=0,n=r.length;n>i;i++)this[r[i]]=t[r[i]]},DS.InvalidError.prototype=Ember.create(Error.prototype),DS.Adapter=Ember.Object.extend({find:Ember.required(Function),findAll:null,findQuery:null,generateIdForRecord:null,serialize:function(t,r){return e(t,"store").serializerFor(t.constructor.typeKey).serialize(t,r)},createRecord:Ember.required(Function),updateRecord:Ember.required(Function),deleteRecord:Ember.required(Function),findMany:function(e,r,i){var n=t.call(i,function(t){return this.find(e,r,t)},this);return Ember.RSVP.all(n)}})}(),function(){var e=Ember.get,t=Ember.String.fmt,r=Ember.EnumerableUtils.indexOf,i=0;DS.FixtureAdapter=DS.Adapter.extend({serializer:null,simulateRemoteResponse:!0,latency:50,fixturesForType:function(e){if(e.FIXTURES){var r=Ember.A(e.FIXTURES);return r.map(function(e){var r=typeof e.id;if("number"!==r&&"string"!==r)throw new Error(t("the id property must be defined as a number or string for fixture %@",[e]));return e.id=e.id+"",e})}return null},queryFixtures:function(){},updateFixtures:function(e,t){e.FIXTURES||(e.FIXTURES=[]);var r=e.FIXTURES;this.deleteLoadedFixture(e,t),r.push(t)},mockJSON:function(e,t,r){return e.serializerFor(t).serialize(r,{includeId:!0})},generateIdForRecord:function(){return"fixture-"+i++},find:function(e,t,r){var i,n=this.fixturesForType(t);return n&&(i=Ember.A(n).findProperty("id",r)),i?this.simulateRemoteCall(function(){return i},this):void 0},findMany:function(e,t,i){var n=this.fixturesForType(t);return n&&(n=n.filter(function(e){return-1!==r(i,e.id)})),n?this.simulateRemoteCall(function(){return n},this):void 0},findAll:function(e,t){var r=this.fixturesForType(t);return this.simulateRemoteCall(function(){return r},this)},findQuery:function(e,t,r){var i=this.fixturesForType(t);return i=this.queryFixtures(i,r,t),i?this.simulateRemoteCall(function(){return i},this):void 0},createRecord:function(e,t,r){var i=this.mockJSON(e,t,r);return this.updateFixtures(t,i),this.simulateRemoteCall(function(){return i},this)},updateRecord:function(e,t,r){var i=this.mockJSON(e,t,r);return this.updateFixtures(t,i),this.simulateRemoteCall(function(){return i},this)},deleteRecord:function(e,t,r){var i=this.mockJSON(e,t,r);return this.deleteLoadedFixture(t,i),this.simulateRemoteCall(function(){return null})},deleteLoadedFixture:function(e,t){var i=this.findExistingFixture(e,t);if(i){var n=r(e.FIXTURES,i);return e.FIXTURES.splice(n,1),!0}},findExistingFixture:function(t,r){var i=this.fixturesForType(t),n=e(r,"id");return this.findFixtureById(i,n)},findFixtureById:function(t,r){return Ember.A(t).find(function(t){return""+e(t,"id")==""+r?!0:!1})},simulateRemoteCall:function(t,r){var i=this;return new Ember.RSVP.Promise(function(n){e(i,"simulateRemoteResponse")?Ember.run.later(function(){n(t.call(r))},e(i,"latency")):Ember.run.schedule("actions",null,function(){n(t.call(r))})},"DS: FixtureAdapter#simulateRemoteCall")}})}(),function(){function e(e){return null==e?null:e+""}var t=Ember.get,r=(Ember.set,Ember.ArrayPolyfills.forEach),i=Ember.ArrayPolyfills.map;DS.RESTSerializer=DS.JSONSerializer.extend({normalize:function(e,t,r){return this.normalizeId(t),this.normalizeUsingDeclaredMapping(e,t),this.normalizeAttributes(e,t),this.normalizeRelationships(e,t),this.normalizeHash&&this.normalizeHash[r]&&this.normalizeHash[r](t),this._super(e,t,r)},normalizePayload:function(e,t){return t},normalizeId:function(e){var r=t(this,"primaryKey");"id"!==r&&(e.id=e[r],delete e[r])},normalizeUsingDeclaredMapping:function(e,r){var i,n,a=t(this,"attrs");if(a)for(n in a)i=a[n],r[n]=r[i],delete r[i]},normalizeAttributes:function(e,t){var r;this.keyForAttribute&&e.eachAttribute(function(e){r=this.keyForAttribute(e),e!==r&&(t[e]=t[r],delete t[r])},this)},normalizeRelationships:function(e,t){var r;this.keyForRelationship&&e.eachRelationship(function(e,i){r=this.keyForRelationship(e,i.kind),e!==r&&(t[e]=t[r],delete t[r])},this)},extractSingle:function(t,i,n,a){n=this.normalizePayload(i,n);var o,s=i.typeKey;for(var c in n){var d=this.typeForRoot(c),u=d===s;if(u&&"array"!==Ember.typeOf(n[c]))o=this.normalize(i,n[c],c);else{{t.modelFor(d)}r.call(n[c],function(r){var i=this.typeForRoot(c),n=t.modelFor(i),s=t.serializerFor(n);r=s.normalize(n,r,c);var d=u&&!a&&!o,l=u&&e(r.id)===a;d||l?o=r:t.push(i,r)},this)}}return o},extractArray:function(e,t,r){r=this.normalizePayload(t,r);var n,a=t.typeKey;for(var o in r){var s=o,c=!1;"_"===o.charAt(0)&&(c=!0,s=o.substr(1));var d=this.typeForRoot(s),u=e.modelFor(d),l=e.serializerFor(u),h=!c&&d===a,f=i.call(r[o],function(e){return l.normalize(u,e,o)},this);h?n=f:e.pushMany(d,f)}return n},pushPayload:function(e,t){t=this.normalizePayload(null,t);for(var r in t){var n=this.typeForRoot(r),a=e.modelFor(n),o=i.call(t[r],function(e){return this.normalize(a,e,r)},this);e.pushMany(n,o)}},typeForRoot:function(e){return Ember.String.singularize(e)},serialize:function(){return this._super.apply(this,arguments)},serializeIntoHash:function(e,t,r,i){e[t.typeKey]=this.serialize(r,i)},serializePolymorphicType:function(e,r,i){var n=i.key,a=t(e,n);n=this.keyForAttribute?this.keyForAttribute(n):n,r[n+"Type"]=a.constructor.typeKey}})}(),function(){var e=Ember.get,t=(Ember.set,Ember.ArrayPolyfills.forEach);DS.RESTAdapter=DS.Adapter.extend({defaultSerializer:"_rest",find:function(e,t,r){return this.ajax(this.buildURL(t.typeKey,r),"GET")},findAll:function(e,t,r){var i;return r&&(i={since:r}),this.ajax(this.buildURL(t.typeKey),"GET",{data:i})},findQuery:function(e,t,r){return this.ajax(this.buildURL(t.typeKey),"GET",{data:r})},findMany:function(e,t,r){return this.ajax(this.buildURL(t.typeKey),"GET",{data:{ids:r}})},findHasMany:function(t,r,i){var n=e(this,"host"),a=e(r,"id"),o=r.constructor.typeKey;return n&&"/"===i.charAt(0)&&"/"!==i.charAt(1)&&(i=n+i),this.ajax(this.urlPrefix(i,this.buildURL(o,a)),"GET")},findBelongsTo:function(t,r,i){var n=e(r,"id"),a=r.constructor.typeKey;return this.ajax(this.urlPrefix(i,this.buildURL(a,n)),"GET")},createRecord:function(e,t,r){var i={},n=e.serializerFor(t.typeKey);return n.serializeIntoHash(i,t,r,{includeId:!0}),this.ajax(this.buildURL(t.typeKey),"POST",{data:i})},updateRecord:function(t,r,i){var n={},a=t.serializerFor(r.typeKey);a.serializeIntoHash(n,r,i);var o=e(i,"id");return this.ajax(this.buildURL(r.typeKey,o),"PUT",{data:n})},deleteRecord:function(t,r,i){var n=e(i,"id");return this.ajax(this.buildURL(r.typeKey,n),"DELETE")},buildURL:function(t,r){var i=[],n=e(this,"host"),a=this.urlPrefix();return t&&i.push(this.pathForType(t)),r&&i.push(r),a&&i.unshift(a),i=i.join("/"),!n&&i&&(i="/"+i),i},urlPrefix:function(t,r){var i=e(this,"host"),n=e(this,"namespace"),a=[];return t?"/"===t.charAt(0)?i&&(t=t.slice(1),a.push(i)):/^http(s)?:\/\//.test(t)||a.push(r):(i&&a.push(i),n&&a.push(n)),t&&a.push(t),a.join("/")},pathForType:function(e){return Ember.String.pluralize(e)},ajaxError:function(e){return e&&(e.then=null),e},ajax:function(e,t,r){var i=this;return new Ember.RSVP.Promise(function(n,a){r=i.ajaxOptions(e,t,r),r.success=function(e){Ember.run(null,n,e)},r.error=function(e){Ember.run(null,a,i.ajaxError(e))},Ember.$.ajax(r)},"DS: RestAdapter#ajax "+t+" to "+e)},ajaxOptions:function(e,r,i){if(i=i||{},i.url=e,i.type=r,i.dataType="json",i.context=this,i.data&&"GET"!==r&&(i.contentType="application/json; charset=utf-8",i.data=JSON.stringify(i.data)),void 0!==this.headers){var n=this.headers;i.beforeSend=function(e){t.call(Ember.keys(n),function(t){e.setRequestHeader(t,n[t])})}}return i}})}(),function(){DS.Model.reopen({_debugInfo:function(){var e=["id"],t={belongsTo:[],hasMany:[]},r=[];this.eachAttribute(function(t){e.push(t)},this),this.eachRelationship(function(e,i){t[i.kind].push(e),r.push(e)});var i=[{name:"Attributes",properties:e,expand:!0},{name:"Belongs To",properties:t.belongsTo,expand:!0},{name:"Has Many",properties:t.hasMany,expand:!0},{name:"Flags",properties:["isLoaded","isDirty","isSaving","isDeleted","isError","isNew","isValid"]}];return{propertyInfo:{includeOtherProperties:!0,groups:i,expensiveProperties:r}}}})}(),function(){Ember.String.pluralize=function(e){return Ember.Inflector.inflector.pluralize(e)},Ember.String.singularize=function(e){return Ember.Inflector.inflector.singularize(e)}}(),function(){function e(e,t){for(var r=0,i=t.length;i>r;r++)e.uncountable[t[r].toLowerCase()]=!0}function t(e,t){for(var r,i=0,n=t.length;n>i;i++)r=t[i],e.irregular[r[0].toLowerCase()]=r[1],e.irregularInverse[r[1].toLowerCase()]=r[0]}function r(r){r=r||{},r.uncountable=r.uncountable||{},r.irregularPairs=r.irregularPairs||{};var i=this.rules={plurals:r.plurals||[],singular:r.singular||[],irregular:{},irregularInverse:{},uncountable:{}};e(i,r.uncountable),t(i,r.irregularPairs)}var i=/^\s*$/;r.prototype={plural:function(e,t){this.rules.plurals.push([e,t.toLowerCase()])},singular:function(e,t){this.rules.singular.push([e,t.toLowerCase()])},uncountable:function(t){e(this.rules,[t.toLowerCase()])},irregular:function(e,r){t(this.rules,[[e,r]])},pluralize:function(e){return this.inflect(e,this.rules.plurals,this.rules.irregular)},singularize:function(e){return this.inflect(e,this.rules.singular,this.rules.irregularInverse)},inflect:function(e,t,r){var n,a,o,s,c,d,u,l;if(c=i.test(e))return e;if(s=e.toLowerCase(),d=this.rules.uncountable[s])return e;if(u=r&&r[s])return u;for(var h=t.length,f=0;h>f&&(n=t[h-1],l=n[0],!l.test(e));h--);return n=n||[],l=n[0],a=n[1],o=e.replace(l,a)}},Ember.Inflector=r}(),function(){Ember.Inflector.defaultRules={plurals:[[/$/,"s"],[/s$/i,"s"],[/^(ax|test)is$/i,"$1es"],[/(octop|vir)us$/i,"$1i"],[/(octop|vir)i$/i,"$1i"],[/(alias|status)$/i,"$1es"],[/(bu)s$/i,"$1ses"],[/(buffal|tomat)o$/i,"$1oes"],[/([ti])um$/i,"$1a"],[/([ti])a$/i,"$1a"],[/sis$/i,"ses"],[/(?:([^f])fe|([lr])f)$/i,"$1$2ves"],[/(hive)$/i,"$1s"],[/([^aeiouy]|qu)y$/i,"$1ies"],[/(x|ch|ss|sh)$/i,"$1es"],[/(matr|vert|ind)(?:ix|ex)$/i,"$1ices"],[/^(m|l)ouse$/i,"$1ice"],[/^(m|l)ice$/i,"$1ice"],[/^(ox)$/i,"$1en"],[/^(oxen)$/i,"$1"],[/(quiz)$/i,"$1zes"]],singular:[[/s$/i,""],[/(ss)$/i,"$1"],[/(n)ews$/i,"$1ews"],[/([ti])a$/i,"$1um"],[/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i,"$1sis"],[/(^analy)(sis|ses)$/i,"$1sis"],[/([^f])ves$/i,"$1fe"],[/(hive)s$/i,"$1"],[/(tive)s$/i,"$1"],[/([lr])ves$/i,"$1f"],[/([^aeiouy]|qu)ies$/i,"$1y"],[/(s)eries$/i,"$1eries"],[/(m)ovies$/i,"$1ovie"],[/(x|ch|ss|sh)es$/i,"$1"],[/^(m|l)ice$/i,"$1ouse"],[/(bus)(es)?$/i,"$1"],[/(o)es$/i,"$1"],[/(shoe)s$/i,"$1"],[/(cris|test)(is|es)$/i,"$1is"],[/^(a)x[ie]s$/i,"$1xis"],[/(octop|vir)(us|i)$/i,"$1us"],[/(alias|status)(es)?$/i,"$1"],[/^(ox)en/i,"$1"],[/(vert|ind)ices$/i,"$1ex"],[/(matr)ices$/i,"$1ix"],[/(quiz)zes$/i,"$1"],[/(database)s$/i,"$1"]],irregularPairs:[["person","people"],["man","men"],["child","children"],["sex","sexes"],["move","moves"],["cow","kine"],["zombie","zombies"]],uncountable:["equipment","information","rice","money","species","series","fish","sheep","jeans","police"]}}(),function(){(Ember.EXTEND_PROTOTYPES===!0||Ember.EXTEND_PROTOTYPES.String)&&(String.prototype.pluralize=function(){return Ember.String.pluralize(this)},String.prototype.singularize=function(){return Ember.String.singularize(this)})}(),function(){Ember.Inflector.inflector=new Ember.Inflector(Ember.Inflector.defaultRules)}(),function(){var e=Ember.get,t=Ember.EnumerableUtils.forEach;DS.ActiveModelSerializer=DS.RESTSerializer.extend({keyForAttribute:function(e){return Ember.String.decamelize(e)},keyForRelationship:function(e,t){return e=Ember.String.decamelize(e),"belongsTo"===t?e+"_id":"hasMany"===t?Ember.String.singularize(e)+"_ids":e},serializeHasMany:Ember.K,serializeIntoHash:function(e,t,r,i){var n=Ember.String.decamelize(t.typeKey);e[n]=this.serialize(r,i)},serializePolymorphicType:function(t,r,i){var n=i.key,a=e(t,n);n=this.keyForAttribute(n),r[n+"_type"]=Ember.String.capitalize(a.constructor.typeKey)},typeForRoot:function(e){var t=Ember.String.camelize(e);return Ember.String.singularize(t)},normalize:function(e,t,r){return this.normalizeLinks(t),this._super(e,t,r)},normalizeLinks:function(e){if(e.links){var t=e.links;for(var r in t){var i=Ember.String.camelize(r);i!==r&&(t[i]=t[r],delete t[r])}}},normalizeRelationships:function(e,r){var i,n;this.keyForRelationship&&e.eachRelationship(function(e,a){if(a.options.polymorphic){if(i=this.keyForAttribute(e),n=r[i],n&&n.type)n.type=this.typeForRoot(n.type);else if(n&&"hasMany"===a.kind){var o=this;t(n,function(e){e.type=o.typeForRoot(e.type)})}}else i=this.keyForRelationship(e,a.kind),n=r[i];r[e]=n,e!==i&&delete r[i]},this)}})}(),function(){function e(i,n,a,o,s){var c=t(n,"attrs");c&&a.eachRelationship(function(n,a){var d,u,l,h,f=c[n],p=i.serializerFor(a.type.typeKey),m=t(p,"primaryKey");if("hasMany"===a.kind&&f&&("always"===f.embedded||"load"===f.embedded)){if(u="_"+Ember.String.pluralize(a.type.typeKey),d=this.keyForRelationship(n,a.kind),l=this.keyForAttribute(n),h=[],!o[l])return;s[u]=s[u]||[],r(o[l],function(t){var r=i.modelFor(a.type.typeKey);e(i,p,r,t,s),h.push(t[m]),s[u].push(t)}),o[d]=h,delete o[l]}},n)}var t=Ember.get,r=Ember.EnumerableUtils.forEach;DS.EmbeddedRecordsMixin=Ember.Mixin.create({serializeHasMany:function(e,r,i){var n=i.key,a=t(this,"attrs"),o=a&&a[n]&&"always"===a[n].embedded;o&&(r[this.keyForAttribute(n)]=t(e,n).map(function(e){var r=e.serialize(),i=t(this,"primaryKey");return r[i]=t(e,i),r},this))},extractSingle:function(t,r,i,n,a){var o=this.keyForAttribute(r.typeKey),s=i[o];return e(t,this,r,s,i),this._super(t,r,i,n,a)},extractArray:function(t,i,n){var a=this.keyForAttribute(i.typeKey),o=n[Ember.String.pluralize(a)];return r(o,function(r){e(t,this,i,r,n)},this),this._super(t,i,n)}})}(),function(){var e=Ember.EnumerableUtils.forEach;DS.ActiveModelAdapter=DS.RESTAdapter.extend({defaultSerializer:"_ams",pathForType:function(e){var t=Ember.String.decamelize(e);return Ember.String.pluralize(t)},ajaxError:function(t){var r=this._super(t);if(t&&422===t.status){var i=Ember.$.parseJSON(t.responseText).errors,n={};return e(Ember.keys(i),function(e){n[Ember.String.camelize(e)]=i[e]}),new DS.InvalidError(n)}return r}})}(),function(){Ember.onLoad("Ember.Application",function(e){e.initializer({name:"activeModelAdapter",initialize:function(e,t){t.register("serializer:_ams",DS.ActiveModelSerializer),t.register("adapter:_ams",DS.ActiveModelAdapter)}})})}()}(),"undefined"==typeof location||"localhost"!==location.hostname&&"127.0.0.1"!==location.hostname||Ember.Logger.warn("You are running a production build of Ember on localhost and won't receive detailed error messages. If you want full error messages please use the non-minified build provided on the Ember website.");
8
+ !function(){var e,t;!function(){var r={},n={};e=function(e,t,n){r[e]={deps:t,callback:n}},t=function(e){if(n[e])return n[e];n[e]={};var i,a,o,s,c;if(i=r[e],!i)throw new Error("Module '"+e+"' not found.");a=i.deps,o=i.callback,s=[];for(var d=0,u=a.length;u>d;d++)"exports"===a[d]?s.push(c={}):s.push(t(a[d]));var l=o.apply(this,s);return n[e]=c||l}}(),function(){var e;"undefined"==typeof e&&(e=Ember.Namespace.create({VERSION:"1.0.0-beta.5"}),"undefined"!=typeof window&&(window.DS=e),Ember.libraries&&Ember.libraries.registerCoreLibrary("Ember Data",e.VERSION))}(),function(){function e(e){return function(){return this[e].apply(this,arguments)}}var t=Ember.get,r=(Ember.set,Ember.isNone);DS.JSONSerializer=Ember.Object.extend({primaryKey:"id",applyTransforms:function(e,t){return e.eachTransformedAttribute(function(e,r){var n=this.transformFor(r);t[e]=n.deserialize(t[e])},this),t},normalize:function(e,t){return t?(this.applyTransforms(e,t),t):t},serialize:function(e,r){var n={};if(r&&r.includeId){var i=t(e,"id");i&&(n[t(this,"primaryKey")]=i)}return e.eachAttribute(function(t,r){this.serializeAttribute(e,n,t,r)},this),e.eachRelationship(function(t,r){"belongsTo"===r.kind?this.serializeBelongsTo(e,n,r):"hasMany"===r.kind&&this.serializeHasMany(e,n,r)},this),n},serializeAttribute:function(e,r,n,i){var a=t(this,"attrs"),o=t(e,n),s=i.type;if(s){var c=this.transformFor(s);o=c.serialize(o)}n=a&&a[n]||(this.keyForAttribute?this.keyForAttribute(n):n),r[n]=o},serializeBelongsTo:function(e,n,i){var a=i.key,o=t(e,a);a=this.keyForRelationship?this.keyForRelationship(a,"belongsTo"):a,n[a]=r(o)?o:t(o,"id"),i.options.polymorphic&&this.serializePolymorphicType(e,n,i)},serializeHasMany:function(e,r,n){var i=n.key,a=DS.RelationshipChange.determineRelationshipType(e.constructor,n);("manyToNone"===a||"manyToMany"===a)&&(r[i]=t(e,i).mapBy("id"))},serializePolymorphicType:Ember.K,extract:function(e,t,r,n,i){this.extractMeta(e,t,r);var a="extract"+i.charAt(0).toUpperCase()+i.substr(1);return this[a](e,t,r,n,i)},extractFindAll:e("extractArray"),extractFindQuery:e("extractArray"),extractFindMany:e("extractArray"),extractFindHasMany:e("extractArray"),extractCreateRecord:e("extractSave"),extractUpdateRecord:e("extractSave"),extractDeleteRecord:e("extractSave"),extractFind:e("extractSingle"),extractFindBelongsTo:e("extractSingle"),extractSave:e("extractSingle"),extractSingle:function(e,t,r){return this.normalize(t,r)},extractArray:function(e,t,r){return this.normalize(t,r)},extractMeta:function(e,t,r){r&&r.meta&&(e.metaForType(t,r.meta),delete r.meta)},transformFor:function(e){var t=this.container.lookup("transform:"+e);return t}})}(),function(){var e=Ember.get,t=Ember.String.capitalize,r=Ember.String.underscore,n=window.DS;n.DebugAdapter=Ember.DataAdapter.extend({getFilters:function(){return[{name:"isNew",desc:"New"},{name:"isModified",desc:"Modified"},{name:"isClean",desc:"Clean"}]},detect:function(e){return e!==n.Model&&n.Model.detect(e)},columnsForType:function(n){var i=[{name:"id",desc:"Id"}],a=0,o=this;return e(n,"attributes").forEach(function(e){if(a++>o.attributeLimit)return!1;var n=t(r(e).replace("_"," "));i.push({name:e,desc:n})}),i},getRecords:function(e){return this.get("store").all(e)},getRecordColumnValues:function(t){var r=this,n=0,i={id:e(t,"id")};return t.eachAttribute(function(a){if(n++>r.attributeLimit)return!1;var o=e(t,a);i[a]=o}),i},getRecordKeywords:function(t){var r=[],n=Ember.A(["id"]);return t.eachAttribute(function(e){n.push(e)}),n.forEach(function(n){r.push(e(t,n))}),r},getRecordFilterValues:function(e){return{isNew:e.get("isNew"),isModified:e.get("isDirty")&&!e.get("isNew"),isClean:!e.get("isDirty")}},getRecordColor:function(e){var t="black";return e.get("isNew")?t="green":e.get("isDirty")&&(t="blue"),t},observeRecord:function(e,t){var r=Ember.A(),n=this,i=Ember.A(["id","isNew","isDirty"]);e.eachAttribute(function(e){i.push(e)}),i.forEach(function(i){var a=function(){t(n.wrapRecord(e))};Ember.addObserver(e,i,a),r.push(function(){Ember.removeObserver(e,i,a)})});var a=function(){r.forEach(function(e){e()})};return a}})}(),function(){DS.Transform=Ember.Object.extend({serialize:Ember.required(),deserialize:Ember.required()})}(),function(){DS.BooleanTransform=DS.Transform.extend({deserialize:function(e){var t=typeof e;return"boolean"===t?e:"string"===t?null!==e.match(/^true$|^t$|^1$/i):"number"===t?1===e:!1},serialize:function(e){return Boolean(e)}})}(),function(){DS.DateTransform=DS.Transform.extend({deserialize:function(e){var t=typeof e;return"string"===t?new Date(Ember.Date.parse(e)):"number"===t?new Date(e):null===e||void 0===e?e:null},serialize:function(e){if(e instanceof Date){var t=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],r=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],n=function(e){return 10>e?"0"+e:""+e},i=e.getUTCFullYear(),a=e.getUTCMonth(),o=e.getUTCDate(),s=e.getUTCDay(),c=e.getUTCHours(),d=e.getUTCMinutes(),u=e.getUTCSeconds(),l=t[s],h=n(o),f=r[a];return l+", "+h+" "+f+" "+i+" "+n(c)+":"+n(d)+":"+n(u)+" GMT"}return null}})}(),function(){var e=Ember.isEmpty;DS.NumberTransform=DS.Transform.extend({deserialize:function(t){return e(t)?null:Number(t)},serialize:function(t){return e(t)?null:Number(t)}})}(),function(){var e=Ember.isNone;DS.StringTransform=DS.Transform.extend({deserialize:function(t){return e(t)?null:String(t)},serialize:function(t){return e(t)?null:String(t)}})}(),function(){Ember.set;Ember.onLoad("Ember.Application",function(e){e.initializer({name:"store",initialize:function(e,t){t.register("store:main",t.Store||DS.Store),t.register("serializer:_default",DS.JSONSerializer),t.register("serializer:_rest",DS.RESTSerializer),t.register("adapter:_rest",DS.RESTAdapter),e.lookup("store:main")}}),e.initializer({name:"transforms",before:"store",initialize:function(e,t){t.register("transform:boolean",DS.BooleanTransform),t.register("transform:date",DS.DateTransform),t.register("transform:number",DS.NumberTransform),t.register("transform:string",DS.StringTransform)}}),e.initializer({name:"dataAdapter",before:"store",initialize:function(e,t){t.register("dataAdapter:main",DS.DebugAdapter)}}),e.initializer({name:"injectStore",before:"store",initialize:function(e,t){t.inject("controller","store","store:main"),t.inject("route","store","store:main"),t.inject("serializer","store","store:main"),t.inject("dataAdapter","store","store:main")}})})}(),function(){Ember.Date=Ember.Date||{};var e=Date.parse,t=[1,4,5,6,7,10,11];Ember.Date.parse=function(r){var n,i,a=0;if(i=/^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(r)){for(var o,s=0;o=t[s];++s)i[o]=+i[o]||0;i[2]=(+i[2]||1)-1,i[3]=+i[3]||1,"Z"!==i[8]&&void 0!==i[9]&&(a=60*i[10]+i[11],"+"===i[9]&&(a=0-a)),n=Date.UTC(i[1],i[2],i[3],i[4],i[5]+a,i[6],i[7])}else n=e?e(r):0/0;return n},(Ember.EXTEND_PROTOTYPES===!0||Ember.EXTEND_PROTOTYPES.Date)&&(Date.parse=Ember.Date.parse)}(),function(){{var e=Ember.get;Ember.set}DS.RecordArray=Ember.ArrayProxy.extend(Ember.Evented,{type:null,content:null,isLoaded:!1,isUpdating:!1,store:null,objectAtContent:function(t){var r=e(this,"content");return r.objectAt(t)},update:function(){if(!e(this,"isUpdating")){var t=e(this,"store"),r=e(this,"type");t.fetchAll(r,this)}},addRecord:function(t){e(this,"content").addObject(t)},removeRecord:function(t){e(this,"content").removeObject(t)},save:function(){var t="DS: RecordArray#save "+e(this,"type"),r=Ember.RSVP.all(this.invoke("save"),t).then(function(e){return Ember.A(e)},null,"DS: RecordArray#save apply Ember.NativeArray");return DS.PromiseArray.create({promise:r})}})}(),function(){var e=Ember.get;DS.FilteredRecordArray=DS.RecordArray.extend({filterFunction:null,isLoaded:!0,replace:function(){var t=e(this,"type").toString();throw new Error("The result of a client-side filter (on "+t+") is immutable.")},updateFilter:Ember.observer(function(){var t=e(this,"manager");t.updateFilter(this,e(this,"type"),e(this,"filterFunction"))},"filterFunction")})}(),function(){{var e=Ember.get;Ember.set}DS.AdapterPopulatedRecordArray=DS.RecordArray.extend({query:null,replace:function(){var t=e(this,"type").toString();throw new Error("The result of a server query (on "+t+") is immutable.")},load:function(t){var r=e(this,"store"),n=e(this,"type"),i=r.pushMany(n,t),a=r.metadataFor(n);this.setProperties({content:Ember.A(i),isLoaded:!0,meta:a}),Ember.run.once(this,"trigger","didLoad")}})}(),function(){var e=Ember.get,t=Ember.set,r=Ember.EnumerableUtils.map;DS.ManyArray=DS.RecordArray.extend({init:function(){this._super.apply(this,arguments),this._changesToSync=Ember.OrderedSet.create()},name:null,owner:null,isPolymorphic:!1,isLoaded:!1,promise:null,loadingRecordsCount:function(e){this.loadingRecordsCount=e},loadedRecord:function(){this.loadingRecordsCount--,0===this.loadingRecordsCount&&(t(this,"isLoaded",!0),this.trigger("didLoad"))},fetch:function(){var t=e(this,"content"),r=e(this,"store"),n=e(this,"owner"),i=Ember.RSVP.defer("DS: ManyArray#fetch "+e(this,"type")),a=t.filterProperty("isEmpty",!0);r.fetchMany(a,n,i)},replaceContent:function(e,t,n){n=r(n,function(e){return e},this),this._super(e,t,n)},arrangedContentDidChange:function(){Ember.run.once(this,"fetch")},arrayContentWillChange:function(t,r){var n=e(this,"owner"),i=e(this,"name");if(!n._suspendedRelationships)for(var a=t;t+r>a;a++){var o=e(this,"content").objectAt(a),s=DS.RelationshipChange.createChange(n,o,e(this,"store"),{parentType:n.constructor,changeType:"remove",kind:"hasMany",key:i});this._changesToSync.add(s)}return this._super.apply(this,arguments)},arrayContentDidChange:function(t,r,n){this._super.apply(this,arguments);var i=e(this,"owner"),a=e(this,"name"),o=e(this,"store");if(!i._suspendedRelationships){for(var s=t;t+n>s;s++){var c=e(this,"content").objectAt(s),d=DS.RelationshipChange.createChange(i,c,o,{parentType:i.constructor,changeType:"add",kind:"hasMany",key:a});d.hasManyName=a,this._changesToSync.add(d)}this._changesToSync.forEach(function(e){e.sync()}),this._changesToSync.clear()}},createRecord:function(t){var r,n=e(this,"owner"),i=e(n,"store"),a=e(this,"type");return r=i.createRecord.call(i,a,t),this.pushObject(r),r}})}(),function(){function e(e,r,a,o){return r.eachRelationship(function(r,s){if(a.links&&a.links[r])return o&&s.options.async&&(o._relationships[r]=null),void 0;var c=s.kind,d=a[r];null!=d&&("belongsTo"===c?t(e,a,r,s,d):"hasMany"===c&&(n(e,a,r,s,d),i(o,r,d)))}),a}function t(e,t,n,i,a){if(!(R(a)||a instanceof DS.Model)){var o;"number"==typeof a||"string"==typeof a?(o=r(i,n,t),t[n]=e.recordForId(o,a)):"object"==typeof a&&(t[n]=e.recordForId(a.type,a.id))}}function r(e,t,r){return e.options.polymorphic?r[t+"Type"]:e.type}function n(e,r,n,i,a){for(var o=0,s=a.length;s>o;o++)t(e,a,o,i,a[o])}function i(e,t,r){e&&r.pushObjects(e.get(t).filterBy("isNew"))}function a(e){return DS.PromiseObject.create({promise:e})}function o(e){return DS.PromiseArray.create({promise:e})}function s(e,t,r){return e.lookup("serializer:"+t)||e.lookup("serializer:application")||e.lookup("serializer:"+r)||e.lookup("serializer:_default")}function c(e){return e.lookup("serializer:application")||e.lookup("serializer:_default")}function d(e,t){var r=e.serializer,n=e.defaultSerializer,i=e.container;return i&&void 0===r&&(r=s(i,t.typeKey,n)),(null===r||void 0===r)&&(r={extract:function(e,t,r){return r}}),r}function u(e,t,r,n){var i=e.find(t,r,n),a=d(e,r);return T(i,"DS: Handle Adapter#find of "+r+" with id: "+n).then(function(e){return e=a.extract(t,r,e,n,"find"),t.push(r,e)},function(e){var i=t.getById(r,n);throw i.notFound(),e},"DS: Extract payload of '"+r+"'")}function l(e,t,r,n,i){var a=e.findMany(t,r,n,i),o=d(e,r);return T(a,"DS: Handle Adapter#findMany of "+r).then(function(e){e=o.extract(t,r,e,null,"findMany"),t.pushMany(r,e)},null,"DS: Extract payload of "+r)}function h(e,t,r,n,i){var a=e.findHasMany(t,r,n,i),o=d(e,i.type);return T(a,"DS: Handle Adapter#findHasMany of "+r+" : "+i.type).then(function(e){e=o.extract(t,i.type,e,null,"findHasMany");var n=t.pushMany(i.type,e);r.updateHasMany(i.key,n)},null,"DS: Extract payload of "+r+" : hasMany "+i.type)}function f(e,t,r,n,i){var a=e.findBelongsTo(t,r,n,i),o=d(e,i.type);return T(a,"DS: Handle Adapter#findBelongsTo of "+r+" : "+i.type).then(function(e){e=o.extract(t,i.type,e,null,"findBelongsTo");var r=t.push(i.type,e);return r.updateBelongsTo(i.key,r),r},null,"DS: Extract payload of "+r+" : "+i.type)}function p(e,t,r,n){var i=e.findAll(t,r,n),a=d(e,r);return T(i,"DS: Handle Adapter#findAll of "+r).then(function(e){return e=a.extract(t,r,e,null,"findAll"),t.pushMany(r,e),t.didUpdateAll(r),t.all(r)},null,"DS: Extract payload of findAll "+r)}function m(e,t,r,n,i){var a=e.findQuery(t,r,n,i),o=d(e,r);return T(a,"DS: Handle Adapter#findQuery of "+r).then(function(e){return e=o.extract(t,r,e,null,"findQuery"),i.load(e),i},null,"DS: Extract payload of findQuery "+r)}function y(e,t,r,n){var i=n.constructor,a=e[r](t,i,n),o=d(e,i);return a.then(function(e){return e&&(e=o.extract(t,i,e,g(n,"id"),r)),t.didSaveRecord(n,e),n},function(e){throw e instanceof DS.InvalidError?t.recordWasInvalid(n,e.errors):t.recordWasError(n,e),e},"DS: Extract and notify about "+r+" completion of "+n)}var g=Ember.get,b=Ember.set,v=Ember.run.once,R=Ember.isNone,E=Ember.EnumerableUtils.forEach,S=Ember.EnumerableUtils.indexOf,D=Ember.EnumerableUtils.map,T=Ember.RSVP.resolve,A=Ember.copy,F=function(e){return null==e?null:e+""};DS.Store=Ember.Object.extend({init:function(){this.typeMaps={},this.recordArrayManager=DS.RecordArrayManager.create({store:this}),this._relationshipChanges={},this._pendingSave=[]},adapter:"_rest",serialize:function(e,t){return this.serializerFor(e.constructor.typeKey).serialize(e,t)},defaultAdapter:Ember.computed("adapter",function(){var e=g(this,"adapter");return"string"==typeof e&&(e=this.container.lookup("adapter:"+e)||this.container.lookup("adapter:application")||this.container.lookup("adapter:_rest")),DS.Adapter.detect(e)&&(e=e.create({container:this.container})),e}),createRecord:function(e,t){e=this.modelFor(e),t=A(t)||{},R(t.id)&&(t.id=this._generateId(e)),t.id=F(t.id);var r=this.buildRecord(e,t.id);return r.loadedData(),r.setProperties(t),r},_generateId:function(e){var t=this.adapterFor(e);return t&&t.generateIdForRecord?t.generateIdForRecord(this):null},deleteRecord:function(e){e.deleteRecord()},unloadRecord:function(e){e.unloadRecord()},find:function(e,t){return void 0===t?this.findAll(e):"object"===Ember.typeOf(t)?this.findQuery(e,t):this.findById(e,F(t))},findById:function(e,t){e=this.modelFor(e);var r=this.recordForId(e,t),n=this.fetchRecord(r)||T(r,"DS: Store#findById "+e+" with id: "+t);return a(n)},findByIds:function(e,t){var r=this;return o(Ember.RSVP.all(D(t,function(t){return r.findById(e,t)})).then(Ember.A,null,"DS: Store#findByIds of "+e+" complete"))},fetchRecord:function(e){if(R(e))return null;if(e._loadingPromise)return e._loadingPromise;if(!g(e,"isEmpty"))return null;var t=e.constructor,r=g(e,"id"),n=this.adapterFor(t),i=u(n,this,t,r);return e.loadingData(i),i},getById:function(e,t){return this.hasRecordForId(e,t)?this.recordForId(e,t):null},reloadRecord:function(e){var t=e.constructor,r=this.adapterFor(t),n=g(e,"id");return u(r,this,t,n)},fetchMany:function(e,t,r){if(e.length){var n=Ember.MapWithDefault.create({defaultValue:function(){return Ember.A()}});E(e,function(e){n.get(e.constructor).push(e)}),E(n,function(e,n){var i=n.mapProperty("id"),a=this.adapterFor(e);r.resolve(l(a,this,e,i,t))},this)}},hasRecordForId:function(e,t){return t=F(t),e=this.modelFor(e),!!this.typeMapFor(e).idToRecord[t]},recordForId:function(e,t){e=this.modelFor(e),t=F(t);var r=this.typeMapFor(e).idToRecord[t];return r||(r=this.buildRecord(e,t)),r},findMany:function(e,t,r,n){r=this.modelFor(r),t=Ember.A(t);var i=t.filterProperty("isEmpty",!0),a=this.recordArrayManager.createManyArray(r,t);return E(i,function(e){e.loadingData()}),a.loadingRecordsCount=i.length,i.length?(E(i,function(e){this.recordArrayManager.registerWaitingRecordArray(e,a)},this),this.fetchMany(i,e,n)):(n&&n.resolve(),a.set("isLoaded",!0),Ember.run.once(a,"trigger","didLoad")),a},findHasMany:function(e,t,r,n){var i=this.adapterFor(e.constructor),a=this.recordArrayManager.createManyArray(r.type,Ember.A([]));return n.resolve(h(i,this,e,t,r)),a},findBelongsTo:function(e,t,r,n){var i=this.adapterFor(e.constructor);n.resolve(f(i,this,e,t,r))},findQuery:function(e,t){e=this.modelFor(e);var r=this.recordArrayManager.createAdapterPopulatedRecordArray(e,t),n=this.adapterFor(e),i="DS: Store#findQuery "+e,a=Ember.RSVP.defer(i);return a.resolve(m(n,this,e,t,r)),o(a.promise)},findAll:function(e){return e=this.modelFor(e),this.fetchAll(e,this.all(e))},fetchAll:function(e,t){var r=this.adapterFor(e),n=this.typeMapFor(e).metadata.since;return b(t,"isUpdating",!0),o(p(r,this,e,n))},didUpdateAll:function(e){var t=this.typeMapFor(e).findAllCache;b(t,"isUpdating",!1)},all:function(e){e=this.modelFor(e);var t=this.typeMapFor(e),r=t.findAllCache;if(r)return r;var n=this.recordArrayManager.createRecordArray(e);return t.findAllCache=n,n},unloadAll:function(e){e=this.modelFor(e);for(var t,r=this.typeMapFor(e),n=r.records;t=n.pop();)t.unloadRecord();r.findAllCache=null},filter:function(e,t,r){var n;3===arguments.length?n=this.findQuery(e,t):2===arguments.length&&(r=t),e=this.modelFor(e);var i=this.recordArrayManager.createFilteredRecordArray(e,r);return n=n||T(i),o(n.then(function(){return i},null,"DS: Store#filter of "+e))},recordIsLoaded:function(e,t){return this.hasRecordForId(e,t)?!g(this.recordForId(e,t),"isEmpty"):!1},metadataFor:function(e){return e=this.modelFor(e),this.typeMapFor(e).metadata},dataWasUpdated:function(e,t){this.recordArrayManager.recordDidChange(t)},scheduleSave:function(e,t){e.adapterWillCommit(),this._pendingSave.push([e,t]),v(this,"flushPendingSave")},flushPendingSave:function(){var e=this._pendingSave.slice();this._pendingSave=[],E(e,function(e){var t,r=e[0],n=e[1],i=this.adapterFor(r.constructor);t=g(r,"isNew")?"createRecord":g(r,"isDeleted")?"deleteRecord":"updateRecord",n.resolve(y(i,this,t,r))},this)},didSaveRecord:function(t,r){r&&(r=e(this,t.constructor,r,t),this.updateId(t,r)),t.adapterDidCommit(r)},recordWasInvalid:function(e,t){e.adapterDidInvalidate(t)},recordWasError:function(e){e.adapterDidError()},updateId:function(e,t){var r=(g(e,"id"),F(t.id));this.typeMapFor(e.constructor).idToRecord[r]=e,b(e,"id",r)},typeMapFor:function(e){var t,r=g(this,"typeMaps"),n=Ember.guidFor(e);return(t=r[n])?t:(t={idToRecord:{},records:[],metadata:{}},r[n]=t,t)},_load:function(e,t,r){var n=F(t.id),i=this.recordForId(e,n);return i.setupData(t,r),this.recordArrayManager.recordDidChange(i),i},modelFor:function(e){var t;if("string"==typeof e){var r=this.container.normalize("model:"+e);if(t=this.container.lookupFactory(r),!t)throw new Ember.Error("No model was found for '"+e+"'");t.typeKey=r.split(":",2)[1]}else t=e;return t.store=this,t},push:function(t,r,n){return t=this.modelFor(t),r=e(this,t,r),this._load(t,r,n),this.recordForId(t,r.id)},pushPayload:function(e,t){var r;t?r=this.serializerFor(e):(t=e,r=c(this.container)),r.pushPayload(this,t)},update:function(e,t){return this.push(e,t,!0)},pushMany:function(e,t){return D(t,function(t){return this.push(e,t)},this)},metaForType:function(e,t){e=this.modelFor(e),Ember.merge(this.typeMapFor(e).metadata,t)},buildRecord:function(e,t,r){var n=this.typeMapFor(e),i=n.idToRecord,a=e._create({id:t,store:this,container:this.container});return r&&a.setupData(r),t&&(i[t]=a),n.records.push(a),a},dematerializeRecord:function(e){var t=e.constructor,r=this.typeMapFor(t),n=g(e,"id");e.updateRecordArrays(),n&&delete r.idToRecord[n];var i=S(r.records,e);r.records.splice(i,1)},addRelationshipChangeFor:function(e,t,r,n,i){var a=e.clientId,o=r?r:r,s=t+n,c=this._relationshipChanges;a in c||(c[a]={}),o in c[a]||(c[a][o]={}),s in c[a][o]||(c[a][o][s]={}),c[a][o][s][i.changeType]=i},removeRelationshipChangeFor:function(e,t,r,n,i){var a=e.clientId,o=r?r.clientId:r,s=this._relationshipChanges,c=t+n;a in s&&o in s[a]&&c in s[a][o]&&delete s[a][o][c][i]},relationshipChangePairsFor:function(e){var t=[];if(!e)return t;var r=this._relationshipChanges[e.clientId];for(var n in r)if(r.hasOwnProperty(n))for(var i in r[n])r[n].hasOwnProperty(i)&&t.push(r[n][i]);return t},adapterFor:function(e){var t,r=this.container;return r&&(t=r.lookup("adapter:"+e.typeKey)||r.lookup("adapter:application")),t||g(this,"defaultAdapter")},serializerFor:function(e){e=this.modelFor(e);var t=this.adapterFor(e);return s(this.container,e.typeKey,t&&t.defaultSerializer)}}),DS.PromiseArray=Ember.ArrayProxy.extend(Ember.PromiseProxyMixin),DS.PromiseObject=Ember.ObjectProxy.extend(Ember.PromiseProxyMixin)}(),function(){function e(t){var r,n={};for(var i in t)r=t[i],n[i]=r&&"object"==typeof r?e(r):r;return n}function t(e,t){for(var r in t)e[r]=t[r];return e}function r(r){var n=e(s);return t(n,r)}function n(e,r,i){e=t(r?Ember.create(r):{},e),e.parentState=r,e.stateName=i;for(var a in e)e.hasOwnProperty(a)&&"parentState"!==a&&"stateName"!==a&&"object"==typeof e[a]&&(e[a]=n(e[a],e,i+"."+a));return e}var i=Ember.get,a=Ember.set,o=function(e,t){t.value===t.originalValue?(delete e._attributes[t.name],e.send("propertyWasReset",t.name)):t.value!==t.oldValue&&e.send("becomeDirty"),e.updateRecordArraysLater()},s={initialState:"uncommitted",isDirty:!0,uncommitted:{didSetProperty:o,propertyWasReset:function(e){var t=!1;for(var r in e._attributes){t=!0;break}t||e.send("rolledBack")},pushedData:Ember.K,becomeDirty:Ember.K,willCommit:function(e){e.transitionTo("inFlight")},reloadRecord:function(e,t){t(i(e,"store").reloadRecord(e))},rolledBack:function(e){e.transitionTo("loaded.saved")},becameInvalid:function(e){e.transitionTo("invalid")},rollback:function(e){e.rollback()}},inFlight:{isSaving:!0,didSetProperty:o,becomeDirty:Ember.K,pushedData:Ember.K,willCommit:Ember.K,didCommit:function(e){var t=i(this,"dirtyType");e.transitionTo("saved"),e.send("invokeLifecycleCallbacks",t)},becameInvalid:function(e){e.transitionTo("invalid"),e.send("invokeLifecycleCallbacks")},becameError:function(e){e.transitionTo("uncommitted"),e.triggerLater("becameError",e)}},invalid:{isValid:!1,deleteRecord:function(e){e.transitionTo("deleted.uncommitted"),e.clearRelationships()},didSetProperty:function(e,t){i(e,"errors").remove(t.name),o(e,t)},becomeDirty:Ember.K,rolledBack:function(e){i(e,"errors").clear()},becameValid:function(e){e.transitionTo("uncommitted")},invokeLifecycleCallbacks:function(e){e.triggerLater("becameInvalid",e)}}},c=r({dirtyType:"created",isNew:!0});c.uncommitted.rolledBack=function(e){e.transitionTo("deleted.saved")};var d=r({dirtyType:"updated"});c.uncommitted.deleteRecord=function(e){e.clearRelationships(),e.transitionTo("deleted.saved")},c.uncommitted.rollback=function(e){s.uncommitted.rollback.apply(this,arguments),e.transitionTo("deleted.saved")},d.uncommitted.deleteRecord=function(e){e.transitionTo("deleted.uncommitted"),e.clearRelationships()};var u={isEmpty:!1,isLoading:!1,isLoaded:!1,isDirty:!1,isSaving:!1,isDeleted:!1,isNew:!1,isValid:!0,rolledBack:Ember.K,propertyWasReset:Ember.K,empty:{isEmpty:!0,loadingData:function(e,t){e._loadingPromise=t,e.transitionTo("loading")},loadedData:function(e){e.transitionTo("loaded.created.uncommitted"),e.suspendRelationshipObservers(function(){e.notifyPropertyChange("data")})},pushedData:function(e){e.transitionTo("loaded.saved"),e.triggerLater("didLoad")}},loading:{isLoading:!0,exit:function(e){e._loadingPromise=null},pushedData:function(e){e.transitionTo("loaded.saved"),e.triggerLater("didLoad"),a(e,"isError",!1)},becameError:function(e){e.triggerLater("becameError",e)},notFound:function(e){e.transitionTo("empty")}},loaded:{initialState:"saved",isLoaded:!0,saved:{setup:function(e){var t=e._attributes,r=!1;for(var n in t)if(t.hasOwnProperty(n)){r=!0;break}r&&e.adapterDidDirty()},didSetProperty:o,pushedData:Ember.K,becomeDirty:function(e){e.transitionTo("updated.uncommitted")},willCommit:function(e){e.transitionTo("updated.inFlight")},reloadRecord:function(e,t){t(i(e,"store").reloadRecord(e))},deleteRecord:function(e){e.transitionTo("deleted.uncommitted"),e.clearRelationships()},unloadRecord:function(e){e.clearRelationships(),e.transitionTo("deleted.saved")},didCommit:function(e){e.send("invokeLifecycleCallbacks",i(e,"lastDirtyType"))},notFound:Ember.K},created:c,updated:d},deleted:{initialState:"uncommitted",dirtyType:"deleted",isDeleted:!0,isLoaded:!0,isDirty:!0,setup:function(e){e.updateRecordArrays()},uncommitted:{willCommit:function(e){e.transitionTo("inFlight")},rollback:function(e){e.rollback()},becomeDirty:Ember.K,deleteRecord:Ember.K,rolledBack:function(e){e.transitionTo("loaded.saved")}},inFlight:{isSaving:!0,willCommit:Ember.K,didCommit:function(e){e.transitionTo("saved"),e.send("invokeLifecycleCallbacks")},becameError:function(e){e.transitionTo("uncommitted"),e.triggerLater("becameError",e)}},saved:{isDirty:!1,setup:function(e){var t=i(e,"store");t.dematerializeRecord(e)},invokeLifecycleCallbacks:function(e){e.triggerLater("didDelete",e),e.triggerLater("didCommit",e)}}},invokeLifecycleCallbacks:function(e,t){"created"===t?e.triggerLater("didCreate",e):e.triggerLater("didUpdate",e),e.triggerLater("didCommit",e)}};u=n(u,null,"root"),DS.RootState=u}(),function(){var e=Ember.get,t=Ember.isEmpty;DS.Errors=Ember.Object.extend(Ember.Enumerable,Ember.Evented,{registerHandlers:function(e,t,r){this.on("becameInvalid",e,t),this.on("becameValid",e,r)},errorsByAttributeName:Ember.reduceComputed("content",{initialValue:function(){return Ember.MapWithDefault.create({defaultValue:function(){return Ember.A()}})},addedItem:function(e,t){return e.get(t.attribute).pushObject(t),e},removedItem:function(e,t){return e.get(t.attribute).removeObject(t),e}}),errorsFor:function(t){return e(this,"errorsByAttributeName").get(t)},messages:Ember.computed.mapBy("content","message"),content:Ember.computed(function(){return Ember.A()}),unknownProperty:function(e){var r=this.errorsFor(e);return t(r)?null:r},nextObject:function(t){return e(this,"content").objectAt(t)},length:Ember.computed.oneWay("content.length").readOnly(),isEmpty:Ember.computed.not("length").readOnly(),add:function(t,r){var n=e(this,"isEmpty");r=this._findOrCreateMessages(t,r),e(this,"content").addObjects(r),this.notifyPropertyChange(t),this.enumerableContentDidChange(),n&&!e(this,"isEmpty")&&this.trigger("becameInvalid")},_findOrCreateMessages:function(e,t){var r=this.errorsFor(e);return Ember.makeArray(t).map(function(t){return r.findBy("message",t)||{attribute:e,message:t}})},remove:function(t){if(!e(this,"isEmpty")){var r=e(this,"content").rejectBy("attribute",t);e(this,"content").setObjects(r),this.notifyPropertyChange(t),this.enumerableContentDidChange(),e(this,"isEmpty")&&this.trigger("becameValid")}},clear:function(){e(this,"isEmpty")||(e(this,"content").clear(),this.enumerableContentDidChange(),this.trigger("becameValid"))},has:function(e){return!t(this.errorsFor(e))}})}(),function(){var e=Ember.get,t=Ember.set,r=Ember.merge,n=Ember.run.once,i=Ember.computed("currentState",function(t){return e(e(this,"currentState"),t)}).readOnly();DS.Model=Ember.Object.extend(Ember.Evented,{isEmpty:i,isLoading:i,isLoaded:i,isDirty:i,isSaving:i,isDeleted:i,isNew:i,isValid:i,dirtyType:i,isError:!1,isReloading:!1,clientId:null,id:null,transaction:null,currentState:null,errors:null,serialize:function(t){var r=e(this,"store");return r.serialize(this,t)},toJSON:function(e){var t=DS.JSONSerializer.create({container:this.container});return t.serialize(this,e)},didLoad:Ember.K,didUpdate:Ember.K,didCreate:Ember.K,didDelete:Ember.K,becameInvalid:Ember.K,becameError:Ember.K,data:Ember.computed(function(){return this._data=this._data||{},this._data}).property(),_data:null,init:function(){t(this,"currentState",DS.RootState.empty);var e=DS.Errors.create();e.registerHandlers(this,function(){this.send("becameInvalid")},function(){this.send("becameValid")}),t(this,"errors",e),this._super(),this._setup()},_setup:function(){this._changesToSync={},this._deferredTriggers=[],this._data={},this._attributes={},this._inFlightAttributes={},this._relationships={}},send:function(t,r){var n=e(this,"currentState");return n[t]||this._unhandledEvent(n,t,r),n[t](this,r)},transitionTo:function(r){var n=r.split(".",1),i=e(this,"currentState"),a=i;do a.exit&&a.exit(this),a=a.parentState;while(!a.hasOwnProperty(n));var o,s,c=r.split("."),d=[],u=[];for(o=0,s=c.length;s>o;o++)a=a[c[o]],a.enter&&u.push(a),a.setup&&d.push(a);for(o=0,s=u.length;s>o;o++)u[o].enter(this);for(t(this,"currentState",a),o=0,s=d.length;s>o;o++)d[o].setup(this);this.updateRecordArraysLater()},_unhandledEvent:function(e,t,r){var n="Attempted to handle event `"+t+"` ";throw n+="on "+String(this)+" while in state ",n+=e.stateName+". ",void 0!==r&&(n+="Called with "+Ember.inspect(r)+"."),new Ember.Error(n)},withTransaction:function(t){var r=e(this,"transaction");r&&t(r)},loadingData:function(e){this.send("loadingData",e)},loadedData:function(){this.send("loadedData")},notFound:function(){this.send("notFound")},pushedData:function(){this.send("pushedData")},deleteRecord:function(){this.send("deleteRecord")},destroyRecord:function(){return this.deleteRecord(),this.save()},unloadRecord:function(){this.send("unloadRecord")},clearRelationships:function(){this.eachRelationship(function(e,r){if("belongsTo"===r.kind)t(this,e,null);else if("hasMany"===r.kind){var n=this._relationships[r.name];n&&n.clear()}},this)},updateRecordArrays:function(){e(this,"store").dataWasUpdated(this.constructor,this)},changedAttributes:function(){var t,r=e(this,"_data"),n=e(this,"_attributes"),i={};for(t in n)i[t]=[r[t],n[t]];return i},adapterWillCommit:function(){this.send("willCommit")},adapterDidCommit:function(e){t(this,"isError",!1),e?this._data=e:Ember.mixin(this._data,this._inFlightAttributes),this._inFlightAttributes={},this.send("didCommit"),this.updateRecordArraysLater(),e&&this.suspendRelationshipObservers(function(){this.notifyPropertyChange("data")})},adapterDidDirty:function(){this.send("becomeDirty"),this.updateRecordArraysLater()},dataDidChange:Ember.observer(function(){this.reloadHasManys()},"data"),reloadHasManys:function(){var t=e(this.constructor,"relationshipsByName");this.updateRecordArraysLater(),t.forEach(function(e,t){this._data.links&&this._data.links[e]||"hasMany"===t.kind&&this.hasManyDidChange(t.key)},this)},hasManyDidChange:function(e){var r=this._relationships[e];if(r){var n=this._data[e]||[];t(r,"content",Ember.A(n)),t(r,"isLoaded",!0),r.trigger("didLoad")}},updateRecordArraysLater:function(){Ember.run.once(this,this.updateRecordArrays)},setupData:function(e,t){t?Ember.merge(this._data,e):this._data=e;var r=this._relationships;this.eachRelationship(function(t,n){e.links&&e.links[t]||n.options.async&&(r[t]=null)}),e&&this.pushedData(),this.suspendRelationshipObservers(function(){this.notifyPropertyChange("data")})},materializeId:function(e){t(this,"id",e)},materializeAttributes:function(e){r(this._data,e)},materializeAttribute:function(e,t){this._data[e]=t},updateHasMany:function(e,t){this._data[e]=t,this.hasManyDidChange(e)},updateBelongsTo:function(e,t){this._data[e]=t},rollback:function(){this._attributes={},e(this,"isError")&&(this._inFlightAttributes={},t(this,"isError",!1)),e(this,"isValid")||(this._inFlightAttributes={}),this.send("rolledBack"),this.suspendRelationshipObservers(function(){this.notifyPropertyChange("data")})},toStringExtension:function(){return e(this,"id")},suspendRelationshipObservers:function(t,r){var n=e(this.constructor,"relationshipNames").belongsTo,i=this;try{this._suspendedRelationships=!0,Ember._suspendObservers(i,n,null,"belongsToDidChange",function(){Ember._suspendBeforeObservers(i,n,null,"belongsToWillChange",function(){t.call(r||i)})})}finally{this._suspendedRelationships=!1}},save:function(){var e="DS: Model#save "+this,t=Ember.RSVP.defer(e);return this.get("store").scheduleSave(this,t),this._inFlightAttributes=this._attributes,this._attributes={},DS.PromiseObject.create({promise:t.promise})},reload:function(){t(this,"isReloading",!0);var e=this,r="DS: Model#reload of "+this,n=new Ember.RSVP.Promise(function(t){e.send("reloadRecord",t)},r).then(function(){return e.set("isReloading",!1),e.set("isError",!1),e},function(t){throw e.set("isError",!0),t},"DS: Model#reload complete, update flags");return DS.PromiseObject.create({promise:n})},adapterDidUpdateAttribute:function(e,t){void 0!==t?(this._data[e]=t,this.notifyPropertyChange(e)):this._data[e]=this._inFlightAttributes[e],this.updateRecordArraysLater()},adapterDidInvalidate:function(t){function r(e){t[e]&&n.add(e,t[e])}var n=e(this,"errors");this.eachAttribute(r),this.eachRelationship(r)},adapterDidError:function(){this.send("becameError"),t(this,"isError",!0)
9
+ },trigger:function(e){Ember.tryInvoke(this,e,[].slice.call(arguments,1)),this._super.apply(this,arguments)},triggerLater:function(){this._deferredTriggers.push(arguments),n(this,"_triggerDeferredTriggers")},_triggerDeferredTriggers:function(){for(var e=0,t=this._deferredTriggers.length;t>e;e++)this.trigger.apply(this,this._deferredTriggers[e]);this._deferredTriggers=[]}}),DS.Model.reopenClass({_create:DS.Model.create,create:function(){throw new Ember.Error("You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.")}})}(),function(){function e(e,t){return"function"==typeof t.defaultValue?t.defaultValue():t.defaultValue}function t(e,t){return e._attributes.hasOwnProperty(t)||e._inFlightAttributes.hasOwnProperty(t)||e._data.hasOwnProperty(t)}function r(e,t){return e._attributes.hasOwnProperty(t)?e._attributes[t]:e._inFlightAttributes.hasOwnProperty(t)?e._inFlightAttributes[t]:e._data[t]}var n=Ember.get;DS.Model.reopenClass({attributes:Ember.computed(function(){var e=Ember.Map.create();return this.eachComputedProperty(function(t,r){r.isAttribute&&(r.name=t,e.set(t,r))}),e}),transformedAttributes:Ember.computed(function(){var e=Ember.Map.create();return this.eachAttribute(function(t,r){r.type&&e.set(t,r.type)}),e}),eachAttribute:function(e,t){n(this,"attributes").forEach(function(r,n){e.call(t,r,n)},t)},eachTransformedAttribute:function(e,t){n(this,"transformedAttributes").forEach(function(r,n){e.call(t,r,n)})}}),DS.Model.reopen({eachAttribute:function(e,t){this.constructor.eachAttribute(e,t)}}),DS.attr=function(n,i){i=i||{};var a={type:n,isAttribute:!0,options:i};return Ember.computed(function(n,a){if(arguments.length>1){var o=this._attributes[n]||this._inFlightAttributes[n]||this._data[n];return this.send("didSetProperty",{name:n,oldValue:o,originalValue:this._data[n],value:a}),this._attributes[n]=a,a}return t(this,n)?r(this,n):e(this,i,n)}).property("data").meta(a)}}(),function(){var e=DS.AttributeChange=function(e){this.record=e.record,this.store=e.store,this.name=e.name,this.value=e.value,this.oldValue=e.oldValue};e.createChange=function(t){return new e(t)},e.prototype={sync:function(){this.value!==this.oldValue&&(this.record.send("becomeDirty"),this.record.updateRecordArraysLater()),this.destroy()},destroy:function(){delete this.record._changesToSync[this.name]}}}(),function(){function e(e){return"object"==typeof e&&(!e.then||"function"!=typeof e.then)}var t=Ember.get,r=Ember.set,n=Ember.EnumerableUtils.forEach;DS.RelationshipChange=function(e){this.parentRecord=e.parentRecord,this.childRecord=e.childRecord,this.firstRecord=e.firstRecord,this.firstRecordKind=e.firstRecordKind,this.firstRecordName=e.firstRecordName,this.secondRecord=e.secondRecord,this.secondRecordKind=e.secondRecordKind,this.secondRecordName=e.secondRecordName,this.changeType=e.changeType,this.store=e.store,this.committed={}},DS.RelationshipChangeAdd=function(e){DS.RelationshipChange.call(this,e)},DS.RelationshipChangeRemove=function(e){DS.RelationshipChange.call(this,e)},DS.RelationshipChange.create=function(e){return new DS.RelationshipChange(e)},DS.RelationshipChangeAdd.create=function(e){return new DS.RelationshipChangeAdd(e)},DS.RelationshipChangeRemove.create=function(e){return new DS.RelationshipChangeRemove(e)},DS.OneToManyChange={},DS.OneToNoneChange={},DS.ManyToNoneChange={},DS.OneToOneChange={},DS.ManyToManyChange={},DS.RelationshipChange._createChange=function(e){return"add"===e.changeType?DS.RelationshipChangeAdd.create(e):"remove"===e.changeType?DS.RelationshipChangeRemove.create(e):void 0},DS.RelationshipChange.determineRelationshipType=function(e,t){var r,n,i=t.key,a=t.kind,o=e.inverseFor(i);return o&&(r=o.name,n=o.kind),o?"belongsTo"===n?"belongsTo"===a?"oneToOne":"manyToOne":"belongsTo"===a?"oneToMany":"manyToMany":"belongsTo"===a?"oneToNone":"manyToNone"},DS.RelationshipChange.createChange=function(e,t,r,n){var i,a=e.constructor;return i=DS.RelationshipChange.determineRelationshipType(a,n),"oneToMany"===i?DS.OneToManyChange.createChange(e,t,r,n):"manyToOne"===i?DS.OneToManyChange.createChange(t,e,r,n):"oneToNone"===i?DS.OneToNoneChange.createChange(e,t,r,n):"manyToNone"===i?DS.ManyToNoneChange.createChange(e,t,r,n):"oneToOne"===i?DS.OneToOneChange.createChange(e,t,r,n):"manyToMany"===i?DS.ManyToManyChange.createChange(e,t,r,n):void 0},DS.OneToNoneChange.createChange=function(e,t,r,n){var i=n.key,a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,store:r,changeType:n.changeType,firstRecordName:i,firstRecordKind:"belongsTo"});return r.addRelationshipChangeFor(e,i,t,null,a),a},DS.ManyToNoneChange.createChange=function(e,t,r,n){var i=n.key,a=DS.RelationshipChange._createChange({parentRecord:e,childRecord:t,secondRecord:e,store:r,changeType:n.changeType,secondRecordName:n.key,secondRecordKind:"hasMany"});return r.addRelationshipChangeFor(e,i,t,null,a),a},DS.ManyToManyChange.createChange=function(e,t,r,n){var i=n.key,a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,secondRecord:t,firstRecordKind:"hasMany",secondRecordKind:"hasMany",store:r,changeType:n.changeType,firstRecordName:i});return r.addRelationshipChangeFor(e,i,t,null,a),a},DS.OneToOneChange.createChange=function(e,t,r,n){var i;n.parentType?i=n.parentType.inverseFor(n.key).name:n.key&&(i=n.key);var a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,secondRecord:t,firstRecordKind:"belongsTo",secondRecordKind:"belongsTo",store:r,changeType:n.changeType,firstRecordName:i});return r.addRelationshipChangeFor(e,i,t,null,a),a},DS.OneToOneChange.maintainInvariant=function(e,r,n,i){if("add"===e.changeType&&r.recordIsMaterialized(n)){var a=t(n,i);if(a){var o=DS.OneToOneChange.createChange(n,a,r,{parentType:e.parentType,hasManyName:e.hasManyName,changeType:"remove",key:e.key});r.addRelationshipChangeFor(n,i,e.parentRecord,null,o),o.sync()}}},DS.OneToManyChange.createChange=function(e,t,r,n){var i;n.parentType?(i=n.parentType.inverseFor(n.key).name,DS.OneToManyChange.maintainInvariant(n,r,e,i)):n.key&&(i=n.key);var a=DS.RelationshipChange._createChange({parentRecord:t,childRecord:e,firstRecord:e,secondRecord:t,firstRecordKind:"belongsTo",secondRecordKind:"hasMany",store:r,changeType:n.changeType,firstRecordName:i});return r.addRelationshipChangeFor(e,i,t,a.getSecondRecordName(),a),a},DS.OneToManyChange.maintainInvariant=function(e,r,n,i){if("add"===e.changeType&&n){var a=t(n,i);if(a){var o=DS.OneToManyChange.createChange(n,a,r,{parentType:e.parentType,hasManyName:e.hasManyName,changeType:"remove",key:e.key});r.addRelationshipChangeFor(n,i,e.parentRecord,o.getSecondRecordName(),o),o.sync()}}},DS.RelationshipChange.prototype={getSecondRecordName:function(){var e,t=this.secondRecordName;if(!t){if(e=this.secondRecord,!e)return;var r=this.firstRecord.constructor,n=r.inverseFor(this.firstRecordName);this.secondRecordName=n.name}return this.secondRecordName},getFirstRecordName:function(){var e=this.firstRecordName;return e},destroy:function(){var e=this.childRecord,t=this.getFirstRecordName(),r=this.getSecondRecordName(),n=this.store;n.removeRelationshipChangeFor(e,t,this.parentRecord,r,this.changeType)},getSecondRecord:function(){return this.secondRecord},getFirstRecord:function(){return this.firstRecord},coalesce:function(){var e=this.store.relationshipChangePairsFor(this.firstRecord);n(e,function(e){var t=e.add,r=e.remove;t&&r&&(t.destroy(),r.destroy())})}},DS.RelationshipChangeAdd.prototype=Ember.create(DS.RelationshipChange.create({})),DS.RelationshipChangeRemove.prototype=Ember.create(DS.RelationshipChange.create({})),DS.RelationshipChangeAdd.prototype.changeType="add",DS.RelationshipChangeAdd.prototype.sync=function(){var n=this.getSecondRecordName(),i=this.getFirstRecordName(),a=this.getFirstRecord(),o=this.getSecondRecord();o instanceof DS.Model&&a instanceof DS.Model&&("belongsTo"===this.secondRecordKind?o.suspendRelationshipObservers(function(){r(o,n,a)}):"hasMany"===this.secondRecordKind&&o.suspendRelationshipObservers(function(){var r=t(o,n);e(r)&&r.addObject(a)})),a instanceof DS.Model&&o instanceof DS.Model&&t(a,i)!==o&&("belongsTo"===this.firstRecordKind?a.suspendRelationshipObservers(function(){r(a,i,o)}):"hasMany"===this.firstRecordKind&&a.suspendRelationshipObservers(function(){var r=t(a,i);e(r)&&r.addObject(o)})),this.coalesce()},DS.RelationshipChangeRemove.prototype.changeType="remove",DS.RelationshipChangeRemove.prototype.sync=function(){var n=this.getSecondRecordName(),i=this.getFirstRecordName(),a=this.getFirstRecord(),o=this.getSecondRecord();o instanceof DS.Model&&a instanceof DS.Model&&("belongsTo"===this.secondRecordKind?o.suspendRelationshipObservers(function(){r(o,n,null)}):"hasMany"===this.secondRecordKind&&o.suspendRelationshipObservers(function(){var r=t(o,n);e(r)&&r.removeObject(a)})),a instanceof DS.Model&&t(a,i)&&("belongsTo"===this.firstRecordKind?a.suspendRelationshipObservers(function(){r(a,i,null)}):"hasMany"===this.firstRecordKind&&a.suspendRelationshipObservers(function(){var r=t(a,i);e(r)&&r.removeObject(o)})),this.coalesce()}}(),function(){function e(e,n,i){return Ember.computed(function(e,n){var a=t(this,"data"),o=t(this,"store"),s="DS: Async belongsTo "+this+" : "+e;if(2===arguments.length)return void 0===n?null:DS.PromiseObject.create({promise:Ember.RSVP.resolve(n,s)});var c=a.links&&a.links[e],d=a[e];if(r(d)){if(c){var u=Ember.RSVP.defer("DS: Async belongsTo (link) "+this+" : "+e);return o.findBelongsTo(this,c,i,u),DS.PromiseObject.create({promise:u.promise})}return null}var l=o.fetchRecord(d)||Ember.RSVP.resolve(d,s);return DS.PromiseObject.create({promise:l})}).property("data").meta(i)}var t=Ember.get,r=(Ember.set,Ember.isNone);DS.belongsTo=function(n,i){"object"==typeof n&&(i=n,n=void 0),i=i||{};var a={type:n,isRelationship:!0,options:i,kind:"belongsTo"};return i.async?e(n,i,a):Ember.computed(function(e,i){var a,o,s=t(this,"data"),c=t(this,"store");return o="string"==typeof n?c.modelFor(n):n,2===arguments.length?void 0===i?null:i:(a=s[e],r(a)?null:(c.fetchRecord(a),a))}).property("data").meta(a)},DS.Model.reopen({belongsToWillChange:Ember.beforeObserver(function(e,r){if(t(e,"isLoaded")){var n=t(e,r);if(n){var i=t(e,"store"),a=DS.RelationshipChange.createChange(e,n,i,{key:r,kind:"belongsTo",changeType:"remove"});a.sync(),this._changesToSync[r]=a}}}),belongsToDidChange:Ember.immediateObserver(function(e,r){if(t(e,"isLoaded")){var n=t(e,r);if(n){var i=t(e,"store"),a=DS.RelationshipChange.createChange(e,n,i,{key:r,kind:"belongsTo",changeType:"add"});a.sync()}}delete this._changesToSync[r]})})}(),function(){function e(e,r,n){return Ember.computed(function(e){var a=this._relationships[e],o="DS: Async hasMany "+this+" : "+e;if(!a){var s=Ember.RSVP.defer(o);a=t(this,e,r,function(t,r){var a,o=r.links&&r.links[e];return a=o?t.findHasMany(this,o,n,s):t.findMany(this,r[e],n.type,s),i(a,"promise",s.promise),a})}var c=a.get("promise").then(function(){return a},null,"DS: Async hasMany records received");return DS.PromiseArray.create({promise:c})}).property("data").meta(n)}function t(e,t,r,i){var o=e._relationships;if(o[t])return o[t];var s=n(e,"data"),c=n(e,"store"),d=o[t]=i.call(e,c,s);return a(d,{owner:e,name:t,isPolymorphic:r.polymorphic})}function r(r,n){n=n||{};var i={type:r,isRelationship:!0,options:n,kind:"hasMany"};return n.async?e(r,n,i):Ember.computed(function(e){return t(this,e,n,function(t,r){r[e];return t.findMany(this,r[e],i.type)})}).property("data").meta(i)}var n=Ember.get,i=Ember.set,a=Ember.setProperties;DS.hasMany=function(e,t){return"object"==typeof e&&(t=e,e=void 0),r(e,t)}}(),function(){{var e=Ember.get;Ember.set}DS.Model.reopen({didDefineProperty:function(e,t,r){if(r instanceof Ember.Descriptor){var n=r.meta();n.isRelationship&&"belongsTo"===n.kind&&(Ember.addObserver(e,t,null,"belongsToDidChange"),Ember.addBeforeObserver(e,t,null,"belongsToWillChange")),n.parentType=e.constructor}}}),DS.Model.reopenClass({typeForRelationship:function(t){var r=e(this,"relationshipsByName").get(t);return r&&r.type},inverseFor:function(t){function r(t,n,i){i=i||[];var a=e(n,"relationships");if(a){var o=a.get(t);return o&&i.push.apply(i,a.get(t)),t.superclass&&r(t.superclass,n,i),i}}var n=this.typeForRelationship(t);if(!n)return null;var i=this.metaForProperty(t).options;if(null===i.inverse)return null;var a,o;if(i.inverse)a=i.inverse,o=Ember.get(n,"relationshipsByName").get(a).kind;else{var s=r(this,n);if(0===s.length)return null;a=s[0].name,o=s[0].kind}return{type:n,name:a,kind:o}},relationships:Ember.computed(function(){var e=new Ember.MapWithDefault({defaultValue:function(){return[]}});return this.eachComputedProperty(function(t,r){if(r.isRelationship){"string"==typeof r.type&&(r.type=this.store.modelFor(r.type));var n=e.get(r.type);n.push({name:t,kind:r.kind})}}),e}),relationshipNames:Ember.computed(function(){var e={hasMany:[],belongsTo:[]};return this.eachComputedProperty(function(t,r){r.isRelationship&&e[r.kind].push(t)}),e}),relatedTypes:Ember.computed(function(){var t,r=Ember.A();return this.eachComputedProperty(function(n,i){i.isRelationship&&(t=i.type,"string"==typeof t&&(t=e(this,t,!1)||this.store.modelFor(t)),r.contains(t)||r.push(t))}),r}),relationshipsByName:Ember.computed(function(){var e,t=Ember.Map.create();return this.eachComputedProperty(function(r,n){n.isRelationship&&(n.key=r,e=n.type,e||"hasMany"!==n.kind?e||(e=r):e=Ember.String.singularize(r),"string"==typeof e&&(n.type=this.store.modelFor(e)),t.set(r,n))}),t}),fields:Ember.computed(function(){var e=Ember.Map.create();return this.eachComputedProperty(function(t,r){r.isRelationship?e.set(t,r.kind):r.isAttribute&&e.set(t,"attribute")}),e}),eachRelationship:function(t,r){e(this,"relationshipsByName").forEach(function(e,n){t.call(r,e,n)})},eachRelatedType:function(t,r){e(this,"relatedTypes").forEach(function(e){t.call(r,e)})}}),DS.Model.reopen({eachRelationship:function(e,t){this.constructor.eachRelationship(e,t)}})}(),function(){var e=Ember.get,t=(Ember.set,Ember.run.once),r=Ember.EnumerableUtils.forEach;DS.RecordArrayManager=Ember.Object.extend({init:function(){this.filteredRecordArrays=Ember.MapWithDefault.create({defaultValue:function(){return[]}}),this.changedRecords=[]},recordDidChange:function(e){this.changedRecords.push(e),t(this,this.updateRecordArrays)},recordArraysForRecord:function(e){return e._recordArrays=e._recordArrays||Ember.OrderedSet.create(),e._recordArrays},updateRecordArrays:function(){r(this.changedRecords,function(t){e(t,"isDeleted")?this._recordWasDeleted(t):this._recordWasChanged(t)},this),this.changedRecords=[]},_recordWasDeleted:function(e){var t=e._recordArrays;t&&r(t,function(t){t.removeRecord(e)})},_recordWasChanged:function(t){var n,i=t.constructor,a=this.filteredRecordArrays.get(i);r(a,function(r){n=e(r,"filterFunction"),this.updateRecordArray(r,n,i,t)},this);var o=t._loadingRecordArrays;if(o){for(var s=0,c=o.length;c>s;s++)o[s].loadedRecord();t._loadingRecordArrays=[]}},updateRecordArray:function(e,t,r,n){var i;i=t?t(n):!0;var a=this.recordArraysForRecord(n);i?(a.add(e),e.addRecord(n)):i||(a.remove(e),e.removeRecord(n))},updateFilter:function(t,r,n){for(var i,a=this.store.typeMapFor(r),o=a.records,s=0,c=o.length;c>s;s++)i=o[s],e(i,"isDeleted")||e(i,"isEmpty")||this.updateRecordArray(t,n,r,i)},createManyArray:function(e,t){var n=DS.ManyArray.create({type:e,content:t,store:this.store});return r(t,function(e){var t=this.recordArraysForRecord(e);t.add(n)},this),n},createRecordArray:function(e){var t=DS.RecordArray.create({type:e,content:Ember.A(),store:this.store,isLoaded:!0});return this.registerFilteredRecordArray(t,e),t},createFilteredRecordArray:function(e,t){var r=DS.FilteredRecordArray.create({type:e,content:Ember.A(),store:this.store,manager:this,filterFunction:t});return this.registerFilteredRecordArray(r,e,t),r},createAdapterPopulatedRecordArray:function(e,t){return DS.AdapterPopulatedRecordArray.create({type:e,query:t,content:Ember.A(),store:this.store})},registerFilteredRecordArray:function(e,t,r){var n=this.filteredRecordArrays.get(t);n.push(e),this.updateFilter(e,t,r)},registerWaitingRecordArray:function(e,t){var r=e._loadingRecordArrays||[];r.push(t),e._loadingRecordArrays=r}})}(),function(){var e=Ember.get,t=(Ember.set,Ember.ArrayPolyfills.map),r=["description","fileName","lineNumber","message","name","number","stack"];DS.InvalidError=function(e){var t=Error.prototype.constructor.call(this,"The backend rejected the commit because it was invalid: "+Ember.inspect(e));this.errors=e;for(var n=0,i=r.length;i>n;n++)this[r[n]]=t[r[n]]},DS.InvalidError.prototype=Ember.create(Error.prototype),DS.Adapter=Ember.Object.extend({find:Ember.required(Function),findAll:null,findQuery:null,generateIdForRecord:null,serialize:function(t,r){return e(t,"store").serializerFor(t.constructor.typeKey).serialize(t,r)},createRecord:Ember.required(Function),updateRecord:Ember.required(Function),deleteRecord:Ember.required(Function),findMany:function(e,r,n){var i=t.call(n,function(t){return this.find(e,r,t)},this);return Ember.RSVP.all(i)}})}(),function(){var e=Ember.get,t=Ember.String.fmt,r=Ember.EnumerableUtils.indexOf,n=0;DS.FixtureAdapter=DS.Adapter.extend({serializer:null,simulateRemoteResponse:!0,latency:50,fixturesForType:function(e){if(e.FIXTURES){var r=Ember.A(e.FIXTURES);return r.map(function(e){var r=typeof e.id;if("number"!==r&&"string"!==r)throw new Error(t("the id property must be defined as a number or string for fixture %@",[e]));return e.id=e.id+"",e})}return null},queryFixtures:function(){},updateFixtures:function(e,t){e.FIXTURES||(e.FIXTURES=[]);var r=e.FIXTURES;this.deleteLoadedFixture(e,t),r.push(t)},mockJSON:function(e,t,r){return e.serializerFor(t).serialize(r,{includeId:!0})},generateIdForRecord:function(){return"fixture-"+n++},find:function(e,t,r){var n,i=this.fixturesForType(t);return i&&(n=Ember.A(i).findProperty("id",r)),n?this.simulateRemoteCall(function(){return n},this):void 0},findMany:function(e,t,n){var i=this.fixturesForType(t);return i&&(i=i.filter(function(e){return-1!==r(n,e.id)})),i?this.simulateRemoteCall(function(){return i},this):void 0},findAll:function(e,t){var r=this.fixturesForType(t);return this.simulateRemoteCall(function(){return r},this)},findQuery:function(e,t,r){var n=this.fixturesForType(t);return n=this.queryFixtures(n,r,t),n?this.simulateRemoteCall(function(){return n},this):void 0},createRecord:function(e,t,r){var n=this.mockJSON(e,t,r);return this.updateFixtures(t,n),this.simulateRemoteCall(function(){return n},this)},updateRecord:function(e,t,r){var n=this.mockJSON(e,t,r);return this.updateFixtures(t,n),this.simulateRemoteCall(function(){return n},this)},deleteRecord:function(e,t,r){var n=this.mockJSON(e,t,r);return this.deleteLoadedFixture(t,n),this.simulateRemoteCall(function(){return null})},deleteLoadedFixture:function(e,t){var n=this.findExistingFixture(e,t);if(n){var i=r(e.FIXTURES,n);return e.FIXTURES.splice(i,1),!0}},findExistingFixture:function(t,r){var n=this.fixturesForType(t),i=e(r,"id");return this.findFixtureById(n,i)},findFixtureById:function(t,r){return Ember.A(t).find(function(t){return""+e(t,"id")==""+r?!0:!1})},simulateRemoteCall:function(t,r){var n=this;return new Ember.RSVP.Promise(function(i){e(n,"simulateRemoteResponse")?Ember.run.later(function(){i(t.call(r))},e(n,"latency")):Ember.run.schedule("actions",null,function(){i(t.call(r))})},"DS: FixtureAdapter#simulateRemoteCall")}})}(),function(){function e(e){return null==e?null:e+""}var t=Ember.get,r=(Ember.set,Ember.ArrayPolyfills.forEach),n=Ember.ArrayPolyfills.map;DS.RESTSerializer=DS.JSONSerializer.extend({normalize:function(e,t,r){return this.normalizeId(t),this.normalizeAttributes(e,t),this.normalizeRelationships(e,t),this.normalizeUsingDeclaredMapping(e,t),this.normalizeHash&&this.normalizeHash[r]&&this.normalizeHash[r](t),this._super(e,t,r)},normalizePayload:function(e,t){return t},normalizeId:function(e){var r=t(this,"primaryKey");"id"!==r&&(e.id=e[r],delete e[r])},normalizeUsingDeclaredMapping:function(e,r){var n,i,a=t(this,"attrs");if(a)for(i in a)n=a[i],n&&n.key&&(n=n.key),"string"==typeof n&&(r[i]=r[n],delete r[n])},normalizeAttributes:function(e,t){var r;this.keyForAttribute&&e.eachAttribute(function(e){r=this.keyForAttribute(e),e!==r&&(t[e]=t[r],delete t[r])},this)},normalizeRelationships:function(e,t){var r;this.keyForRelationship&&e.eachRelationship(function(e,n){r=this.keyForRelationship(e,n.kind),e!==r&&(t[e]=t[r],delete t[r])},this)},extractSingle:function(t,n,i,a){i=this.normalizePayload(n,i);var o,s=n.typeKey;for(var c in i){var d=this.typeForRoot(c),u=d===s;if(u&&"array"!==Ember.typeOf(i[c]))o=this.normalize(n,i[c],c);else{{t.modelFor(d)}r.call(i[c],function(r){var n=this.typeForRoot(c),i=t.modelFor(n),s=t.serializerFor(i);r=s.normalize(i,r,c);var d=u&&!a&&!o,l=u&&e(r.id)===a;d||l?o=r:t.push(n,r)},this)}}return o},extractArray:function(e,t,r){r=this.normalizePayload(t,r);var i,a=t.typeKey;for(var o in r){var s=o,c=!1;"_"===o.charAt(0)&&(c=!0,s=o.substr(1));var d=this.typeForRoot(s),u=e.modelFor(d),l=e.serializerFor(u),h=!c&&d===a,f=n.call(r[o],function(e){return l.normalize(u,e,o)},this);h?i=f:e.pushMany(d,f)}return i},pushPayload:function(e,t){t=this.normalizePayload(null,t);for(var r in t){var i=this.typeForRoot(r),a=e.modelFor(i),o=n.call(Ember.makeArray(t[r]),function(e){return this.normalize(a,e,r)},this);e.pushMany(i,o)}},typeForRoot:function(e){return Ember.String.singularize(e)},serialize:function(){return this._super.apply(this,arguments)},serializeIntoHash:function(e,t,r,n){e[t.typeKey]=this.serialize(r,n)},serializePolymorphicType:function(e,r,n){var i=n.key,a=t(e,i);i=this.keyForAttribute?this.keyForAttribute(i):i,r[i+"Type"]=a.constructor.typeKey}})}(),function(){var e=Ember.get,t=(Ember.set,Ember.ArrayPolyfills.forEach);DS.RESTAdapter=DS.Adapter.extend({defaultSerializer:"_rest",find:function(e,t,r){return this.ajax(this.buildURL(t.typeKey,r),"GET")},findAll:function(e,t,r){var n;return r&&(n={since:r}),this.ajax(this.buildURL(t.typeKey),"GET",{data:n})},findQuery:function(e,t,r){return this.ajax(this.buildURL(t.typeKey),"GET",{data:r})},findMany:function(e,t,r){return this.ajax(this.buildURL(t.typeKey),"GET",{data:{ids:r}})},findHasMany:function(t,r,n){var i=e(this,"host"),a=e(r,"id"),o=r.constructor.typeKey;return i&&"/"===n.charAt(0)&&"/"!==n.charAt(1)&&(n=i+n),this.ajax(this.urlPrefix(n,this.buildURL(o,a)),"GET")},findBelongsTo:function(t,r,n){var i=e(r,"id"),a=r.constructor.typeKey;return this.ajax(this.urlPrefix(n,this.buildURL(a,i)),"GET")},createRecord:function(e,t,r){var n={},i=e.serializerFor(t.typeKey);return i.serializeIntoHash(n,t,r,{includeId:!0}),this.ajax(this.buildURL(t.typeKey),"POST",{data:n})},updateRecord:function(t,r,n){var i={},a=t.serializerFor(r.typeKey);a.serializeIntoHash(i,r,n);var o=e(n,"id");return this.ajax(this.buildURL(r.typeKey,o),"PUT",{data:i})},deleteRecord:function(t,r,n){var i=e(n,"id");return this.ajax(this.buildURL(r.typeKey,i),"DELETE")},buildURL:function(t,r){var n=[],i=e(this,"host"),a=this.urlPrefix();return t&&n.push(this.pathForType(t)),r&&n.push(r),a&&n.unshift(a),n=n.join("/"),!i&&n&&(n="/"+n),n},urlPrefix:function(t,r){var n=e(this,"host"),i=e(this,"namespace"),a=[];return t?"/"===t.charAt(0)?n&&(t=t.slice(1),a.push(n)):/^http(s)?:\/\//.test(t)||a.push(r):(n&&a.push(n),i&&a.push(i)),t&&a.push(t),a.join("/")},pathForType:function(e){return Ember.String.pluralize(e)},ajaxError:function(e){return e&&(e.then=null),e},ajax:function(e,t,r){var n=this;return new Ember.RSVP.Promise(function(i,a){r=n.ajaxOptions(e,t,r),r.success=function(e){Ember.run(null,i,e)},r.error=function(e){Ember.run(null,a,n.ajaxError(e))},Ember.$.ajax(r)},"DS: RestAdapter#ajax "+t+" to "+e)},ajaxOptions:function(e,r,n){if(n=n||{},n.url=e,n.type=r,n.dataType="json",n.context=this,n.data&&"GET"!==r&&(n.contentType="application/json; charset=utf-8",n.data=JSON.stringify(n.data)),void 0!==this.headers){var i=this.headers;n.beforeSend=function(e){t.call(Ember.keys(i),function(t){e.setRequestHeader(t,i[t])})}}return n}})}(),function(){DS.Model.reopen({_debugInfo:function(){var e=["id"],t={belongsTo:[],hasMany:[]},r=[];this.eachAttribute(function(t){e.push(t)},this),this.eachRelationship(function(e,n){t[n.kind].push(e),r.push(e)});var n=[{name:"Attributes",properties:e,expand:!0},{name:"Belongs To",properties:t.belongsTo,expand:!0},{name:"Has Many",properties:t.hasMany,expand:!0},{name:"Flags",properties:["isLoaded","isDirty","isSaving","isDeleted","isError","isNew","isValid"]}];return{propertyInfo:{includeOtherProperties:!0,groups:n,expensiveProperties:r}}}})}(),function(){Ember.String.pluralize=function(e){return Ember.Inflector.inflector.pluralize(e)},Ember.String.singularize=function(e){return Ember.Inflector.inflector.singularize(e)}}(),function(){function e(e,t){for(var r=0,n=t.length;n>r;r++)e.uncountable[t[r].toLowerCase()]=!0}function t(e,t){for(var r,n=0,i=t.length;i>n;n++)r=t[n],e.irregular[r[0].toLowerCase()]=r[1],e.irregularInverse[r[1].toLowerCase()]=r[0]}function r(r){r=r||{},r.uncountable=r.uncountable||{},r.irregularPairs=r.irregularPairs||{};var n=this.rules={plurals:r.plurals||[],singular:r.singular||[],irregular:{},irregularInverse:{},uncountable:{}};e(n,r.uncountable),t(n,r.irregularPairs)}var n=/^\s*$/;r.prototype={plural:function(e,t){this.rules.plurals.push([e,t.toLowerCase()])},singular:function(e,t){this.rules.singular.push([e,t.toLowerCase()])},uncountable:function(t){e(this.rules,[t.toLowerCase()])},irregular:function(e,r){t(this.rules,[[e,r]])},pluralize:function(e){return this.inflect(e,this.rules.plurals,this.rules.irregular)},singularize:function(e){return this.inflect(e,this.rules.singular,this.rules.irregularInverse)},inflect:function(e,t,r){var i,a,o,s,c,d,u,l;if(c=n.test(e))return e;if(s=e.toLowerCase(),d=this.rules.uncountable[s])return e;if(u=r&&r[s])return u;for(var h=t.length,f=0;h>f&&(i=t[h-1],l=i[0],!l.test(e));h--);return i=i||[],l=i[0],a=i[1],o=e.replace(l,a)}},Ember.Inflector=r}(),function(){Ember.Inflector.defaultRules={plurals:[[/$/,"s"],[/s$/i,"s"],[/^(ax|test)is$/i,"$1es"],[/(octop|vir)us$/i,"$1i"],[/(octop|vir)i$/i,"$1i"],[/(alias|status)$/i,"$1es"],[/(bu)s$/i,"$1ses"],[/(buffal|tomat)o$/i,"$1oes"],[/([ti])um$/i,"$1a"],[/([ti])a$/i,"$1a"],[/sis$/i,"ses"],[/(?:([^f])fe|([lr])f)$/i,"$1$2ves"],[/(hive)$/i,"$1s"],[/([^aeiouy]|qu)y$/i,"$1ies"],[/(x|ch|ss|sh)$/i,"$1es"],[/(matr|vert|ind)(?:ix|ex)$/i,"$1ices"],[/^(m|l)ouse$/i,"$1ice"],[/^(m|l)ice$/i,"$1ice"],[/^(ox)$/i,"$1en"],[/^(oxen)$/i,"$1"],[/(quiz)$/i,"$1zes"]],singular:[[/s$/i,""],[/(ss)$/i,"$1"],[/(n)ews$/i,"$1ews"],[/([ti])a$/i,"$1um"],[/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i,"$1sis"],[/(^analy)(sis|ses)$/i,"$1sis"],[/([^f])ves$/i,"$1fe"],[/(hive)s$/i,"$1"],[/(tive)s$/i,"$1"],[/([lr])ves$/i,"$1f"],[/([^aeiouy]|qu)ies$/i,"$1y"],[/(s)eries$/i,"$1eries"],[/(m)ovies$/i,"$1ovie"],[/(x|ch|ss|sh)es$/i,"$1"],[/^(m|l)ice$/i,"$1ouse"],[/(bus)(es)?$/i,"$1"],[/(o)es$/i,"$1"],[/(shoe)s$/i,"$1"],[/(cris|test)(is|es)$/i,"$1is"],[/^(a)x[ie]s$/i,"$1xis"],[/(octop|vir)(us|i)$/i,"$1us"],[/(alias|status)(es)?$/i,"$1"],[/^(ox)en/i,"$1"],[/(vert|ind)ices$/i,"$1ex"],[/(matr)ices$/i,"$1ix"],[/(quiz)zes$/i,"$1"],[/(database)s$/i,"$1"]],irregularPairs:[["person","people"],["man","men"],["child","children"],["sex","sexes"],["move","moves"],["cow","kine"],["zombie","zombies"]],uncountable:["equipment","information","rice","money","species","series","fish","sheep","jeans","police"]}}(),function(){(Ember.EXTEND_PROTOTYPES===!0||Ember.EXTEND_PROTOTYPES.String)&&(String.prototype.pluralize=function(){return Ember.String.pluralize(this)},String.prototype.singularize=function(){return Ember.String.singularize(this)})}(),function(){Ember.Inflector.inflector=new Ember.Inflector(Ember.Inflector.defaultRules)}(),function(){var e=Ember.get,t=Ember.EnumerableUtils.forEach;DS.ActiveModelSerializer=DS.RESTSerializer.extend({keyForAttribute:function(e){return Ember.String.decamelize(e)},keyForRelationship:function(e,t){return e=Ember.String.decamelize(e),"belongsTo"===t?e+"_id":"hasMany"===t?Ember.String.singularize(e)+"_ids":e},serializeHasMany:Ember.K,serializeIntoHash:function(e,t,r,n){var i=Ember.String.decamelize(t.typeKey);e[i]=this.serialize(r,n)},serializePolymorphicType:function(t,r,n){var i=n.key,a=e(t,i);i=this.keyForAttribute(i),r[i+"_type"]=Ember.String.capitalize(a.constructor.typeKey)},typeForRoot:function(e){var t=Ember.String.camelize(e);return Ember.String.singularize(t)},normalize:function(e,t,r){return this.normalizeLinks(t),this._super(e,t,r)},normalizeLinks:function(e){if(e.links){var t=e.links;for(var r in t){var n=Ember.String.camelize(r);n!==r&&(t[n]=t[r],delete t[r])}}},normalizeRelationships:function(e,r){var n,i;this.keyForRelationship&&e.eachRelationship(function(e,a){if(a.options.polymorphic){if(n=this.keyForAttribute(e),i=r[n],i&&i.type)i.type=this.typeForRoot(i.type);else if(i&&"hasMany"===a.kind){var o=this;t(i,function(e){e.type=o.typeForRoot(e.type)})}}else n=this.keyForRelationship(e,a.kind),i=r[n];r[e]=i,e!==n&&delete r[n]},this)}})}(),function(){function e(n,i,a,o,s){var c=t(i,"attrs");c&&a.eachRelationship(function(i,a){var d,u,l,h,f=c[i],p=n.serializerFor(a.type.typeKey),m=t(p,"primaryKey");if("hasMany"===a.kind&&f&&("always"===f.embedded||"load"===f.embedded)){if(u="_"+Ember.String.pluralize(a.type.typeKey),d=this.keyForRelationship(i,a.kind),l=this.keyForAttribute(i),h=[],!o[l])return;s[u]=s[u]||[],r(o[l],function(t){var r=n.modelFor(a.type.typeKey);e(n,p,r,t,s),h.push(t[m]),s[u].push(t)}),o[d]=h,delete o[l]}},i)}var t=Ember.get,r=Ember.EnumerableUtils.forEach;DS.EmbeddedRecordsMixin=Ember.Mixin.create({serializeHasMany:function(e,r,n){var i=n.key,a=t(this,"attrs"),o=a&&a[i]&&"always"===a[i].embedded;o&&(r[this.keyForAttribute(i)]=t(e,i).map(function(e){var r=e.serialize(),n=t(this,"primaryKey");return r[n]=t(e,n),r},this))},extractSingle:function(t,r,n,i,a){var o=this.keyForAttribute(r.typeKey),s=n[o];return e(t,this,r,s,n),this._super(t,r,n,i,a)},extractArray:function(t,n,i){var a=this.keyForAttribute(n.typeKey),o=i[Ember.String.pluralize(a)];return r(o,function(r){e(t,this,n,r,i)},this),this._super(t,n,i)}})}(),function(){var e=Ember.EnumerableUtils.forEach;DS.ActiveModelAdapter=DS.RESTAdapter.extend({defaultSerializer:"_ams",pathForType:function(e){var t=Ember.String.decamelize(e);return Ember.String.pluralize(t)},ajaxError:function(t){var r=this._super(t);if(t&&422===t.status){var n=Ember.$.parseJSON(t.responseText).errors,i={};return e(Ember.keys(n),function(e){i[Ember.String.camelize(e)]=n[e]}),new DS.InvalidError(i)}return r}})}(),function(){Ember.onLoad("Ember.Application",function(e){e.initializer({name:"activeModelAdapter",initialize:function(e,t){t.register("serializer:_ams",DS.ActiveModelSerializer),t.register("adapter:_ams",DS.ActiveModelAdapter)}})})}()}(),"undefined"==typeof location||"localhost"!==location.hostname&&"127.0.0.1"!==location.hostname||Ember.Logger.warn("You are running a production build of Ember on localhost and won't receive detailed error messages. If you want full error messages please use the non-minified build provided on the Ember website.");
@@ -1,13 +1,12 @@
1
1
  /*!
2
2
  * @overview Ember Data
3
- * @copyright Copyright 2011-2013 Tilde Inc. and contributors.
3
+ * @copyright Copyright 2011-2014 Tilde Inc. and contributors.
4
4
  * Portions Copyright 2011 LivingSocial Inc.
5
5
  * @license Licensed under MIT license (see license.js)
6
+ * @version 1.0.0-beta.5
6
7
  */
7
8
 
8
9
 
9
- // Version: 1.0.0-beta.4
10
-
11
10
  (function() {
12
11
  var define, requireModule;
13
12
 
@@ -60,8 +59,14 @@ var define, requireModule;
60
59
  */
61
60
  var DS;
62
61
  if ('undefined' === typeof DS) {
62
+ /**
63
+ @property VERSION
64
+ @type String
65
+ @default '1.0.0-beta.5'
66
+ @static
67
+ */
63
68
  DS = Ember.Namespace.create({
64
- VERSION: '1.0.0-beta.4'
69
+ VERSION: '1.0.0-beta.5'
65
70
  });
66
71
 
67
72
  if ('undefined' !== typeof window) {
@@ -122,6 +127,7 @@ DS.JSONSerializer = Ember.Object.extend({
122
127
 
123
128
  @property primaryKey
124
129
  @type {String}
130
+ @default 'id'
125
131
  */
126
132
  primaryKey: 'id',
127
133
 
@@ -164,11 +170,13 @@ DS.JSONSerializer = Ember.Object.extend({
164
170
  ```javascript
165
171
  App.ApplicationSerializer = DS.JSONSerializer.extend({
166
172
  normalize: function(type, hash) {
167
- var normalizedHash = {};
168
173
  var fields = Ember.get(type, 'fields');
169
174
  fields.forEach(function(field) {
170
- var normalizedProp = Ember.String.camelize(field);
171
- normalizedHash[normalizedProp] = hash[field];
175
+ var payloadField = Ember.String.underscore(field);
176
+ if (field === payloadField) { return; }
177
+
178
+ hash[field] = hash[payloadField];
179
+ delete hash[payloadField];
172
180
  });
173
181
  return this._super.apply(this, arguments);
174
182
  }
@@ -338,7 +346,7 @@ DS.JSONSerializer = Ember.Object.extend({
338
346
  var id = get(record, 'id');
339
347
 
340
348
  if (id) {
341
- json[get(this, 'primaryKey')] = get(record, 'id');
349
+ json[get(this, 'primaryKey')] = id;
342
350
  }
343
351
  }
344
352
 
@@ -747,6 +755,26 @@ DS.JSONSerializer = Ember.Object.extend({
747
755
  }
748
756
  },
749
757
 
758
+ /**
759
+ `keyForAttribute` can be used to define rules for how to convert an
760
+ attribute name in your model to a key in your JSON.
761
+
762
+ Example
763
+
764
+ ```javascript
765
+ App.ApplicationSerializer = DS.RESTSerializer.extend({
766
+ keyForAttribute: function(attr) {
767
+ return Ember.String.underscore(attr).toUpperCase();
768
+ }
769
+ });
770
+ ```
771
+
772
+ @method keyForAttribute
773
+ @param {String} key
774
+ @return {String} normalized key
775
+ */
776
+
777
+
750
778
  /**
751
779
  `keyForRelationship` can be used to define a custom key when
752
780
  serializeing relationship properties. By default `JSONSerializer`
@@ -968,7 +996,7 @@ DS.Transform = Ember.Object.extend({
968
996
  }
969
997
  ```
970
998
 
971
- @method deserialized
999
+ @method deserialize
972
1000
  @param serialized The serialized value
973
1001
  @return The deserialized value
974
1002
  */
@@ -1359,7 +1387,7 @@ var get = Ember.get, set = Ember.set;
1359
1387
  A record array is an array that contains records of a certain type. The record
1360
1388
  array materializes records as needed when they are retrieved for the first
1361
1389
  time. You should not create record arrays yourself. Instead, an instance of
1362
- DS.RecordArray or its subclasses will be returned by your application's store
1390
+ `DS.RecordArray` or its subclasses will be returned by your application's store
1363
1391
  in response to queries.
1364
1392
 
1365
1393
  @class RecordArray
@@ -1377,24 +1405,87 @@ DS.RecordArray = Ember.ArrayProxy.extend(Ember.Evented, {
1377
1405
  */
1378
1406
  type: null,
1379
1407
 
1380
- // The array of client ids backing the record array. When a
1381
- // record is requested from the record array, the record
1382
- // for the client id at the same index is materialized, if
1383
- // necessary, by the store.
1408
+ /**
1409
+ The array of client ids backing the record array. When a
1410
+ record is requested from the record array, the record
1411
+ for the client id at the same index is materialized, if
1412
+ necessary, by the store.
1413
+
1414
+ @property content
1415
+ @private
1416
+ @type Ember.Array
1417
+ */
1384
1418
  content: null,
1385
1419
 
1420
+ /**
1421
+ The flag to signal a `RecordArray` is currently loading data.
1422
+
1423
+ Example
1424
+
1425
+ ```javascript
1426
+ var people = store.all(App.Person);
1427
+ people.get('isLoaded'); // true
1428
+ ```
1429
+
1430
+ @property isLoaded
1431
+ @type Boolean
1432
+ */
1386
1433
  isLoaded: false,
1434
+ /**
1435
+ The flag to signal a `RecordArray` is currently loading data.
1436
+
1437
+ Example
1438
+
1439
+ ```javascript
1440
+ var people = store.all(App.Person);
1441
+ people.get('isUpdating'); // false
1442
+ people.update();
1443
+ people.get('isUpdating'); // true
1444
+ ```
1445
+
1446
+ @property isUpdating
1447
+ @type Boolean
1448
+ */
1387
1449
  isUpdating: false,
1388
1450
 
1389
- // The store that created this record array.
1451
+ /**
1452
+ The store that created this record array.
1453
+
1454
+ @property store
1455
+ @private
1456
+ @type DS.Store
1457
+ */
1390
1458
  store: null,
1391
1459
 
1460
+ /**
1461
+ Retrieves an object from the content by index.
1462
+
1463
+ @method objectAtContent
1464
+ @private
1465
+ @param {Number} index
1466
+ @return {DS.Model} record
1467
+ */
1392
1468
  objectAtContent: function(index) {
1393
1469
  var content = get(this, 'content');
1394
1470
 
1395
1471
  return content.objectAt(index);
1396
1472
  },
1397
1473
 
1474
+ /**
1475
+ Used to get the latest version of all of the records in this array
1476
+ from the adapter.
1477
+
1478
+ Example
1479
+
1480
+ ```javascript
1481
+ var people = store.all(App.Person);
1482
+ people.get('isUpdating'); // false
1483
+ people.update();
1484
+ people.get('isUpdating'); // true
1485
+ ```
1486
+
1487
+ @method update
1488
+ */
1398
1489
  update: function() {
1399
1490
  if (get(this, 'isUpdating')) { return; }
1400
1491
 
@@ -1404,14 +1495,44 @@ DS.RecordArray = Ember.ArrayProxy.extend(Ember.Evented, {
1404
1495
  store.fetchAll(type, this);
1405
1496
  },
1406
1497
 
1498
+ /**
1499
+ Adds a record to the `RecordArray`.
1500
+
1501
+ @method addRecord
1502
+ @private
1503
+ @param {DS.Model} record
1504
+ */
1407
1505
  addRecord: function(record) {
1408
1506
  get(this, 'content').addObject(record);
1409
1507
  },
1410
1508
 
1509
+ /**
1510
+ Removes a record to the `RecordArray`.
1511
+
1512
+ @method removeRecord
1513
+ @private
1514
+ @param {DS.Model} record
1515
+ */
1411
1516
  removeRecord: function(record) {
1412
1517
  get(this, 'content').removeObject(record);
1413
1518
  },
1414
1519
 
1520
+ /**
1521
+ Saves all of the records in the `RecordArray`.
1522
+
1523
+ Example
1524
+
1525
+ ```javascript
1526
+ var messages = store.all(App.Message);
1527
+ messages.forEach(function(message) {
1528
+ message.set('hasBeenSeen', true);
1529
+ });
1530
+ messages.save();
1531
+ ```
1532
+
1533
+ @method save
1534
+ @return {DS.PromiseArray} promise
1535
+ */
1415
1536
  save: function() {
1416
1537
  var promiseLabel = "DS: RecordArray#save " + get(this, 'type');
1417
1538
  var promise = Ember.RSVP.all(this.invoke("save"), promiseLabel).then(function(array) {
@@ -1434,11 +1555,42 @@ DS.RecordArray = Ember.ArrayProxy.extend(Ember.Evented, {
1434
1555
  var get = Ember.get;
1435
1556
 
1436
1557
  /**
1558
+ Represents a list of records whose membership is determined by the
1559
+ store. As records are created, loaded, or modified, the store
1560
+ evaluates them to determine if they should be part of the record
1561
+ array.
1562
+
1437
1563
  @class FilteredRecordArray
1438
1564
  @namespace DS
1439
1565
  @extends DS.RecordArray
1440
1566
  */
1441
1567
  DS.FilteredRecordArray = DS.RecordArray.extend({
1568
+ /**
1569
+ The filterFunction is a function used to test records from the store to
1570
+ determine if they should be part of the record array.
1571
+
1572
+ Example
1573
+
1574
+ ```javascript
1575
+ var allPeople = store.all('person');
1576
+ allPeople.mapBy('name'); // ["Tom Dale", "Yehuda Katz", "Trek Glowacki"]
1577
+
1578
+ var people = store.filter('person', function(person) {
1579
+ if (person.get('name').match(/Katz$/)) { return true; }
1580
+ });
1581
+ people.mapBy('name'); // ["Yehuda Katz"]
1582
+
1583
+ var notKatzFilter = function(person) {
1584
+ return !person.get('name').match(/Katz$/);
1585
+ };
1586
+ people.set('filterFunction', notKatzFilter);
1587
+ people.mapBy('name'); // ["Tom Dale", "Trek Glowacki"]
1588
+ ```
1589
+
1590
+ @method filterFunction
1591
+ @param {DS.Model} record
1592
+ @return {Boolean} `true` if the record should be in the array
1593
+ */
1442
1594
  filterFunction: null,
1443
1595
  isLoaded: true,
1444
1596
 
@@ -1447,6 +1599,10 @@ DS.FilteredRecordArray = DS.RecordArray.extend({
1447
1599
  throw new Error("The result of a client-side filter (on " + type + ") is immutable.");
1448
1600
  },
1449
1601
 
1602
+ /**
1603
+ @method updateFilter
1604
+ @private
1605
+ */
1450
1606
  updateFilter: Ember.observer(function() {
1451
1607
  var manager = get(this, 'manager');
1452
1608
  manager.updateFilter(this, get(this, 'type'), get(this, 'filterFunction'));
@@ -1465,6 +1621,11 @@ DS.FilteredRecordArray = DS.RecordArray.extend({
1465
1621
  var get = Ember.get, set = Ember.set;
1466
1622
 
1467
1623
  /**
1624
+ Represents an ordered list of records whose order and membership is
1625
+ determined by the adapter. For example, a query sent to the adapter
1626
+ may trigger a search on the server, whose results would be loaded
1627
+ into an instance of the `AdapterPopulatedRecordArray`.
1628
+
1468
1629
  @class AdapterPopulatedRecordArray
1469
1630
  @namespace DS
1470
1631
  @extends DS.RecordArray
@@ -1477,6 +1638,11 @@ DS.AdapterPopulatedRecordArray = DS.RecordArray.extend({
1477
1638
  throw new Error("The result of a server query (on " + type + ") is immutable.");
1478
1639
  },
1479
1640
 
1641
+ /**
1642
+ @method load
1643
+ @private
1644
+ @param {Array} data
1645
+ */
1480
1646
  load: function(data) {
1481
1647
  var store = get(this, 'store'),
1482
1648
  type = get(this, 'type'),
@@ -1507,10 +1673,10 @@ var get = Ember.get, set = Ember.set;
1507
1673
  var map = Ember.EnumerableUtils.map;
1508
1674
 
1509
1675
  /**
1510
- A ManyArray is a RecordArray that represents the contents of a has-many
1676
+ A `ManyArray` is a `RecordArray` that represents the contents of a has-many
1511
1677
  relationship.
1512
1678
 
1513
- The ManyArray is instantiated lazily the first time the relationship is
1679
+ The `ManyArray` is instantiated lazily the first time the relationship is
1514
1680
  requested.
1515
1681
 
1516
1682
  ### Inverses
@@ -1519,13 +1685,15 @@ var map = Ember.EnumerableUtils.map;
1519
1685
  an inverse. For example, imagine the following models are
1520
1686
  defined:
1521
1687
 
1522
- App.Post = DS.Model.extend({
1523
- comments: DS.hasMany('comment')
1524
- });
1688
+ ```javascript
1689
+ App.Post = DS.Model.extend({
1690
+ comments: DS.hasMany('comment')
1691
+ });
1525
1692
 
1526
- App.Comment = DS.Model.extend({
1527
- post: DS.belongsTo('post')
1528
- });
1693
+ App.Comment = DS.Model.extend({
1694
+ post: DS.belongsTo('post')
1695
+ });
1696
+ ```
1529
1697
 
1530
1698
  If you created a new instance of `App.Post` and added
1531
1699
  a `App.Comment` record to its `comments` has-many
@@ -1549,7 +1717,7 @@ DS.ManyArray = DS.RecordArray.extend({
1549
1717
  /**
1550
1718
  The property name of the relationship
1551
1719
 
1552
- @property {String}
1720
+ @property {String} name
1553
1721
  @private
1554
1722
  */
1555
1723
  name: null,
@@ -1557,7 +1725,7 @@ DS.ManyArray = DS.RecordArray.extend({
1557
1725
  /**
1558
1726
  The record to which this relationship belongs.
1559
1727
 
1560
- @property {DS.Model}
1728
+ @property {DS.Model} owner
1561
1729
  @private
1562
1730
  */
1563
1731
  owner: null,
@@ -1565,7 +1733,7 @@ DS.ManyArray = DS.RecordArray.extend({
1565
1733
  /**
1566
1734
  `true` if the relationship is polymorphic, `false` otherwise.
1567
1735
 
1568
- @property {Boolean}
1736
+ @property {Boolean} isPolymorphic
1569
1737
  @private
1570
1738
  */
1571
1739
  isPolymorphic: false,
@@ -1578,15 +1746,24 @@ DS.ManyArray = DS.RecordArray.extend({
1578
1746
  Used for async `hasMany` arrays
1579
1747
  to keep track of when they will resolve.
1580
1748
 
1581
- @property {Ember.RSVP.Promise}
1749
+ @property {Ember.RSVP.Promise} promise
1582
1750
  @private
1583
1751
  */
1584
1752
  promise: null,
1585
1753
 
1754
+ /**
1755
+ @method loadingRecordsCount
1756
+ @param {Number} count
1757
+ @private
1758
+ */
1586
1759
  loadingRecordsCount: function(count) {
1587
1760
  this.loadingRecordsCount = count;
1588
1761
  },
1589
1762
 
1763
+ /**
1764
+ @method loadedRecord
1765
+ @private
1766
+ */
1590
1767
  loadedRecord: function() {
1591
1768
  this.loadingRecordsCount--;
1592
1769
  if (this.loadingRecordsCount === 0) {
@@ -1595,6 +1772,10 @@ DS.ManyArray = DS.RecordArray.extend({
1595
1772
  }
1596
1773
  },
1597
1774
 
1775
+ /**
1776
+ @method fetch
1777
+ @private
1778
+ */
1598
1779
  fetch: function() {
1599
1780
  var records = get(this, 'content'),
1600
1781
  store = get(this, 'store'),
@@ -1690,7 +1871,14 @@ DS.ManyArray = DS.RecordArray.extend({
1690
1871
  }
1691
1872
  },
1692
1873
 
1693
- // Create a child record within the owner
1874
+ /**
1875
+ Create a child record within the owner
1876
+
1877
+ @method createRecord
1878
+ @private
1879
+ @param {Object} hash
1880
+ @return {DS.Model} record
1881
+ */
1694
1882
  createRecord: function(hash) {
1695
1883
  var owner = get(this, 'owner'),
1696
1884
  store = get(owner, 'store'),
@@ -1762,7 +1950,7 @@ var coerceId = function(id) {
1762
1950
 
1763
1951
  /**
1764
1952
  The store contains all of the data for records loaded from the server.
1765
- It is also responsible for creating instances of DS.Model that wrap
1953
+ It is also responsible for creating instances of `DS.Model` that wrap
1766
1954
  the individual data for a record, so that they can be bound to in your
1767
1955
  Handlebars templates.
1768
1956
 
@@ -1776,10 +1964,10 @@ var coerceId = function(id) {
1776
1964
  automatically created by their `Ember.Application`.
1777
1965
 
1778
1966
  You can retrieve models from the store in several ways. To retrieve a record
1779
- for a specific id, use `DS.Model`'s `find()` method:
1967
+ for a specific id, use `DS.Store`'s `find()` method:
1780
1968
 
1781
1969
  ```javascript
1782
- var person = App.Person.find(123);
1970
+ var person = store.find('person', 123);
1783
1971
  ```
1784
1972
 
1785
1973
  If your application has multiple `DS.Store` instances (an unusual case), you can
@@ -1789,11 +1977,9 @@ var coerceId = function(id) {
1789
1977
  var person = store.find(App.Person, 123);
1790
1978
  ```
1791
1979
 
1792
- In general, you should retrieve models using the methods on `DS.Model`; you should
1793
- rarely need to interact with the store directly.
1794
-
1795
- By default, the store will talk to your backend using a standard REST mechanism.
1796
- You can customize how the store talks to your backend by specifying a custom adapter:
1980
+ By default, the store will talk to your backend using a standard
1981
+ REST mechanism. You can customize how the store talks to your
1982
+ backend by specifying a custom adapter:
1797
1983
 
1798
1984
  ```javascript
1799
1985
  MyApp.store = DS.Store.create({
@@ -1909,7 +2095,7 @@ DS.Store = Ember.Object.extend({
1909
2095
  @param {String} type
1910
2096
  @param {Object} properties a hash of properties to set on the
1911
2097
  newly created record.
1912
- @returns DS.Model
2098
+ @returns {DS.Model} record
1913
2099
  */
1914
2100
  createRecord: function(type, properties) {
1915
2101
  type = this.modelFor(type);
@@ -1944,9 +2130,10 @@ DS.Store = Ember.Object.extend({
1944
2130
  If possible, this method asks the adapter to generate an ID for
1945
2131
  a newly created record.
1946
2132
 
1947
- @method generateId
2133
+ @method _generateId
2134
+ @private
1948
2135
  @param {String} type
1949
- @returns String if the adapter can generate one, an ID
2136
+ @returns {String} if the adapter can generate one, an ID
1950
2137
  */
1951
2138
  _generateId: function(type) {
1952
2139
  var adapter = this.adapterFor(type);
@@ -1965,6 +2152,16 @@ DS.Store = Ember.Object.extend({
1965
2152
  /**
1966
2153
  For symmetry, a record can be deleted via the store.
1967
2154
 
2155
+ Example
2156
+
2157
+ ```javascript
2158
+ var post = store.createRecord('post', {
2159
+ title: "Rails is omakase"
2160
+ });
2161
+
2162
+ store.deletedRecord(post);
2163
+ ```
2164
+
1968
2165
  @method deleteRecord
1969
2166
  @param {DS.Model} record
1970
2167
  */
@@ -1973,7 +2170,16 @@ DS.Store = Ember.Object.extend({
1973
2170
  },
1974
2171
 
1975
2172
  /**
1976
- For symmetry, a record can be unloaded via the store.
2173
+ For symmetry, a record can be unloaded via the store. Only
2174
+ non-dirty records can be unloaded.
2175
+
2176
+ Example
2177
+
2178
+ ```javascript
2179
+ store.find('post', 1).then(function(post) {
2180
+ store.unloadRecord(post);
2181
+ });
2182
+ ```
1977
2183
 
1978
2184
  @method unloadRecord
1979
2185
  @param {DS.Model} record
@@ -2032,8 +2238,9 @@ DS.Store = Ember.Object.extend({
2032
2238
  responds.
2033
2239
 
2034
2240
  @method find
2035
- @param {DS.Model} type
2241
+ @param {String or subclass of DS.Model} type
2036
2242
  @param {Object|String|Integer|null} id
2243
+ @return {Promise} promise
2037
2244
  */
2038
2245
  find: function(type, id) {
2039
2246
  if (id === undefined) {
@@ -2053,8 +2260,9 @@ DS.Store = Ember.Object.extend({
2053
2260
 
2054
2261
  @method findById
2055
2262
  @private
2056
- @param type
2057
- @param id
2263
+ @param {String or subclass of DS.Model} type
2264
+ @param {String|Integer} id
2265
+ @return {Promise} promise
2058
2266
  */
2059
2267
  findById: function(type, id) {
2060
2268
  type = this.modelFor(type);
@@ -2073,7 +2281,7 @@ DS.Store = Ember.Object.extend({
2073
2281
  @method findByIds
2074
2282
  @param {String} type
2075
2283
  @param {Array} ids
2076
- @returns Promise
2284
+ @returns {Promise} promise
2077
2285
  */
2078
2286
  findByIds: function(type, ids) {
2079
2287
  var store = this;
@@ -2091,7 +2299,7 @@ DS.Store = Ember.Object.extend({
2091
2299
  @method fetchRecord
2092
2300
  @private
2093
2301
  @param {DS.Model} record
2094
- @returns Promise
2302
+ @returns {Promise} promise
2095
2303
  */
2096
2304
  fetchRecord: function(record) {
2097
2305
  if (isNone(record)) { return null; }
@@ -2099,18 +2307,15 @@ DS.Store = Ember.Object.extend({
2099
2307
  if (!get(record, 'isEmpty')) { return null; }
2100
2308
 
2101
2309
  var type = record.constructor,
2102
- id = get(record, 'id'),
2103
- resolver = Ember.RSVP.defer("DS: Store#fetchRecord " + record );
2104
-
2105
- record.loadingData(resolver.promise);
2310
+ id = get(record, 'id');
2106
2311
 
2107
2312
  var adapter = this.adapterFor(type);
2108
2313
 
2109
2314
 
2110
2315
 
2111
- resolver.resolve(_find(adapter, this, type, id));
2112
-
2113
- return resolver.promise;
2316
+ var promise = _find(adapter, this, type, id);
2317
+ record.loadingData(promise);
2318
+ return promise;
2114
2319
  },
2115
2320
 
2116
2321
  /**
@@ -2124,8 +2329,9 @@ DS.Store = Ember.Object.extend({
2124
2329
  ```
2125
2330
 
2126
2331
  @method getById
2127
- @param type
2128
- @param id
2332
+ @param {String or subclass of DS.Model} type
2333
+ @param {String|Integer} id
2334
+ @param {DS.Model} record
2129
2335
  */
2130
2336
  getById: function(type, id) {
2131
2337
  if (this.hasRecordForId(type, id)) {
@@ -2136,8 +2342,7 @@ DS.Store = Ember.Object.extend({
2136
2342
  },
2137
2343
 
2138
2344
  /**
2139
- This method is called by the record's `reload` method. The record's `reload`
2140
- passes in a resolver for the promise it returns.
2345
+ This method is called by the record's `reload` method.
2141
2346
 
2142
2347
  This method calls the adapter's `find` method, which returns a promise. When
2143
2348
  **that** promise resolves, `reloadRecord` will resolve the promise returned
@@ -2146,7 +2351,7 @@ DS.Store = Ember.Object.extend({
2146
2351
  @method reloadRecord
2147
2352
  @private
2148
2353
  @param {DS.Model} record
2149
- @param {Resolver} resolver
2354
+ @return {Promise} promise
2150
2355
  */
2151
2356
  reloadRecord: function(record) {
2152
2357
  var type = record.constructor,
@@ -2173,8 +2378,9 @@ DS.Store = Ember.Object.extend({
2173
2378
 
2174
2379
  @method fetchMany
2175
2380
  @private
2176
- @param records
2177
- @param owner
2381
+ @param {Array} records
2382
+ @param {DS.Model} owner
2383
+ @param {Resolver} resolver
2178
2384
  */
2179
2385
  fetchMany: function(records, owner, resolver) {
2180
2386
  if (!records.length) { return; }
@@ -2202,9 +2408,9 @@ DS.Store = Ember.Object.extend({
2202
2408
  Returns true if a record for a given type and ID is already loaded.
2203
2409
 
2204
2410
  @method hasRecordForId
2205
- @param {DS.Model} type
2411
+ @param {String or subclass of DS.Model} type
2206
2412
  @param {String|Integer} id
2207
- @returns Boolean
2413
+ @returns {Boolean}
2208
2414
  */
2209
2415
  hasRecordForId: function(type, id) {
2210
2416
  id = coerceId(id);
@@ -2217,9 +2423,10 @@ DS.Store = Ember.Object.extend({
2217
2423
  it builds a new record and leaves it in the `empty` state.
2218
2424
 
2219
2425
  @method recordForId
2220
- @param {String} type
2426
+ @private
2427
+ @param {String or subclass of DS.Model} type
2221
2428
  @param {String|Integer} id
2222
- @returns DS.Model
2429
+ @returns {DS.Model} record
2223
2430
  */
2224
2431
  recordForId: function(type, id) {
2225
2432
  type = this.modelFor(type);
@@ -2239,10 +2446,10 @@ DS.Store = Ember.Object.extend({
2239
2446
  @method findMany
2240
2447
  @private
2241
2448
  @param {DS.Model} owner
2242
- @param {Array<DS.Model>} records
2243
- @param {String} type
2449
+ @param {Array} records
2450
+ @param {String or subclass of DS.Model} type
2244
2451
  @param {Resolver} resolver
2245
- @return DS.ManyArray
2452
+ @return {DS.ManyArray} records
2246
2453
  */
2247
2454
  findMany: function(owner, records, type, resolver) {
2248
2455
  type = this.modelFor(type);
@@ -2288,9 +2495,9 @@ DS.Store = Ember.Object.extend({
2288
2495
  @private
2289
2496
  @param {DS.Model} owner
2290
2497
  @param {any} link
2291
- @param {String} type
2498
+ @param {String or subclass of DS.Model} type
2292
2499
  @param {Resolver} resolver
2293
- @return DS.ManyArray
2500
+ @return {DS.ManyArray}
2294
2501
  */
2295
2502
  findHasMany: function(owner, link, relationship, resolver) {
2296
2503
  var adapter = this.adapterFor(owner.constructor);
@@ -2302,6 +2509,14 @@ DS.Store = Ember.Object.extend({
2302
2509
  return records;
2303
2510
  },
2304
2511
 
2512
+ /**
2513
+ @method findBelongsTo
2514
+ @private
2515
+ @param {DS.Model} owner
2516
+ @param {any} link
2517
+ @param {Relationship} relationship
2518
+ @param {Resolver} resolver
2519
+ */
2305
2520
  findBelongsTo: function(owner, link, relationship, resolver) {
2306
2521
  var adapter = this.adapterFor(owner.constructor);
2307
2522
 
@@ -2323,19 +2538,15 @@ DS.Store = Ember.Object.extend({
2323
2538
 
2324
2539
  @method findQuery
2325
2540
  @private
2326
- @param {String} type
2541
+ @param {String or subclass of DS.Model} type
2327
2542
  @param {any} query an opaque query to be used by the adapter
2328
- @return Promise
2543
+ @return {Promise} promise
2329
2544
  */
2330
2545
  findQuery: function(type, query) {
2331
2546
  type = this.modelFor(type);
2332
2547
 
2333
- var array = DS.AdapterPopulatedRecordArray.create({
2334
- type: type,
2335
- query: query,
2336
- content: Ember.A(),
2337
- store: this
2338
- });
2548
+ var array = this.recordArrayManager
2549
+ .createAdapterPopulatedRecordArray(type, query);
2339
2550
 
2340
2551
  var adapter = this.adapterFor(type),
2341
2552
  promiseLabel = "DS: Store#findQuery " + type,
@@ -2355,7 +2566,7 @@ DS.Store = Ember.Object.extend({
2355
2566
 
2356
2567
  @method findAll
2357
2568
  @private
2358
- @param {Class} type
2569
+ @param {String or subclass of DS.Model} type
2359
2570
  @return {DS.AdapterPopulatedRecordArray}
2360
2571
  */
2361
2572
  findAll: function(type) {
@@ -2367,27 +2578,24 @@ DS.Store = Ember.Object.extend({
2367
2578
  /**
2368
2579
  @method fetchAll
2369
2580
  @private
2370
- @param type
2371
- @param array
2372
- @returns Promise
2581
+ @param {DS.Model} type
2582
+ @param {DS.RecordArray} array
2583
+ @returns {Promise} promise
2373
2584
  */
2374
2585
  fetchAll: function(type, array) {
2375
2586
  var adapter = this.adapterFor(type),
2376
- sinceToken = this.typeMapFor(type).metadata.since,
2377
- resolver = Ember.RSVP.defer("DS: Store#findAll " + type);
2587
+ sinceToken = this.typeMapFor(type).metadata.since;
2378
2588
 
2379
2589
  set(array, 'isUpdating', true);
2380
2590
 
2381
2591
 
2382
2592
 
2383
- resolver.resolve(_findAll(adapter, this, type, sinceToken));
2384
-
2385
- return promiseArray(resolver.promise);
2593
+ return promiseArray(_findAll(adapter, this, type, sinceToken));
2386
2594
  },
2387
2595
 
2388
2596
  /**
2389
2597
  @method didUpdateAll
2390
- @param type
2598
+ @param {DS.Model} type
2391
2599
  */
2392
2600
  didUpdateAll: function(type) {
2393
2601
  var findAllCache = this.typeMapFor(type).findAllCache;
@@ -2404,8 +2612,14 @@ DS.Store = Ember.Object.extend({
2404
2612
  Also note that multiple calls to `all` for a given type will always
2405
2613
  return the same RecordArray.
2406
2614
 
2615
+ Example
2616
+
2617
+ ```javascript
2618
+ var local_posts = store.all(App.Post);
2619
+ ```
2620
+
2407
2621
  @method all
2408
- @param {Class} type
2622
+ @param {String or subclass of DS.Model} type
2409
2623
  @return {DS.RecordArray}
2410
2624
  */
2411
2625
  all: function(type) {
@@ -2416,14 +2630,7 @@ DS.Store = Ember.Object.extend({
2416
2630
 
2417
2631
  if (findAllCache) { return findAllCache; }
2418
2632
 
2419
- var array = DS.RecordArray.create({
2420
- type: type,
2421
- content: Ember.A(),
2422
- store: this,
2423
- isLoaded: true
2424
- });
2425
-
2426
- this.recordArrayManager.registerFilteredRecordArray(array, type);
2633
+ var array = this.recordArrayManager.createRecordArray(type);
2427
2634
 
2428
2635
  typeMap.findAllCache = array;
2429
2636
  return array;
@@ -2433,8 +2640,12 @@ DS.Store = Ember.Object.extend({
2433
2640
  /**
2434
2641
  This method unloads all of the known records for a given type.
2435
2642
 
2643
+ ```javascript
2644
+ store.unloadAll(App.Post);
2645
+ ```
2646
+
2436
2647
  @method unloadAll
2437
- @param {Class} type
2648
+ @param {String or subclass of DS.Model} type
2438
2649
  */
2439
2650
  unloadAll: function(type) {
2440
2651
  type = this.modelFor(type);
@@ -2469,11 +2680,24 @@ DS.Store = Ember.Object.extend({
2469
2680
  results returned by the server could then appear in the filter if they
2470
2681
  match the filter function.
2471
2682
 
2683
+ Example
2684
+
2685
+ ```javascript
2686
+ store.filter(App.Post, {unread: true}, function(post) {
2687
+ return post.get('unread');
2688
+ }).then(function(unreadPosts) {
2689
+ unreadPosts.get('length'); // 5
2690
+ var unreadPost = unreadPosts.objectAt(0);
2691
+ unreadPosts.set('unread', false);
2692
+ unreadPosts.get('length'); // 4
2693
+ });
2694
+ ```
2695
+
2472
2696
  @method filter
2473
- @param {Class} type
2697
+ @param {String or subclass of DS.Model} type
2474
2698
  @param {Object} query optional query
2475
2699
  @param {Function} filter
2476
- @return {DS.FilteredRecordArray}
2700
+ @return {DS.PromiseArray}
2477
2701
  */
2478
2702
  filter: function(type, query, filter) {
2479
2703
  var promise;
@@ -2487,21 +2711,13 @@ DS.Store = Ember.Object.extend({
2487
2711
 
2488
2712
  type = this.modelFor(type);
2489
2713
 
2490
- var array = DS.FilteredRecordArray.create({
2491
- type: type,
2492
- content: Ember.A(),
2493
- store: this,
2494
- manager: this.recordArrayManager,
2495
- filterFunction: filter
2496
- });
2497
-
2498
- this.recordArrayManager.registerFilteredRecordArray(array, type, filter);
2714
+ var array = this.recordArrayManager
2715
+ .createFilteredRecordArray(type, filter);
2716
+ promise = promise || resolve(array);
2499
2717
 
2500
- if (promise) {
2501
- return promise.then(function() { return array; }, null, "DS: Store#filter of " + type);
2502
- } else {
2718
+ return promiseArray(promise.then(function() {
2503
2719
  return array;
2504
- }
2720
+ }, null, "DS: Store#filter of " + type));
2505
2721
  },
2506
2722
 
2507
2723
  /**
@@ -2509,8 +2725,17 @@ DS.Store = Ember.Object.extend({
2509
2725
  in the store. Use this function to know beforehand if a find()
2510
2726
  will result in a request or that it will be a cache hit.
2511
2727
 
2728
+ Example
2729
+
2730
+ ```javascript
2731
+ store.recordIsLoaded(App.Post, 1); // false
2732
+ store.find(App.Post, 1).then(function() {
2733
+ store.recordIsLoaded(App.Post, 1); // true
2734
+ });
2735
+ ```
2736
+
2512
2737
  @method recordIsLoaded
2513
- @param type
2738
+ @param {String or subclass of DS.Model} type
2514
2739
  @param {string} id
2515
2740
  @return {boolean}
2516
2741
  */
@@ -2523,7 +2748,7 @@ DS.Store = Ember.Object.extend({
2523
2748
  This method returns the metadata for a specific type.
2524
2749
 
2525
2750
  @method metadataFor
2526
- @param {string} type
2751
+ @param {String or subclass of DS.Model} type
2527
2752
  @return {object}
2528
2753
  */
2529
2754
  metadataFor: function(type) {
@@ -2546,7 +2771,6 @@ DS.Store = Ember.Object.extend({
2546
2771
  @method dataWasUpdated
2547
2772
  @private
2548
2773
  @param {Class} type
2549
- @param {Number|String} clientId
2550
2774
  @param {DS.Model} record
2551
2775
  */
2552
2776
  dataWasUpdated: function(type, record) {
@@ -2679,6 +2903,7 @@ DS.Store = Ember.Object.extend({
2679
2903
  @method typeMapFor
2680
2904
  @private
2681
2905
  @param type
2906
+ @return {Object} typeMap
2682
2907
  */
2683
2908
  typeMapFor: function(type) {
2684
2909
  var typeMaps = get(this, 'typeMaps'),
@@ -2709,7 +2934,7 @@ DS.Store = Ember.Object.extend({
2709
2934
 
2710
2935
  @method _load
2711
2936
  @private
2712
- @param {DS.Model} type
2937
+ @param {String or subclass of DS.Model} type
2713
2938
  @param {Object} data
2714
2939
  @param {Boolean} partial the data should be merged into
2715
2940
  the existing data, not replace it.
@@ -2736,10 +2961,13 @@ DS.Store = Ember.Object.extend({
2736
2961
  modelFor: function(key) {
2737
2962
  var factory;
2738
2963
 
2964
+
2739
2965
  if (typeof key === 'string') {
2740
- factory = this.container.lookupFactory('model:' + key);
2966
+ var normalizedKey = this.container.normalize('model:' + key);
2967
+
2968
+ factory = this.container.lookupFactory(normalizedKey);
2741
2969
  if (!factory) { throw new Ember.Error("No model was found for '" + key + "'"); }
2742
- factory.typeKey = key;
2970
+ factory.typeKey = normalizedKey.split(':', 2)[1];
2743
2971
  } else {
2744
2972
  // A factory already supplied.
2745
2973
  factory = key;
@@ -2805,9 +3033,9 @@ DS.Store = Ember.Object.extend({
2805
3033
  records, as well as to update existing records.
2806
3034
 
2807
3035
  @method push
2808
- @param {String} type
3036
+ @param {String or subclass of DS.Model} type
2809
3037
  @param {Object} data
2810
- @returns DS.Model the record that was created or
3038
+ @returns {DS.Model} the record that was created or
2811
3039
  updated.
2812
3040
  */
2813
3041
  push: function(type, data, _partial) {
@@ -2857,8 +3085,8 @@ DS.Store = Ember.Object.extend({
2857
3085
  @method pushPayload
2858
3086
  @param {String} type
2859
3087
  @param {Object} payload
3088
+ @return {DS.Model} the record that was created or updated.
2860
3089
  */
2861
-
2862
3090
  pushPayload: function (type, payload) {
2863
3091
  var serializer;
2864
3092
  if (!payload) {
@@ -2883,9 +3111,9 @@ DS.Store = Ember.Object.extend({
2883
3111
  call `push` repeatedly for you.
2884
3112
 
2885
3113
  @method pushMany
2886
- @param {String} type
3114
+ @param {String or subclass of DS.Model} type
2887
3115
  @param {Array} datas
2888
- @return {Array<DS.Model>}
3116
+ @return {Array}
2889
3117
  */
2890
3118
  pushMany: function(type, datas) {
2891
3119
  return map(datas, function(data) {
@@ -2898,7 +3126,7 @@ DS.Store = Ember.Object.extend({
2898
3126
  you can call `metaForType`.
2899
3127
 
2900
3128
  @method metaForType
2901
- @param {String} type
3129
+ @param {String or subclass of DS.Model} type
2902
3130
  @param {Object} metadata
2903
3131
  */
2904
3132
  metaForType: function(type, metadata) {
@@ -2916,7 +3144,7 @@ DS.Store = Ember.Object.extend({
2916
3144
  @param {subclass of DS.Model} type
2917
3145
  @param {String} id
2918
3146
  @param {Object} data
2919
- @returns DS.Model
3147
+ @returns {DS.Model} record
2920
3148
  */
2921
3149
  buildRecord: function(type, id, data) {
2922
3150
  var typeMap = this.typeMapFor(type),
@@ -3065,6 +3293,7 @@ DS.Store = Ember.Object.extend({
3065
3293
  @method serializerFor
3066
3294
  @private
3067
3295
  @param {String} type the record to serialize
3296
+ @return {DS.Serializer}
3068
3297
  */
3069
3298
  serializerFor: function(type) {
3070
3299
  type = this.modelFor(type);
@@ -3138,28 +3367,85 @@ function addUnsavedRecords(record, key, data) {
3138
3367
  }
3139
3368
 
3140
3369
  // Delegation to the adapter and promise management
3370
+ /**
3371
+ A `PromiseArray` is an object that acts like both an `Ember.Array`
3372
+ and a promise. When the promise is resolved the the resulting value
3373
+ will be set to the `PromiseArray`'s `content` property. This makes
3374
+ it easy to create data bindings with the `PromiseArray` that will be
3375
+ updated when the promise resolves.
3141
3376
 
3142
- DS.PromiseArray = Ember.ArrayProxy.extend(Ember.PromiseProxyMixin);
3143
- DS.PromiseObject = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin);
3377
+ For more information see the [Ember.PromiseProxyMixin
3378
+ documentation](/api/classes/Ember.PromiseProxyMixin.html).
3144
3379
 
3145
- function promiseObject(promise) {
3146
- return DS.PromiseObject.create({ promise: promise });
3147
- }
3380
+ Example
3148
3381
 
3149
- function promiseArray(promise) {
3150
- return DS.PromiseArray.create({ promise: promise });
3151
- }
3382
+ ```javascript
3383
+ var promiseArray = DS.PromiseArray.create({
3384
+ promise: $.getJSON('/some/remote/data.json')
3385
+ });
3152
3386
 
3153
- function isThenable(object) {
3154
- return object && typeof object.then === 'function';
3155
- }
3387
+ promiseArray.get('length'); // 0
3156
3388
 
3157
- function serializerFor(container, type, defaultSerializer) {
3158
- return container.lookup('serializer:'+type) ||
3159
- container.lookup('serializer:application') ||
3160
- container.lookup('serializer:' + defaultSerializer) ||
3161
- container.lookup('serializer:_default');
3162
- }
3389
+ promiseArray.then(function() {
3390
+ promiseArray.get('length'); // 100
3391
+ });
3392
+ ```
3393
+
3394
+ @class PromiseArray
3395
+ @namespace DS
3396
+ @extends Ember.ArrayProxy
3397
+ @uses Ember.PromiseProxyMixin
3398
+ */
3399
+ DS.PromiseArray = Ember.ArrayProxy.extend(Ember.PromiseProxyMixin);
3400
+ /**
3401
+ A `PromiseObject` is an object that acts like both an `Ember.Object`
3402
+ and a promise. When the promise is resolved the the resulting value
3403
+ will be set to the `PromiseObject`'s `content` property. This makes
3404
+ it easy to create data bindings with the `PromiseObject` that will
3405
+ be updated when the promise resolves.
3406
+
3407
+ For more information see the [Ember.PromiseProxyMixin
3408
+ documentation](/api/classes/Ember.PromiseProxyMixin.html).
3409
+
3410
+ Example
3411
+
3412
+ ```javascript
3413
+ var promiseObject = DS.PromiseObject.create({
3414
+ promise: $.getJSON('/some/remote/data.json')
3415
+ });
3416
+
3417
+ promiseObject.get('name'); // null
3418
+
3419
+ promiseObject.then(function() {
3420
+ promiseObject.get('name'); // 'Tomster'
3421
+ });
3422
+ ```
3423
+
3424
+ @class PromiseObject
3425
+ @namespace DS
3426
+ @extends Ember.ObjectProxy
3427
+ @uses Ember.PromiseProxyMixin
3428
+ */
3429
+ DS.PromiseObject = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin);
3430
+
3431
+ function promiseObject(promise) {
3432
+ return DS.PromiseObject.create({ promise: promise });
3433
+ }
3434
+
3435
+ function promiseArray(promise) {
3436
+ return DS.PromiseArray.create({ promise: promise });
3437
+ }
3438
+
3439
+ function isThenable(object) {
3440
+ return object && typeof object.then === 'function';
3441
+ }
3442
+
3443
+ function serializerFor(container, type, defaultSerializer) {
3444
+ return container.lookup('serializer:'+type) ||
3445
+ container.lookup('serializer:application') ||
3446
+ container.lookup('serializer:' + defaultSerializer) ||
3447
+ container.lookup('serializer:_default');
3448
+ }
3163
3449
 
3164
3450
  function defaultSerializer(container) {
3165
3451
  return container.lookup('serializer:application') ||
@@ -3257,7 +3543,7 @@ function _findQuery(adapter, store, type, query, recordArray) {
3257
3543
  serializer = serializerForAdapter(adapter, type);
3258
3544
 
3259
3545
  return resolve(promise, "DS: Handle Adapter#findQuery of " + type).then(function(payload) {
3260
- payload = serializer.extract(store, type, payload, null, 'findAll');
3546
+ payload = serializer.extract(store, type, payload, null, 'findQuery');
3261
3547
 
3262
3548
 
3263
3549
  recordArray.load(payload);
@@ -3604,9 +3890,7 @@ var DirtyState = {
3604
3890
  record.send('invokeLifecycleCallbacks', dirtyType);
3605
3891
  },
3606
3892
 
3607
- becameInvalid: function(record, errors) {
3608
- set(record, 'errors', errors);
3609
-
3893
+ becameInvalid: function(record) {
3610
3894
  record.transitionTo('invalid');
3611
3895
  record.send('invokeLifecycleCallbacks');
3612
3896
  },
@@ -3631,23 +3915,15 @@ var DirtyState = {
3631
3915
  },
3632
3916
 
3633
3917
  didSetProperty: function(record, context) {
3634
- var errors = get(record, 'errors'),
3635
- key = context.name;
3636
-
3637
- set(errors, key, null);
3638
-
3639
- if (!hasDefinedProperties(errors)) {
3640
- record.send('becameValid');
3641
- }
3918
+ get(record, 'errors').remove(context.name);
3642
3919
 
3643
3920
  didSetProperty(record, context);
3644
3921
  },
3645
3922
 
3646
3923
  becomeDirty: Ember.K,
3647
3924
 
3648
- rollback: function(record) {
3649
- record.send('becameValid');
3650
- record.send('rollback');
3925
+ rolledBack: function(record) {
3926
+ get(record, 'errors').clear();
3651
3927
  },
3652
3928
 
3653
3929
  becameValid: function(record) {
@@ -4002,6 +4278,210 @@ DS.RootState = RootState;
4002
4278
 
4003
4279
 
4004
4280
 
4281
+ (function() {
4282
+ var get = Ember.get, isEmpty = Ember.isEmpty;
4283
+
4284
+ /**
4285
+ @module ember-data
4286
+ */
4287
+
4288
+ /**
4289
+ Holds validation errors for a given record organized by attribute names.
4290
+
4291
+ @class Errors
4292
+ @namespace DS
4293
+ @extends Ember.Object
4294
+ @uses Ember.Enumerable
4295
+ @uses Ember.Evented
4296
+ */
4297
+ DS.Errors = Ember.Object.extend(Ember.Enumerable, Ember.Evented, {
4298
+ /**
4299
+ Register with target handler
4300
+
4301
+ @method registerHandlers
4302
+ @param {Object} target
4303
+ @param {Function} becameInvalid
4304
+ @param {Function} becameValid
4305
+ */
4306
+ registerHandlers: function(target, becameInvalid, becameValid) {
4307
+ this.on('becameInvalid', target, becameInvalid);
4308
+ this.on('becameValid', target, becameValid);
4309
+ },
4310
+
4311
+ /**
4312
+ @property errorsByAttributeName
4313
+ @type {Ember.MapWithDefault}
4314
+ @private
4315
+ */
4316
+ errorsByAttributeName: Ember.reduceComputed("content", {
4317
+ initialValue: function() {
4318
+ return Ember.MapWithDefault.create({
4319
+ defaultValue: function() {
4320
+ return Ember.A();
4321
+ }
4322
+ });
4323
+ },
4324
+
4325
+ addedItem: function(errors, error) {
4326
+ errors.get(error.attribute).pushObject(error);
4327
+
4328
+ return errors;
4329
+ },
4330
+
4331
+ removedItem: function(errors, error) {
4332
+ errors.get(error.attribute).removeObject(error);
4333
+
4334
+ return errors;
4335
+ }
4336
+ }),
4337
+
4338
+ /**
4339
+ Returns errors for a given attribute
4340
+
4341
+ @method errorsFor
4342
+ @param {String} attribute
4343
+ @returns {Array}
4344
+ */
4345
+ errorsFor: function(attribute) {
4346
+ return get(this, 'errorsByAttributeName').get(attribute);
4347
+ },
4348
+
4349
+ /**
4350
+ */
4351
+ messages: Ember.computed.mapBy('content', 'message'),
4352
+
4353
+ /**
4354
+ @property content
4355
+ @type {Array}
4356
+ @private
4357
+ */
4358
+ content: Ember.computed(function() {
4359
+ return Ember.A();
4360
+ }),
4361
+
4362
+ /**
4363
+ @method unknownProperty
4364
+ @private
4365
+ */
4366
+ unknownProperty: function(attribute) {
4367
+ var errors = this.errorsFor(attribute);
4368
+ if (isEmpty(errors)) { return null; }
4369
+ return errors;
4370
+ },
4371
+
4372
+ /**
4373
+ @method nextObject
4374
+ @private
4375
+ */
4376
+ nextObject: function(index, previousObject, context) {
4377
+ return get(this, 'content').objectAt(index);
4378
+ },
4379
+
4380
+ /**
4381
+ Total number of errors.
4382
+
4383
+ @property length
4384
+ @type {Number}
4385
+ @readOnly
4386
+ */
4387
+ length: Ember.computed.oneWay('content.length').readOnly(),
4388
+
4389
+ /**
4390
+ @property isEmpty
4391
+ @type {Boolean}
4392
+ @readOnly
4393
+ */
4394
+ isEmpty: Ember.computed.not('length').readOnly(),
4395
+
4396
+ /**
4397
+ Adds error messages to a given attribute and sends
4398
+ `becameInvalid` event to the record.
4399
+
4400
+ @method add
4401
+ @param {String} attribute
4402
+ @param {Array|String} messages
4403
+ */
4404
+ add: function(attribute, messages) {
4405
+ var wasEmpty = get(this, 'isEmpty');
4406
+
4407
+ messages = this._findOrCreateMessages(attribute, messages);
4408
+ get(this, 'content').addObjects(messages);
4409
+
4410
+ this.notifyPropertyChange(attribute);
4411
+ this.enumerableContentDidChange();
4412
+
4413
+ if (wasEmpty && !get(this, 'isEmpty')) {
4414
+ this.trigger('becameInvalid');
4415
+ }
4416
+ },
4417
+
4418
+ /**
4419
+ @method _findOrCreateMessages
4420
+ @private
4421
+ */
4422
+ _findOrCreateMessages: function(attribute, messages) {
4423
+ var errors = this.errorsFor(attribute);
4424
+
4425
+ return Ember.makeArray(messages).map(function(message) {
4426
+ return errors.findBy('message', message) || {
4427
+ attribute: attribute,
4428
+ message: message
4429
+ };
4430
+ });
4431
+ },
4432
+
4433
+ /**
4434
+ Removes all error messages from the given attribute and sends
4435
+ `becameValid` event to the record if there no more errors left.
4436
+
4437
+ @method remove
4438
+ @param {String} attribute
4439
+ */
4440
+ remove: function(attribute) {
4441
+ if (get(this, 'isEmpty')) { return; }
4442
+
4443
+ var content = get(this, 'content').rejectBy('attribute', attribute);
4444
+ get(this, 'content').setObjects(content);
4445
+
4446
+ this.notifyPropertyChange(attribute);
4447
+ this.enumerableContentDidChange();
4448
+
4449
+ if (get(this, 'isEmpty')) {
4450
+ this.trigger('becameValid');
4451
+ }
4452
+ },
4453
+
4454
+ /**
4455
+ Removes all error messages and sends `becameValid` event
4456
+ to the record.
4457
+
4458
+ @method clear
4459
+ */
4460
+ clear: function() {
4461
+ if (get(this, 'isEmpty')) { return; }
4462
+
4463
+ get(this, 'content').clear();
4464
+ this.enumerableContentDidChange();
4465
+
4466
+ this.trigger('becameValid');
4467
+ },
4468
+
4469
+ /**
4470
+ Checks if there is error messages for the given attribute.
4471
+
4472
+ @method has
4473
+ @param {String} attribute
4474
+ @returns {Boolean} true if there some errors on given attribute
4475
+ */
4476
+ has: function(attribute) {
4477
+ return !isEmpty(this.errorsFor(attribute));
4478
+ }
4479
+ });
4480
+
4481
+ })();
4482
+
4483
+
4484
+
4005
4485
  (function() {
4006
4486
  /**
4007
4487
  @module ember-data
@@ -4278,10 +4758,10 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
4278
4758
  and values which are an array of error messages.
4279
4759
 
4280
4760
  ```javascript
4281
- record.get('errors'); // null
4761
+ record.get('errors.length'); // 0
4282
4762
  record.set('foo', 'invalid value');
4283
4763
  record.save().then(null, function() {
4284
- record.get('errors'); // {foo: ['foo should be a number.']}
4764
+ record.get('errors').get('foo'); // ['foo should be a number.']
4285
4765
  });
4286
4766
  ```
4287
4767
 
@@ -4385,6 +4865,13 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
4385
4865
 
4386
4866
  init: function() {
4387
4867
  set(this, 'currentState', DS.RootState.empty);
4868
+ var errors = DS.Errors.create();
4869
+ errors.registerHandlers(this, function() {
4870
+ this.send('becameInvalid');
4871
+ }, function() {
4872
+ this.send('becameValid');
4873
+ });
4874
+ set(this, 'errors', errors);
4388
4875
  this._super();
4389
4876
  this._setup();
4390
4877
  },
@@ -4795,12 +5282,11 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
4795
5282
  this._inFlightAttributes = {};
4796
5283
  set(this, 'isError', false);
4797
5284
  }
4798
-
5285
+
4799
5286
  if (!get(this, 'isValid')) {
4800
5287
  this._inFlightAttributes = {};
4801
- this.send('becameValid');
4802
- }
4803
-
5288
+ }
5289
+
4804
5290
  this.send('rolledBack');
4805
5291
 
4806
5292
  this.suspendRelationshipObservers(function() {
@@ -4941,7 +5427,15 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
4941
5427
  @private
4942
5428
  */
4943
5429
  adapterDidInvalidate: function(errors) {
4944
- this.send('becameInvalid', errors);
5430
+ var recordErrors = get(this, 'errors');
5431
+ function addError(name) {
5432
+ if (errors[name]) {
5433
+ recordErrors.add(name, errors[name]);
5434
+ }
5435
+ }
5436
+
5437
+ this.eachAttribute(addError);
5438
+ this.eachRelationship(addError);
4945
5439
  },
4946
5440
 
4947
5441
  /**
@@ -6821,6 +7315,65 @@ DS.RecordArrayManager = Ember.Object.extend({
6821
7315
  return manyArray;
6822
7316
  },
6823
7317
 
7318
+ /**
7319
+ Create a `DS.RecordArray` for a type and register it for updates.
7320
+
7321
+ @method createRecordArray
7322
+ @param {Class} type
7323
+ @return {DS.RecordArray}
7324
+ */
7325
+ createRecordArray: function(type) {
7326
+ var array = DS.RecordArray.create({
7327
+ type: type,
7328
+ content: Ember.A(),
7329
+ store: this.store,
7330
+ isLoaded: true
7331
+ });
7332
+
7333
+ this.registerFilteredRecordArray(array, type);
7334
+
7335
+ return array;
7336
+ },
7337
+
7338
+ /**
7339
+ Create a `DS.FilteredRecordArray` for a type and register it for updates.
7340
+
7341
+ @method createFilteredRecordArray
7342
+ @param {Class} type
7343
+ @param {Function} filter
7344
+ @return {DS.FilteredRecordArray}
7345
+ */
7346
+ createFilteredRecordArray: function(type, filter) {
7347
+ var array = DS.FilteredRecordArray.create({
7348
+ type: type,
7349
+ content: Ember.A(),
7350
+ store: this.store,
7351
+ manager: this,
7352
+ filterFunction: filter
7353
+ });
7354
+
7355
+ this.registerFilteredRecordArray(array, type, filter);
7356
+
7357
+ return array;
7358
+ },
7359
+
7360
+ /**
7361
+ Create a `DS.AdapterPopulatedRecordArray` for a type with given query.
7362
+
7363
+ @method createAdapterPopulatedRecordArray
7364
+ @param {Class} type
7365
+ @param {Object} query
7366
+ @return {DS.AdapterPopulatedRecordArray}
7367
+ */
7368
+ createAdapterPopulatedRecordArray: function(type, query) {
7369
+ return DS.AdapterPopulatedRecordArray.create({
7370
+ type: type,
7371
+ query: query,
7372
+ content: Ember.A(),
7373
+ store: this.store
7374
+ });
7375
+ },
7376
+
6824
7377
  /**
6825
7378
  Register a RecordArray for a given type to be backed by
6826
7379
  a filter function. This will cause the array to update
@@ -6865,6 +7418,35 @@ var map = Ember.ArrayPolyfills.map;
6865
7418
 
6866
7419
  var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
6867
7420
 
7421
+ /**
7422
+ A `DS.InvalidError` is used by an adapter to signal the external API
7423
+ was unable to process a request because the content was not
7424
+ semantically correct or meaningful per the API. Usually this means a
7425
+ record failed some form of server side validation. When a promise
7426
+ from an adapter is rejected with a `DS.InvalidError` the record will
7427
+ transition to the `invalid` state and the errors will be set to the
7428
+ `errors` property on the record.
7429
+
7430
+ Example
7431
+
7432
+ ```javascript
7433
+ App.ApplicationAdapter = DS.RESTAdapter.extend({
7434
+ ajaxError: function(jqXHR) {
7435
+ var error = this._super(jqXHR);
7436
+
7437
+ if (jqXHR && jqXHR.status === 422) {
7438
+ var jsonErrors = Ember.$.parseJSON(jqXHR.responseText)["errors"];
7439
+ return new DS.InvalidError(jsonErrors);
7440
+ } else {
7441
+ return error;
7442
+ }
7443
+ }
7444
+ });
7445
+ ```
7446
+
7447
+ @class InvalidError
7448
+ @namespace DS
7449
+ */
6868
7450
  DS.InvalidError = function(errors) {
6869
7451
  var tmp = Error.prototype.constructor.call(this, "The backend rejected the commit because it was invalid: " + Ember.inspect(errors));
6870
7452
  this.errors = errors;
@@ -6878,8 +7460,10 @@ DS.InvalidError.prototype = Ember.create(Error.prototype);
6878
7460
  /**
6879
7461
  An adapter is an object that receives requests from a store and
6880
7462
  translates them into the appropriate action to take against your
6881
- persistence layer. The persistence layer is usually an HTTP API, but may
6882
- be anything, such as the browser's local storage.
7463
+ persistence layer. The persistence layer is usually an HTTP API, but
7464
+ may be anything, such as the browser's local storage. Typically the
7465
+ adapter is not invoked directly instead its functionality is accessed
7466
+ through the `store`.
6883
7467
 
6884
7468
  ### Creating an Adapter
6885
7469
 
@@ -6907,15 +7491,14 @@ DS.InvalidError.prototype = Ember.create(Error.prototype);
6907
7491
  * `createRecord()`
6908
7492
  * `updateRecord()`
6909
7493
  * `deleteRecord()`
7494
+ * `findAll()`
7495
+ * `findQuery()`
6910
7496
 
6911
7497
  To improve the network performance of your application, you can optimize
6912
7498
  your adapter by overriding these lower-level methods:
6913
7499
 
6914
7500
  * `findMany()`
6915
- * `createRecords()`
6916
- * `updateRecords()`
6917
- * `deleteRecords()`
6918
- * `commit()`
7501
+
6919
7502
 
6920
7503
  For an example implementation, see `DS.RESTAdapter`, the
6921
7504
  included REST adapter.
@@ -6927,6 +7510,25 @@ DS.InvalidError.prototype = Ember.create(Error.prototype);
6927
7510
 
6928
7511
  DS.Adapter = Ember.Object.extend({
6929
7512
 
7513
+ /**
7514
+ If you would like your adapter to use a custom serializer you can
7515
+ set the `defaultSerializer` property to be the name of the custom
7516
+ serializer.
7517
+
7518
+ Note the `defaultSerializer` serializer has a lower priority then
7519
+ a model specific serializer (i.e. `PostSerializer`) or the
7520
+ `application` serializer.
7521
+
7522
+ ```javascript
7523
+ var DjangoAdapter = DS.Adapter.extend({
7524
+ defaultSerializer: 'django'
7525
+ });
7526
+ ```
7527
+
7528
+ @property defaultSerializer
7529
+ @type {String}
7530
+ */
7531
+
6930
7532
  /**
6931
7533
  The `find()` method is invoked when the store is asked for a record that
6932
7534
  has not previously been loaded. In response to `find()` being called, you
@@ -6937,41 +7539,92 @@ DS.Adapter = Ember.Object.extend({
6937
7539
  Here is an example `find` implementation:
6938
7540
 
6939
7541
  ```javascript
6940
- find: function(store, type, id) {
6941
- var url = type.url;
6942
- url = url.fmt(id);
6943
-
6944
- jQuery.getJSON(url, function(data) {
6945
- // data is a hash of key/value pairs. If your server returns a
6946
- // root, simply do something like:
6947
- // store.push(type, id, data.person)
6948
- store.push(type, id, data);
6949
- });
6950
- }
7542
+ App.ApplicationAdapter = DS.Adapter.extend({
7543
+ find: function(store, type, id) {
7544
+ var url = [type, id].join('/');
7545
+
7546
+ return new Ember.RSVP.Promise(function(resolve, reject) {
7547
+ jQuery.getJSON(url).then(function(data) {
7548
+ Ember.run(null, resolve, data);
7549
+ }, function(jqXHR) {
7550
+ jqXHR.then = null; // tame jQuery's ill mannered promises
7551
+ Ember.run(null, reject, jqXHR);
7552
+ });
7553
+ });
7554
+ }
7555
+ });
6951
7556
  ```
6952
7557
 
6953
7558
  @method find
7559
+ @param {DS.Store} store
7560
+ @param {subclass of DS.Model} type
7561
+ @param {String} id
7562
+ @return {Promise} promise
6954
7563
  */
6955
7564
  find: Ember.required(Function),
6956
7565
 
6957
7566
  /**
7567
+ The `findAll()` method is called when you call `find` on the store
7568
+ without an ID (i.e. `store.find('post')`).
7569
+
7570
+ Example
7571
+
7572
+ ```javascript
7573
+ App.ApplicationAdapter = DS.Adapter.extend({
7574
+ findAll: function(store, type, sinceToken) {
7575
+ var url = type;
7576
+ var query = { since: sinceToken };
7577
+ return new Ember.RSVP.Promise(function(resolve, reject) {
7578
+ jQuery.getJSON(url, query).then(function(data) {
7579
+ Ember.run(null, resolve, data);
7580
+ }, function(jqXHR) {
7581
+ jqXHR.then = null; // tame jQuery's ill mannered promises
7582
+ Ember.run(null, reject, jqXHR);
7583
+ });
7584
+ });
7585
+ }
7586
+ });
7587
+ ```
6958
7588
 
6959
7589
  @private
6960
7590
  @method findAll
6961
- @param store
6962
- @param type
6963
- @param since
7591
+ @param {DS.Store} store
7592
+ @param {subclass of DS.Model} type
7593
+ @param {String} sinceToken
7594
+ @return {Promise} promise
6964
7595
  */
6965
7596
  findAll: null,
6966
7597
 
6967
7598
  /**
7599
+ This method is called when you call `find` on the store with a
7600
+ query object as the second parameter (i.e. `store.find('person', {
7601
+ page: 1 })`).
7602
+
7603
+ Example
7604
+
7605
+ ```javascript
7606
+ App.ApplicationAdapter = DS.Adapter.extend({
7607
+ findQuery: function(store, type, query) {
7608
+ var url = type;
7609
+ return new Ember.RSVP.Promise(function(resolve, reject) {
7610
+ jQuery.getJSON(url, query).then(function(data) {
7611
+ Ember.run(null, resolve, data);
7612
+ }, function(jqXHR) {
7613
+ jqXHR.then = null; // tame jQuery's ill mannered promises
7614
+ Ember.run(null, reject, jqXHR);
7615
+ });
7616
+ });
7617
+ }
7618
+ });
7619
+ ```
6968
7620
 
6969
7621
  @private
6970
7622
  @method findQuery
6971
- @param store
6972
- @param type
6973
- @param query
6974
- @param recordArray
7623
+ @param {DS.Store} store
7624
+ @param {subclass of DS.Model} type
7625
+ @param {Object} query
7626
+ @param {DS.AdapterPopulatedRecordArray} recordArray
7627
+ @return {Promise} promise
6975
7628
  */
6976
7629
  findQuery: null,
6977
7630
 
@@ -6999,15 +7652,30 @@ DS.Adapter = Ember.Object.extend({
6999
7652
  @method generateIdForRecord
7000
7653
  @param {DS.Store} store
7001
7654
  @param {DS.Model} record
7655
+ @return {String|Number} id
7002
7656
  */
7003
7657
  generateIdForRecord: null,
7004
7658
 
7005
7659
  /**
7006
7660
  Proxies to the serializer's `serialize` method.
7007
7661
 
7662
+ Example
7663
+
7664
+ ```javascript
7665
+ App.ApplicationAdapter = DS.Adapter.extend({
7666
+ createRecord: function(store, type, record) {
7667
+ var data = this.serialize(record, { includeId: true });
7668
+ var url = type;
7669
+
7670
+ // ...
7671
+ }
7672
+ });
7673
+ ```
7674
+
7008
7675
  @method serialize
7009
7676
  @param {DS.Model} record
7010
7677
  @param {Object} options
7678
+ @return {Object} serialized record
7011
7679
  */
7012
7680
  serialize: function(record, options) {
7013
7681
  return get(record, 'store').serializerFor(record.constructor.typeKey).serialize(record, options);
@@ -7019,13 +7687,36 @@ DS.Adapter = Ember.Object.extend({
7019
7687
 
7020
7688
  Serializes the record and send it to the server.
7021
7689
 
7022
- This implementation should call the adapter's `didCreateRecord`
7023
- method on success or `didError` method on failure.
7690
+ Example
7691
+
7692
+ ```javascript
7693
+ App.ApplicationAdapter = DS.Adapter.extend({
7694
+ createRecord: function(store, type, record) {
7695
+ var data = this.serialize(record, { includeId: true });
7696
+ var url = type;
7697
+
7698
+ return new Ember.RSVP.Promise(function(resolve, reject) {
7699
+ jQuery.ajax({
7700
+ type: 'POST',
7701
+ url: url,
7702
+ dataType: 'json',
7703
+ data: data
7704
+ }).then(function(data) {
7705
+ Ember.run(null, resolve, data);
7706
+ }, function(jqXHR) {
7707
+ jqXHR.then = null; // tame jQuery's ill mannered promises
7708
+ Ember.run(null, reject, jqXHR);
7709
+ });
7710
+ });
7711
+ }
7712
+ });
7713
+ ```
7024
7714
 
7025
7715
  @method createRecord
7026
7716
  @param {DS.Store} store
7027
7717
  @param {subclass of DS.Model} type the DS.Model class of the record
7028
7718
  @param {DS.Model} record
7719
+ @return {Promise} promise
7029
7720
  */
7030
7721
  createRecord: Ember.required(Function),
7031
7722
 
@@ -7035,10 +7726,37 @@ DS.Adapter = Ember.Object.extend({
7035
7726
 
7036
7727
  Serializes the record update and send it to the server.
7037
7728
 
7729
+ Example
7730
+
7731
+ ```javascript
7732
+ App.ApplicationAdapter = DS.Adapter.extend({
7733
+ updateRecord: function(store, type, record) {
7734
+ var data = this.serialize(record, { includeId: true });
7735
+ var id = record.get('id');
7736
+ var url = [type, id].join('/');
7737
+
7738
+ return new Ember.RSVP.Promise(function(resolve, reject) {
7739
+ jQuery.ajax({
7740
+ type: 'PUT',
7741
+ url: url,
7742
+ dataType: 'json',
7743
+ data: data
7744
+ }).then(function(data) {
7745
+ Ember.run(null, resolve, data);
7746
+ }, function(jqXHR) {
7747
+ jqXHR.then = null; // tame jQuery's ill mannered promises
7748
+ Ember.run(null, reject, jqXHR);
7749
+ });
7750
+ });
7751
+ }
7752
+ });
7753
+ ```
7754
+
7038
7755
  @method updateRecord
7039
7756
  @param {DS.Store} store
7040
7757
  @param {subclass of DS.Model} type the DS.Model class of the record
7041
7758
  @param {DS.Model} record
7759
+ @return {Promise} promise
7042
7760
  */
7043
7761
  updateRecord: Ember.required(Function),
7044
7762
 
@@ -7048,10 +7766,37 @@ DS.Adapter = Ember.Object.extend({
7048
7766
 
7049
7767
  Sends a delete request for the record to the server.
7050
7768
 
7769
+ Example
7770
+
7771
+ ```javascript
7772
+ App.ApplicationAdapter = DS.Adapter.extend({
7773
+ deleteRecord: function(store, type, record) {
7774
+ var data = this.serialize(record, { includeId: true });
7775
+ var id = record.get('id');
7776
+ var url = [type, id].join('/');
7777
+
7778
+ return new Ember.RSVP.Promise(function(resolve, reject) {
7779
+ jQuery.ajax({
7780
+ type: 'DELETE',
7781
+ url: url,
7782
+ dataType: 'json',
7783
+ data: data
7784
+ }).then(function(data) {
7785
+ Ember.run(null, resolve, data);
7786
+ }, function(jqXHR) {
7787
+ jqXHR.then = null; // tame jQuery's ill mannered promises
7788
+ Ember.run(null, reject, jqXHR);
7789
+ });
7790
+ });
7791
+ }
7792
+ });
7793
+ ```
7794
+
7051
7795
  @method deleteRecord
7052
7796
  @param {DS.Store} store
7053
7797
  @param {subclass of DS.Model} type the DS.Model class of the record
7054
7798
  @param {DS.Model} record
7799
+ @return {Promise} promise
7055
7800
  */
7056
7801
  deleteRecord: Ember.required(Function),
7057
7802
 
@@ -7062,10 +7807,29 @@ DS.Adapter = Ember.Object.extend({
7062
7807
  May be overwritten to improve performance and reduce the number of
7063
7808
  server requests.
7064
7809
 
7810
+ Example
7811
+
7812
+ ```javascript
7813
+ App.ApplicationAdapter = DS.Adapter.extend({
7814
+ findMany: function(store, type, ids) {
7815
+ var url = type;
7816
+ return new Ember.RSVP.Promise(function(resolve, reject) {
7817
+ jQuery.getJSON(url, {ids: ids}).then(function(data) {
7818
+ Ember.run(null, resolve, data);
7819
+ }, function(jqXHR) {
7820
+ jqXHR.then = null; // tame jQuery's ill mannered promises
7821
+ Ember.run(null, reject, jqXHR);
7822
+ });
7823
+ });
7824
+ }
7825
+ });
7826
+ ```
7827
+
7065
7828
  @method findMany
7066
7829
  @param {DS.Store} store
7067
7830
  @param {subclass of DS.Model} type the DS.Model class of the records
7068
7831
  @param {Array} ids
7832
+ @return {Promise} promise
7069
7833
  */
7070
7834
  findMany: function(store, type, ids) {
7071
7835
  var promises = map.call(ids, function(id) {
@@ -7099,6 +7863,10 @@ var counter = 0;
7099
7863
  system would do. Its possible to do develop your entire application
7100
7864
  with `DS.FixtureAdapter`.
7101
7865
 
7866
+ For information on how to use the `FixtureAdapter` in your
7867
+ application please see the [FixtureAdapter
7868
+ guide](/guides/models/the-fixture-adapter/).
7869
+
7102
7870
  @class FixtureAdapter
7103
7871
  @namespace DS
7104
7872
  @extends DS.Adapter
@@ -7107,15 +7875,36 @@ DS.FixtureAdapter = DS.Adapter.extend({
7107
7875
  // by default, fixtures are already in normalized form
7108
7876
  serializer: null,
7109
7877
 
7878
+ /**
7879
+ If `simulateRemoteResponse` is `true` the `FixtureAdapter` will
7880
+ wait a number of milliseconds before resolving promises with the
7881
+ fixture values. The wait time can be configured via the `latency`
7882
+ property.
7883
+
7884
+ @property simulateRemoteResponse
7885
+ @type {Boolean}
7886
+ @default true
7887
+ */
7110
7888
  simulateRemoteResponse: true,
7111
7889
 
7890
+ /**
7891
+ By default the `FixtureAdapter` will simulate a wait of the
7892
+ `latency` milliseconds before resolving promises with the fixture
7893
+ values. This behavior can be turned off via the
7894
+ `simulateRemoteResponse` property.
7895
+
7896
+ @property latency
7897
+ @type {Number}
7898
+ @default 50
7899
+ */
7112
7900
  latency: 50,
7113
7901
 
7114
7902
  /**
7115
7903
  Implement this method in order to provide data associated with a type
7116
7904
 
7117
7905
  @method fixturesForType
7118
- @param type
7906
+ @param {Subclass of DS.Model} type
7907
+ @return {Array}
7119
7908
  */
7120
7909
  fixturesForType: function(type) {
7121
7910
  if (type.FIXTURES) {
@@ -7136,9 +7925,10 @@ DS.FixtureAdapter = DS.Adapter.extend({
7136
7925
  Implement this method in order to query fixtures data
7137
7926
 
7138
7927
  @method queryFixtures
7139
- @param fixture
7140
- @param query
7141
- @param type
7928
+ @param {Array} fixture
7929
+ @param {Object} query
7930
+ @param {Subclass of DS.Model} type
7931
+ @return {Promise|Array}
7142
7932
  */
7143
7933
  queryFixtures: function(fixtures, query, type) {
7144
7934
 
@@ -7146,8 +7936,8 @@ DS.FixtureAdapter = DS.Adapter.extend({
7146
7936
 
7147
7937
  /**
7148
7938
  @method updateFixtures
7149
- @param type
7150
- @param fixture
7939
+ @param {Subclass of DS.Model} type
7940
+ @param {Array} fixture
7151
7941
  */
7152
7942
  updateFixtures: function(type, fixture) {
7153
7943
  if(!type.FIXTURES) {
@@ -7165,8 +7955,8 @@ DS.FixtureAdapter = DS.Adapter.extend({
7165
7955
  Implement this method in order to provide json for CRUD methods
7166
7956
 
7167
7957
  @method mockJSON
7168
- @param type
7169
- @param record
7958
+ @param {Subclass of DS.Model} type
7959
+ @param {DS.Model} record
7170
7960
  */
7171
7961
  mockJSON: function(store, type, record) {
7172
7962
  return store.serializerFor(type).serialize(record, { includeId: true });
@@ -7174,8 +7964,9 @@ DS.FixtureAdapter = DS.Adapter.extend({
7174
7964
 
7175
7965
  /**
7176
7966
  @method generateIdForRecord
7177
- @param store
7178
- @param record
7967
+ @param {DS.Store} store
7968
+ @param {DS.Model} record
7969
+ @return {String} id
7179
7970
  */
7180
7971
  generateIdForRecord: function(store) {
7181
7972
  return "fixture-" + counter++;
@@ -7183,9 +7974,10 @@ DS.FixtureAdapter = DS.Adapter.extend({
7183
7974
 
7184
7975
  /**
7185
7976
  @method find
7186
- @param store
7187
- @param type
7188
- @param id
7977
+ @param {DS.Store} store
7978
+ @param {subclass of DS.Model} type
7979
+ @param {String} id
7980
+ @return {Promise} promise
7189
7981
  */
7190
7982
  find: function(store, type, id) {
7191
7983
  var fixtures = this.fixturesForType(type),
@@ -7205,9 +7997,10 @@ DS.FixtureAdapter = DS.Adapter.extend({
7205
7997
 
7206
7998
  /**
7207
7999
  @method findMany
7208
- @param store
7209
- @param type
7210
- @param ids
8000
+ @param {DS.Store} store
8001
+ @param {subclass of DS.Model} type
8002
+ @param {Array} ids
8003
+ @return {Promise} promise
7211
8004
  */
7212
8005
  findMany: function(store, type, ids) {
7213
8006
  var fixtures = this.fixturesForType(type);
@@ -7229,8 +8022,10 @@ DS.FixtureAdapter = DS.Adapter.extend({
7229
8022
  /**
7230
8023
  @private
7231
8024
  @method findAll
7232
- @param store
7233
- @param type
8025
+ @param {DS.Store} store
8026
+ @param {subclass of DS.Model} type
8027
+ @param {String} sinceToken
8028
+ @return {Promise} promise
7234
8029
  */
7235
8030
  findAll: function(store, type) {
7236
8031
  var fixtures = this.fixturesForType(type);
@@ -7244,10 +8039,11 @@ DS.FixtureAdapter = DS.Adapter.extend({
7244
8039
  /**
7245
8040
  @private
7246
8041
  @method findQuery
7247
- @param store
7248
- @param type
7249
- @param query
7250
- @param array
8042
+ @param {DS.Store} store
8043
+ @param {subclass of DS.Model} type
8044
+ @param {Object} query
8045
+ @param {DS.AdapterPopulatedRecordArray} recordArray
8046
+ @return {Promise} promise
7251
8047
  */
7252
8048
  findQuery: function(store, type, query, array) {
7253
8049
  var fixtures = this.fixturesForType(type);
@@ -7264,9 +8060,10 @@ DS.FixtureAdapter = DS.Adapter.extend({
7264
8060
 
7265
8061
  /**
7266
8062
  @method createRecord
7267
- @param store
7268
- @param type
7269
- @param record
8063
+ @param {DS.Store} store
8064
+ @param {subclass of DS.Model} type
8065
+ @param {DS.Model} record
8066
+ @return {Promise} promise
7270
8067
  */
7271
8068
  createRecord: function(store, type, record) {
7272
8069
  var fixture = this.mockJSON(store, type, record);
@@ -7280,9 +8077,10 @@ DS.FixtureAdapter = DS.Adapter.extend({
7280
8077
 
7281
8078
  /**
7282
8079
  @method updateRecord
7283
- @param store
7284
- @param type
7285
- @param record
8080
+ @param {DS.Store} store
8081
+ @param {subclass of DS.Model} type
8082
+ @param {DS.Model} record
8083
+ @return {Promise} promise
7286
8084
  */
7287
8085
  updateRecord: function(store, type, record) {
7288
8086
  var fixture = this.mockJSON(store, type, record);
@@ -7296,9 +8094,10 @@ DS.FixtureAdapter = DS.Adapter.extend({
7296
8094
 
7297
8095
  /**
7298
8096
  @method deleteRecord
7299
- @param store
7300
- @param type
7301
- @param record
8097
+ @param {DS.Store} store
8098
+ @param {subclass of DS.Model} type
8099
+ @param {DS.Model} record
8100
+ @return {Promise} promise
7302
8101
  */
7303
8102
  deleteRecord: function(store, type, record) {
7304
8103
  var fixture = this.mockJSON(store, type, record);
@@ -7343,8 +8142,8 @@ DS.FixtureAdapter = DS.Adapter.extend({
7343
8142
  /*
7344
8143
  @method findFixtureById
7345
8144
  @private
7346
- @param type
7347
- @param record
8145
+ @param fixtures
8146
+ @param id
7348
8147
  */
7349
8148
  findFixtureById: function(fixtures, id) {
7350
8149
  return Ember.A(fixtures).find(function(r) {
@@ -7439,6 +8238,55 @@ function coerceId(id) {
7439
8238
  @extends DS.JSONSerializer
7440
8239
  */
7441
8240
  DS.RESTSerializer = DS.JSONSerializer.extend({
8241
+ /**
8242
+ If you want to do normalizations specific to some part of the payload, you
8243
+ can specify those under `normalizeHash`.
8244
+
8245
+ For example, given the following json where the the `IDs` under
8246
+ `"comments"` are provided as `_id` instead of `id`.
8247
+
8248
+ ```javascript
8249
+ {
8250
+ "post": {
8251
+ "id": 1,
8252
+ "title": "Rails is omakase",
8253
+ "comments": [ 1, 2 ]
8254
+ },
8255
+ "comments": [{
8256
+ "_id": 1,
8257
+ "body": "FIRST"
8258
+ }, {
8259
+ "_id": 2,
8260
+ "body": "Rails is unagi"
8261
+ }]
8262
+ }
8263
+ ```
8264
+
8265
+ You use `normalizeHash` to normalize just the comments:
8266
+
8267
+ ```javascript
8268
+ App.PostSerializer = DS.RESTSerializer.extend({
8269
+ normalizeHash: {
8270
+ comments: function(hash) {
8271
+ hash.id = hash._id;
8272
+ delete hash._id;
8273
+ return hash;
8274
+ }
8275
+ }
8276
+ });
8277
+ ```
8278
+
8279
+ The key under `normalizeHash` is usually just the original key
8280
+ that was in the original payload. However, key names will be
8281
+ impacted by any modifications done in the `normalizePayload`
8282
+ method. The `DS.RESTSerializer`'s default implemention makes no
8283
+ changes to the payload keys.
8284
+
8285
+ @property normalizeHash
8286
+ @type {Object}
8287
+ @default undefined
8288
+ */
8289
+
7442
8290
  /**
7443
8291
  Normalizes a part of the JSON payload returned by
7444
8292
  the server. You should override this method, munge the hash
@@ -7505,10 +8353,11 @@ DS.RESTSerializer = DS.JSONSerializer.extend({
7505
8353
  */
7506
8354
  normalize: function(type, hash, prop) {
7507
8355
  this.normalizeId(hash);
7508
- this.normalizeUsingDeclaredMapping(type, hash);
7509
8356
  this.normalizeAttributes(type, hash);
7510
8357
  this.normalizeRelationships(type, hash);
7511
8358
 
8359
+ this.normalizeUsingDeclaredMapping(type, hash);
8360
+
7512
8361
  if (this.normalizeHash && this.normalizeHash[prop]) {
7513
8362
  this.normalizeHash[prop](hash);
7514
8363
  }
@@ -7564,9 +8413,13 @@ DS.RESTSerializer = DS.JSONSerializer.extend({
7564
8413
  if (attrs) {
7565
8414
  for (key in attrs) {
7566
8415
  payloadKey = attrs[key];
7567
-
7568
- hash[key] = hash[payloadKey];
7569
- delete hash[payloadKey];
8416
+ if (payloadKey && payloadKey.key) {
8417
+ payloadKey = payloadKey.key;
8418
+ }
8419
+ if (typeof payloadKey === 'string') {
8420
+ hash[key] = hash[payloadKey];
8421
+ delete hash[payloadKey];
8422
+ }
7570
8423
  }
7571
8424
  }
7572
8425
  },
@@ -7905,7 +8758,7 @@ DS.RESTSerializer = DS.JSONSerializer.extend({
7905
8758
  type = store.modelFor(typeName);
7906
8759
 
7907
8760
  /*jshint loopfunc:true*/
7908
- var normalizedArray = map.call(payload[prop], function(hash) {
8761
+ var normalizedArray = map.call(Ember.makeArray(payload[prop]), function(hash) {
7909
8762
  return this.normalize(type, hash, prop);
7910
8763
  }, this);
7911
8764
 
@@ -8161,8 +9014,8 @@ var forEach = Ember.ArrayPolyfills.forEach;
8161
9014
  ```js
8162
9015
  {
8163
9016
  "post": {
8164
- title: "I'm Running to Reform the W3C's Tag",
8165
- author: "Yehuda Katz"
9017
+ "title": "I'm Running to Reform the W3C's Tag",
9018
+ "author": "Yehuda Katz"
8166
9019
  }
8167
9020
  }
8168
9021
  ```
@@ -8240,6 +9093,55 @@ var forEach = Ember.ArrayPolyfills.forEach;
8240
9093
  DS.RESTAdapter = DS.Adapter.extend({
8241
9094
  defaultSerializer: '_rest',
8242
9095
 
9096
+
9097
+ /**
9098
+ Endpoint paths can be prefixed with a `namespace` by setting the namespace
9099
+ property on the adapter:
9100
+
9101
+ ```javascript
9102
+ DS.RESTAdapter.reopen({
9103
+ namespace: 'api/1'
9104
+ });
9105
+ ```
9106
+
9107
+ Requests for `App.Post` would now target `/api/1/post/`.
9108
+
9109
+ @property namespace
9110
+ @type {String}
9111
+ */
9112
+
9113
+ /**
9114
+ An adapter can target other hosts by setting the `host` property.
9115
+
9116
+ ```javascript
9117
+ DS.RESTAdapter.reopen({
9118
+ host: 'https://api.example.com'
9119
+ });
9120
+ ```
9121
+
9122
+ Requests for `App.Post` would now target `https://api.example.com/post/`.
9123
+
9124
+ @property host
9125
+ @type {String}
9126
+ */
9127
+
9128
+ /**
9129
+ Some APIs require HTTP headers, e.g. to provide an API key. An array of
9130
+ headers can be added to the adapter which are passed with every request:
9131
+
9132
+ ```javascript
9133
+ DS.RESTAdapter.reopen({
9134
+ headers: {
9135
+ "API_KEY": "secret key",
9136
+ "ANOTHER_HEADER": "Some header value"
9137
+ }
9138
+ });
9139
+ ```
9140
+
9141
+ @property headers
9142
+ @type {Object}
9143
+ */
9144
+
8243
9145
  /**
8244
9146
  Called by the store in order to fetch the JSON for a given
8245
9147
  type and ID.
@@ -8250,12 +9152,10 @@ DS.RESTAdapter = DS.Adapter.extend({
8250
9152
  This method performs an HTTP `GET` request with the id provided as part of the querystring.
8251
9153
 
8252
9154
  @method find
8253
- @see RESTAdapter/buildURL
8254
- @see RESTAdapter/ajax
8255
9155
  @param {DS.Store} store
8256
9156
  @param {subclass of DS.Model} type
8257
9157
  @param {String} id
8258
- @returns Promise
9158
+ @returns {Promise} promise
8259
9159
  */
8260
9160
  find: function(store, type, id) {
8261
9161
  return this.ajax(this.buildURL(type.typeKey, id), 'GET');
@@ -8270,12 +9170,10 @@ DS.RESTAdapter = DS.Adapter.extend({
8270
9170
 
8271
9171
  @private
8272
9172
  @method findAll
8273
- @see RESTAdapter/buildURL
8274
- @see RESTAdapter/ajax
8275
9173
  @param {DS.Store} store
8276
9174
  @param {subclass of DS.Model} type
8277
9175
  @param {String} sinceToken
8278
- @returns Promise
9176
+ @returns {Promise} promise
8279
9177
  */
8280
9178
  findAll: function(store, type, sinceToken) {
8281
9179
  var query;
@@ -8299,12 +9197,10 @@ DS.RESTAdapter = DS.Adapter.extend({
8299
9197
 
8300
9198
  @private
8301
9199
  @method findQuery
8302
- @see RESTAdapter/buildURL
8303
- @see RESTAdapter/ajax
8304
9200
  @param {DS.Store} store
8305
9201
  @param {subclass of DS.Model} type
8306
9202
  @param {Object} query
8307
- @returns Promise
9203
+ @returns {Promise} promise
8308
9204
  */
8309
9205
  findQuery: function(store, type, query) {
8310
9206
  return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query });
@@ -8339,14 +9235,12 @@ DS.RESTAdapter = DS.Adapter.extend({
8339
9235
  promise for the resulting payload.
8340
9236
 
8341
9237
  @method findMany
8342
- @see RESTAdapter/buildURL
8343
- @see RESTAdapter/ajax
8344
9238
  @param {DS.Store} store
8345
9239
  @param {subclass of DS.Model} type
8346
- @param {Array<String>} ids
8347
- @returns Promise
9240
+ @param {Array} ids
9241
+ @returns {Promise} promise
8348
9242
  */
8349
- findMany: function(store, type, ids, owner) {
9243
+ findMany: function(store, type, ids) {
8350
9244
  return this.ajax(this.buildURL(type.typeKey), 'GET', { data: { ids: ids } });
8351
9245
  },
8352
9246
 
@@ -8374,12 +9268,10 @@ DS.RESTAdapter = DS.Adapter.extend({
8374
9268
  request will use the host specified on the adapter (if any).
8375
9269
 
8376
9270
  @method findHasMany
8377
- @see RESTAdapter/buildURL
8378
- @see RESTAdapter/ajax
8379
9271
  @param {DS.Store} store
8380
9272
  @param {DS.Model} record
8381
9273
  @param {String} url
8382
- @returns Promise
9274
+ @returns {Promise} promise
8383
9275
  */
8384
9276
  findHasMany: function(store, record, url) {
8385
9277
  var host = get(this, 'host'),
@@ -8415,12 +9307,10 @@ DS.RESTAdapter = DS.Adapter.extend({
8415
9307
  The `findBelongsTo` method will make an Ajax (HTTP GET) request to the originally specified URL.
8416
9308
 
8417
9309
  @method findBelongsTo
8418
- @see RESTAdapter/buildURL
8419
- @see RESTAdapter/ajax
8420
9310
  @param {DS.Store} store
8421
9311
  @param {DS.Model} record
8422
9312
  @param {String} url
8423
- @returns Promise
9313
+ @returns {Promise} promise
8424
9314
  */
8425
9315
  findBelongsTo: function(store, record, url) {
8426
9316
  var id = get(record, 'id'),
@@ -8440,13 +9330,10 @@ DS.RESTAdapter = DS.Adapter.extend({
8440
9330
  of a record.
8441
9331
 
8442
9332
  @method createRecord
8443
- @see RESTAdapter/buildURL
8444
- @see RESTAdapter/ajax
8445
- @see RESTAdapter/serialize
8446
9333
  @param {DS.Store} store
8447
9334
  @param {subclass of DS.Model} type
8448
9335
  @param {DS.Model} record
8449
- @returns Promise
9336
+ @returns {Promise} promise
8450
9337
  */
8451
9338
  createRecord: function(store, type, record) {
8452
9339
  var data = {};
@@ -8468,13 +9355,10 @@ DS.RESTAdapter = DS.Adapter.extend({
8468
9355
  of a record.
8469
9356
 
8470
9357
  @method updateRecord
8471
- @see RESTAdapter/buildURL
8472
- @see RESTAdapter/ajax
8473
- @see RESTAdapter/serialize
8474
9358
  @param {DS.Store} store
8475
9359
  @param {subclass of DS.Model} type
8476
9360
  @param {DS.Model} record
8477
- @returns Promise
9361
+ @returns {Promise} promise
8478
9362
  */
8479
9363
  updateRecord: function(store, type, record) {
8480
9364
  var data = {};
@@ -8493,13 +9377,10 @@ DS.RESTAdapter = DS.Adapter.extend({
8493
9377
  The `deleteRecord` method makes an Ajax (HTTP DELETE) request to a URL computed by `buildURL`.
8494
9378
 
8495
9379
  @method deleteRecord
8496
- @see RESTAdapter/buildURL
8497
- @see RESTAdapter/ajax
8498
- @see RESTAdapter/serialize
8499
9380
  @param {DS.Store} store
8500
9381
  @param {subclass of DS.Model} type
8501
9382
  @param {DS.Model} record
8502
- @returns Promise
9383
+ @returns {Promise} promise
8503
9384
  */
8504
9385
  deleteRecord: function(store, type, record) {
8505
9386
  var id = get(record, 'id');
@@ -8510,8 +9391,9 @@ DS.RESTAdapter = DS.Adapter.extend({
8510
9391
  /**
8511
9392
  Builds a URL for a given type and optional ID.
8512
9393
 
8513
- By default, it pluralizes the type's name (for example,
8514
- 'post' becomes 'posts' and 'person' becomes 'people').
9394
+ By default, it pluralizes the type's name (for example, 'post'
9395
+ becomes 'posts' and 'person' becomes 'people'). To override the
9396
+ pluralization see [pathForType](#method_pathForType).
8515
9397
 
8516
9398
  If an ID is specified, it adds the ID to the path generated
8517
9399
  for the type, separated by a `/`.
@@ -8519,7 +9401,7 @@ DS.RESTAdapter = DS.Adapter.extend({
8519
9401
  @method buildURL
8520
9402
  @param {String} type
8521
9403
  @param {String} id
8522
- @returns String
9404
+ @returns {String} url
8523
9405
  */
8524
9406
  buildURL: function(type, id) {
8525
9407
  var url = [],
@@ -8537,6 +9419,13 @@ DS.RESTAdapter = DS.Adapter.extend({
8537
9419
  return url;
8538
9420
  },
8539
9421
 
9422
+ /**
9423
+ @method urlPrefix
9424
+ @private
9425
+ @param {String} path
9426
+ @param {String} parentUrl
9427
+ @return {String} urlPrefix
9428
+ */
8540
9429
  urlPrefix: function(path, parentURL) {
8541
9430
  var host = get(this, 'host'),
8542
9431
  namespace = get(this, 'namespace'),
@@ -8587,7 +9476,7 @@ DS.RESTAdapter = DS.Adapter.extend({
8587
9476
 
8588
9477
  @method pathForType
8589
9478
  @param {String} type
8590
- @returns String
9479
+ @returns {String} path
8591
9480
  **/
8592
9481
  pathForType: function(type) {
8593
9482
  return Ember.String.pluralize(type);
@@ -8596,12 +9485,36 @@ DS.RESTAdapter = DS.Adapter.extend({
8596
9485
  /**
8597
9486
  Takes an ajax response, and returns a relavant error.
8598
9487
 
8599
- By default, the `ajaxError` method has the following behavior:
9488
+ Returning a `DS.InvalidError` from this method will cause the
9489
+ record to transition into the `invalid` state and make the
9490
+ `errors` object available on the record.
9491
+
9492
+ ```javascript
9493
+ App.ApplicationAdapter = DS.RESTAdapter.extend({
9494
+ ajaxError: function(jqXHR) {
9495
+ var error = this._super(jqXHR);
9496
+
9497
+ if (jqXHR && jqXHR.status === 422) {
9498
+ var jsonErrors = Ember.$.parseJSON(jqXHR.responseText)["errors"];
9499
+
9500
+ return new DS.InvalidError(jsonErrors);
9501
+ } else {
9502
+ return error;
9503
+ }
9504
+ }
9505
+ });
9506
+ ```
8600
9507
 
8601
- * It simply returns the ajax response (jqXHR).
9508
+ Note: As a correctness optimization, the default implementation of
9509
+ the `ajaxError` method strips out the `then` method from jquery's
9510
+ ajax response (jqXHR). This is important because the jqXHR's
9511
+ `then` method fulfills the promise with itself resulting in a
9512
+ circular "thenable" chain which may cause problems for some
9513
+ promise libraries.
8602
9514
 
8603
9515
  @method ajaxError
8604
- @param jqXHR
9516
+ @param {Object} jqXHR
9517
+ @return {Object} jqXHR
8605
9518
  */
8606
9519
  ajaxError: function(jqXHR) {
8607
9520
  if (jqXHR) {
@@ -8630,9 +9543,10 @@ DS.RESTAdapter = DS.Adapter.extend({
8630
9543
 
8631
9544
  @method ajax
8632
9545
  @private
8633
- @param url
8634
- @param type
8635
- @param hash
9546
+ @param {String} url
9547
+ @param {String} type The request type GET, POST, PUT, DELETE ect.
9548
+ @param {Object} hash
9549
+ @return {Promise} promise
8636
9550
  */
8637
9551
  ajax: function(url, type, hash) {
8638
9552
  var adapter = this;
@@ -8652,6 +9566,14 @@ DS.RESTAdapter = DS.Adapter.extend({
8652
9566
  }, "DS: RestAdapter#ajax " + type + " to " + url);
8653
9567
  },
8654
9568
 
9569
+ /**
9570
+ @method ajaxOptions
9571
+ @private
9572
+ @param {String} url
9573
+ @param {String} type The request type GET, POST, PUT, DELETE ect.
9574
+ @param {Object} hash
9575
+ @return {Object} hash
9576
+ */
8655
9577
  ajaxOptions: function(url, type, hash) {
8656
9578
  hash = hash || {};
8657
9579
  hash.url = url;