main
    1// Fetched from channel: release, with url http://builds.emberjs.com/beta/ember-data.js
    2// Fetched on: 2014-11-11T00:40:24Z
    3(function(global){
    4var define, requireModule, require, requirejs;
    5
    6(function() {
    7
    8  var _isArray;
    9  if (!Array.isArray) {
   10    _isArray = function (x) {
   11      return Object.prototype.toString.call(x) === "[object Array]";
   12    };
   13  } else {
   14    _isArray = Array.isArray;
   15  }
   16  
   17  var registry = {}, seen = {}, state = {};
   18  var FAILED = false;
   19
   20  define = function(name, deps, callback) {
   21  
   22    if (!_isArray(deps)) {
   23      callback = deps;
   24      deps     =  [];
   25    }
   26  
   27    registry[name] = {
   28      deps: deps,
   29      callback: callback
   30    };
   31  };
   32
   33  function reify(deps, name, seen) {
   34    var length = deps.length;
   35    var reified = new Array(length);
   36    var dep;
   37    var exports;
   38
   39    for (var i = 0, l = length; i < l; i++) {
   40      dep = deps[i];
   41      if (dep === 'exports') {
   42        exports = reified[i] = seen;
   43      } else {
   44        reified[i] = require(resolve(dep, name));
   45      }
   46    }
   47
   48    return {
   49      deps: reified,
   50      exports: exports
   51    };
   52  }
   53
   54  requirejs = require = requireModule = function(name) {
   55    if (state[name] !== FAILED &&
   56        seen.hasOwnProperty(name)) {
   57      return seen[name];
   58    }
   59
   60    if (!registry[name]) {
   61      throw new Error('Could not find module ' + name);
   62    }
   63
   64    var mod = registry[name];
   65    var reified;
   66    var module;
   67    var loaded = false;
   68
   69    seen[name] = { }; // placeholder for run-time cycles
   70
   71    try {
   72      reified = reify(mod.deps, name, seen[name]);
   73      module = mod.callback.apply(this, reified.deps);
   74      loaded = true;
   75    } finally {
   76      if (!loaded) {
   77        state[name] = FAILED;
   78      }
   79    }
   80
   81    return reified.exports ? seen[name] : (seen[name] = module);
   82  };
   83
   84  function resolve(child, name) {
   85    if (child.charAt(0) !== '.') { return child; }
   86
   87    var parts = child.split('/');
   88    var nameParts = name.split('/');
   89    var parentBase;
   90
   91    if (nameParts.length === 1) {
   92      parentBase = nameParts;
   93    } else {
   94      parentBase = nameParts.slice(0, -1);
   95    }
   96
   97    for (var i = 0, l = parts.length; i < l; i++) {
   98      var part = parts[i];
   99
  100      if (part === '..') { parentBase.pop(); }
  101      else if (part === '.') { continue; }
  102      else { parentBase.push(part); }
  103    }
  104
  105    return parentBase.join('/');
  106  }
  107
  108  requirejs.entries = requirejs._eak_seen = registry;
  109  requirejs.clear = function(){
  110    requirejs.entries = requirejs._eak_seen = registry = {};
  111    seen = state = {};
  112  };
  113})();
  114
  115define("activemodel-adapter",
  116  ["activemodel-adapter/system","exports"],
  117  function(__dependency1__, __exports__) {
  118    "use strict";
  119    var ActiveModelAdapter = __dependency1__.ActiveModelAdapter;
  120    var ActiveModelSerializer = __dependency1__.ActiveModelSerializer;
  121
  122    __exports__.ActiveModelAdapter = ActiveModelAdapter;
  123    __exports__.ActiveModelSerializer = ActiveModelSerializer;
  124  });
  125define("activemodel-adapter/setup-container",
  126  ["ember-data/system/container_proxy","activemodel-adapter/system/active_model_serializer","activemodel-adapter/system/active_model_adapter","exports"],
  127  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
  128    "use strict";
  129    var ContainerProxy = __dependency1__["default"];
  130    var ActiveModelSerializer = __dependency2__["default"];
  131    var ActiveModelAdapter = __dependency3__["default"];
  132
  133    __exports__["default"] = function setupActiveModelAdapter(container, application){
  134      var proxy = new ContainerProxy(container);
  135      proxy.registerDeprecations([
  136        { deprecated: 'serializer:_ams',  valid: 'serializer:-active-model' },
  137        { deprecated: 'adapter:_ams',     valid: 'adapter:-active-model' }
  138      ]);
  139
  140      container.register('serializer:-active-model', ActiveModelSerializer);
  141      container.register('adapter:-active-model', ActiveModelAdapter);
  142    };
  143  });
  144define("activemodel-adapter/system",
  145  ["activemodel-adapter/system/active_model_adapter","activemodel-adapter/system/active_model_serializer","exports"],
  146  function(__dependency1__, __dependency2__, __exports__) {
  147    "use strict";
  148    var ActiveModelAdapter = __dependency1__["default"];
  149    var ActiveModelSerializer = __dependency2__["default"];
  150
  151    __exports__.ActiveModelAdapter = ActiveModelAdapter;
  152    __exports__.ActiveModelSerializer = ActiveModelSerializer;
  153  });
  154define("activemodel-adapter/system/active_model_adapter",
  155  ["ember-data/adapters","ember-data/system/adapter","ember-inflector","exports"],
  156  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
  157    "use strict";
  158    var RESTAdapter = __dependency1__.RESTAdapter;
  159    var InvalidError = __dependency2__.InvalidError;
  160    var pluralize = __dependency3__.pluralize;
  161
  162    /**
  163      @module ember-data
  164    */
  165
  166    var forEach = Ember.EnumerableUtils.forEach;
  167    var decamelize = Ember.String.decamelize,
  168        underscore = Ember.String.underscore;
  169
  170    /**
  171      The ActiveModelAdapter is a subclass of the RESTAdapter designed to integrate
  172      with a JSON API that uses an underscored naming convention instead of camelCasing.
  173      It has been designed to work out of the box with the
  174      [active_model_serializers](http://github.com/rails-api/active_model_serializers)
  175      Ruby gem. This Adapter expects specific settings using ActiveModel::Serializers,
  176      `embed :ids, include: true` which sideloads the records.
  177
  178      This adapter extends the DS.RESTAdapter by making consistent use of the camelization,
  179      decamelization and pluralization methods to normalize the serialized JSON into a
  180      format that is compatible with a conventional Rails backend and Ember Data.
  181
  182      ## JSON Structure
  183
  184      The ActiveModelAdapter expects the JSON returned from your server to follow
  185      the REST adapter conventions substituting underscored keys for camelcased ones.
  186
  187      Unlike the DS.RESTAdapter, async relationship keys must be the singular form
  188      of the relationship name, followed by "_id" for DS.belongsTo relationships,
  189      or "_ids" for DS.hasMany relationships.
  190
  191      ### Conventional Names
  192
  193      Attribute names in your JSON payload should be the underscored versions of
  194      the attributes in your Ember.js models.
  195
  196      For example, if you have a `Person` model:
  197
  198      ```js
  199      App.FamousPerson = DS.Model.extend({
  200        firstName: DS.attr('string'),
  201        lastName: DS.attr('string'),
  202        occupation: DS.attr('string')
  203      });
  204      ```
  205
  206      The JSON returned should look like this:
  207
  208      ```js
  209      {
  210        "famous_person": {
  211          "id": 1,
  212          "first_name": "Barack",
  213          "last_name": "Obama",
  214          "occupation": "President"
  215        }
  216      }
  217      ```
  218
  219      Let's imagine that `Occupation` is just another model:
  220
  221      ```js
  222      App.Person = DS.Model.extend({
  223        firstName: DS.attr('string'),
  224        lastName: DS.attr('string'),
  225        occupation: DS.belongsTo('occupation')
  226      });
  227
  228      App.Occupation = DS.Model.extend({
  229        name: DS.attr('string'),
  230        salary: DS.attr('number'),
  231        people: DS.hasMany('person')
  232      });
  233      ```
  234
  235      The JSON needed to avoid extra server calls, should look like this:
  236
  237      ```js
  238      {
  239        "people": [{
  240          "id": 1,
  241          "first_name": "Barack",
  242          "last_name": "Obama",
  243          "occupation_id": 1
  244        }],
  245
  246        "occupations": [{
  247          "id": 1,
  248          "name": "President",
  249          "salary": 100000,
  250          "person_ids": [1]
  251        }]
  252      }
  253      ```
  254
  255      @class ActiveModelAdapter
  256      @constructor
  257      @namespace DS
  258      @extends DS.RESTAdapter
  259    **/
  260
  261    var ActiveModelAdapter = RESTAdapter.extend({
  262      defaultSerializer: '-active-model',
  263      /**
  264        The ActiveModelAdapter overrides the `pathForType` method to build
  265        underscored URLs by decamelizing and pluralizing the object type name.
  266
  267        ```js
  268          this.pathForType("famousPerson");
  269          //=> "famous_people"
  270        ```
  271
  272        @method pathForType
  273        @param {String} type
  274        @return String
  275      */
  276      pathForType: function(type) {
  277        var decamelized = decamelize(type);
  278        var underscored = underscore(decamelized);
  279        return pluralize(underscored);
  280      },
  281
  282      /**
  283        The ActiveModelAdapter overrides the `ajaxError` method
  284        to return a DS.InvalidError for all 422 Unprocessable Entity
  285        responses.
  286
  287        A 422 HTTP response from the server generally implies that the request
  288        was well formed but the API was unable to process it because the
  289        content was not semantically correct or meaningful per the API.
  290
  291        For more information on 422 HTTP Error code see 11.2 WebDAV RFC 4918
  292        https://tools.ietf.org/html/rfc4918#section-11.2
  293
  294        @method ajaxError
  295        @param {Object} jqXHR
  296        @return error
  297      */
  298      ajaxError: function(jqXHR) {
  299        var error = this._super(jqXHR);
  300
  301        if (jqXHR && jqXHR.status === 422) {
  302          var response = Ember.$.parseJSON(jqXHR.responseText),
  303              errors = {};
  304
  305          if (response.errors !== undefined) {
  306            var jsonErrors = response.errors;
  307
  308            forEach(Ember.keys(jsonErrors), function(key) {
  309              errors[Ember.String.camelize(key)] = jsonErrors[key];
  310            });
  311          }
  312
  313          return new InvalidError(errors);
  314        } else {
  315          return error;
  316        }
  317      }
  318    });
  319
  320    __exports__["default"] = ActiveModelAdapter;
  321  });
  322define("activemodel-adapter/system/active_model_serializer",
  323  ["ember-inflector","ember-data/serializers/rest_serializer","exports"],
  324  function(__dependency1__, __dependency2__, __exports__) {
  325    "use strict";
  326    var singularize = __dependency1__.singularize;
  327    var RESTSerializer = __dependency2__["default"];
  328    /**
  329      @module ember-data
  330    */
  331
  332    var get = Ember.get,
  333        forEach = Ember.EnumerableUtils.forEach,
  334        camelize =   Ember.String.camelize,
  335        capitalize = Ember.String.capitalize,
  336        decamelize = Ember.String.decamelize,
  337        underscore = Ember.String.underscore;
  338    /**
  339      The ActiveModelSerializer is a subclass of the RESTSerializer designed to integrate
  340      with a JSON API that uses an underscored naming convention instead of camelCasing.
  341      It has been designed to work out of the box with the
  342      [active_model_serializers](http://github.com/rails-api/active_model_serializers)
  343      Ruby gem. This Serializer expects specific settings using ActiveModel::Serializers,
  344      `embed :ids, include: true` which sideloads the records.
  345
  346      This serializer extends the DS.RESTSerializer by making consistent
  347      use of the camelization, decamelization and pluralization methods to
  348      normalize the serialized JSON into a format that is compatible with
  349      a conventional Rails backend and Ember Data.
  350
  351      ## JSON Structure
  352
  353      The ActiveModelSerializer expects the JSON returned from your server
  354      to follow the REST adapter conventions substituting underscored keys
  355      for camelcased ones.
  356
  357      ### Conventional Names
  358
  359      Attribute names in your JSON payload should be the underscored versions of
  360      the attributes in your Ember.js models.
  361
  362      For example, if you have a `Person` model:
  363
  364      ```js
  365      App.FamousPerson = DS.Model.extend({
  366        firstName: DS.attr('string'),
  367        lastName: DS.attr('string'),
  368        occupation: DS.attr('string')
  369      });
  370      ```
  371
  372      The JSON returned should look like this:
  373
  374      ```js
  375      {
  376        "famous_person": {
  377          "id": 1,
  378          "first_name": "Barack",
  379          "last_name": "Obama",
  380          "occupation": "President"
  381        }
  382      }
  383      ```
  384
  385      Let's imagine that `Occupation` is just another model:
  386
  387      ```js
  388      App.Person = DS.Model.extend({
  389        firstName: DS.attr('string'),
  390        lastName: DS.attr('string'),
  391        occupation: DS.belongsTo('occupation')
  392      });
  393
  394      App.Occupation = DS.Model.extend({
  395        name: DS.attr('string'),
  396        salary: DS.attr('number'),
  397        people: DS.hasMany('person')
  398      });
  399      ```
  400
  401      The JSON needed to avoid extra server calls, should look like this:
  402
  403      ```js
  404      {
  405        "people": [{
  406          "id": 1,
  407          "first_name": "Barack",
  408          "last_name": "Obama",
  409          "occupation_id": 1
  410        }],
  411
  412        "occupations": [{
  413          "id": 1,
  414          "name": "President",
  415          "salary": 100000,
  416          "person_ids": [1]
  417        }]
  418      }
  419      ```
  420
  421      @class ActiveModelSerializer
  422      @namespace DS
  423      @extends DS.RESTSerializer
  424    */
  425    var ActiveModelSerializer = RESTSerializer.extend({
  426      // SERIALIZE
  427
  428      /**
  429        Converts camelCased attributes to underscored when serializing.
  430
  431        @method keyForAttribute
  432        @param {String} attribute
  433        @return String
  434      */
  435      keyForAttribute: function(attr) {
  436        return decamelize(attr);
  437      },
  438
  439      /**
  440        Underscores relationship names and appends "_id" or "_ids" when serializing
  441        relationship keys.
  442
  443        @method keyForRelationship
  444        @param {String} key
  445        @param {String} kind
  446        @return String
  447      */
  448      keyForRelationship: function(rawKey, kind) {
  449        var key = decamelize(rawKey);
  450        if (kind === "belongsTo") {
  451          return key + "_id";
  452        } else if (kind === "hasMany") {
  453          return singularize(key) + "_ids";
  454        } else {
  455          return key;
  456        }
  457      },
  458
  459      /*
  460        Does not serialize hasMany relationships by default.
  461      */
  462      serializeHasMany: Ember.K,
  463
  464      /**
  465        Underscores the JSON root keys when serializing.
  466
  467        @method serializeIntoHash
  468        @param {Object} hash
  469        @param {subclass of DS.Model} type
  470        @param {DS.Model} record
  471        @param {Object} options
  472      */
  473      serializeIntoHash: function(data, type, record, options) {
  474        var root = underscore(decamelize(type.typeKey));
  475        data[root] = this.serialize(record, options);
  476      },
  477
  478      /**
  479        Serializes a polymorphic type as a fully capitalized model name.
  480
  481        @method serializePolymorphicType
  482        @param {DS.Model} record
  483        @param {Object} json
  484        @param {Object} relationship
  485      */
  486      serializePolymorphicType: function(record, json, relationship) {
  487        var key = relationship.key;
  488        var belongsTo = get(record, key);
  489        var jsonKey = underscore(key + "_type");
  490
  491        if (Ember.isNone(belongsTo)) {
  492          json[jsonKey] = null;
  493        } else {
  494          json[jsonKey] = capitalize(camelize(belongsTo.constructor.typeKey));
  495        }
  496      },
  497
  498      // EXTRACT
  499
  500      /**
  501        Add extra step to `DS.RESTSerializer.normalize` so links are normalized.
  502
  503        If your payload looks like:
  504
  505        ```js
  506        {
  507          "post": {
  508            "id": 1,
  509            "title": "Rails is omakase",
  510            "links": { "flagged_comments": "api/comments/flagged" }
  511          }
  512        }
  513        ```
  514
  515        The normalized version would look like this
  516
  517        ```js
  518        {
  519          "post": {
  520            "id": 1,
  521            "title": "Rails is omakase",
  522            "links": { "flaggedComments": "api/comments/flagged" }
  523          }
  524        }
  525        ```
  526
  527        @method normalize
  528        @param {subclass of DS.Model} type
  529        @param {Object} hash
  530        @param {String} prop
  531        @return Object
  532      */
  533
  534      normalize: function(type, hash, prop) {
  535        this.normalizeLinks(hash);
  536
  537        return this._super(type, hash, prop);
  538      },
  539
  540      /**
  541        Convert `snake_cased` links  to `camelCase`
  542
  543        @method normalizeLinks
  544        @param {Object} data
  545      */
  546
  547      normalizeLinks: function(data){
  548        if (data.links) {
  549          var links = data.links;
  550
  551          for (var link in links) {
  552            var camelizedLink = camelize(link);
  553
  554            if (camelizedLink !== link) {
  555              links[camelizedLink] = links[link];
  556              delete links[link];
  557            }
  558          }
  559        }
  560      },
  561
  562      /**
  563        Normalize the polymorphic type from the JSON.
  564
  565        Normalize:
  566        ```js
  567          {
  568            id: "1"
  569            minion: { type: "evil_minion", id: "12"}
  570          }
  571        ```
  572
  573        To:
  574        ```js
  575          {
  576            id: "1"
  577            minion: { type: "evilMinion", id: "12"}
  578          }
  579        ```
  580
  581        @method normalizeRelationships
  582        @private
  583      */
  584      normalizeRelationships: function(type, hash) {
  585
  586        if (this.keyForRelationship) {
  587          type.eachRelationship(function(key, relationship) {
  588            var payloadKey, payload;
  589            if (relationship.options.polymorphic) {
  590              payloadKey = this.keyForAttribute(key);
  591              payload = hash[payloadKey];
  592              if (payload && payload.type) {
  593                payload.type = this.typeForRoot(payload.type);
  594              } else if (payload && relationship.kind === "hasMany") {
  595                var self = this;
  596                forEach(payload, function(single) {
  597                  single.type = self.typeForRoot(single.type);
  598                });
  599              }
  600            } else {
  601              payloadKey = this.keyForRelationship(key, relationship.kind);
  602              if (!hash.hasOwnProperty(payloadKey)) { return; }
  603              payload = hash[payloadKey];
  604            }
  605
  606            hash[key] = payload;
  607
  608            if (key !== payloadKey) {
  609              delete hash[payloadKey];
  610            }
  611          }, this);
  612        }
  613      }
  614    });
  615
  616    __exports__["default"] = ActiveModelSerializer;
  617  });
  618define("ember-data",
  619  ["ember-data/core","ember-data/ext/date","ember-data/system/promise_proxies","ember-data/system/store","ember-data/system/model","ember-data/system/adapter","ember-data/system/debug","ember-data/system/record_arrays","ember-data/system/record_array_manager","ember-data/adapters","ember-data/serializers/json_serializer","ember-data/serializers/rest_serializer","ember-inflector","ember-data/serializers/embedded_records_mixin","activemodel-adapter","ember-data/transforms","ember-data/system/relationships","ember-data/ember-initializer","ember-data/setup-container","ember-data/system/container_proxy","ember-data/system/relationships/relationship","exports"],
  620  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __exports__) {
  621    "use strict";
  622    /**
  623      Ember Data
  624
  625      @module ember-data
  626      @main ember-data
  627    */
  628
  629    // support RSVP 2.x via resolve,  but prefer RSVP 3.x's Promise.cast
  630    Ember.RSVP.Promise.cast = Ember.RSVP.Promise.cast || Ember.RSVP.resolve;
  631
  632    var DS = __dependency1__["default"];
  633
  634    var PromiseArray = __dependency3__.PromiseArray;
  635    var PromiseObject = __dependency3__.PromiseObject;
  636    var Store = __dependency4__.Store;
  637    var Model = __dependency5__.Model;
  638    var Errors = __dependency5__.Errors;
  639    var RootState = __dependency5__.RootState;
  640    var attr = __dependency5__.attr;
  641    var InvalidError = __dependency6__.InvalidError;
  642    var Adapter = __dependency6__.Adapter;
  643    var DebugAdapter = __dependency7__["default"];
  644    var RecordArray = __dependency8__.RecordArray;
  645    var FilteredRecordArray = __dependency8__.FilteredRecordArray;
  646    var AdapterPopulatedRecordArray = __dependency8__.AdapterPopulatedRecordArray;
  647    var ManyArray = __dependency8__.ManyArray;
  648    var RecordArrayManager = __dependency9__["default"];
  649    var RESTAdapter = __dependency10__.RESTAdapter;
  650    var FixtureAdapter = __dependency10__.FixtureAdapter;
  651    var JSONSerializer = __dependency11__["default"];
  652    var RESTSerializer = __dependency12__["default"];
  653    var EmbeddedRecordsMixin = __dependency14__["default"];
  654    var ActiveModelAdapter = __dependency15__.ActiveModelAdapter;
  655    var ActiveModelSerializer = __dependency15__.ActiveModelSerializer;
  656
  657    var Transform = __dependency16__.Transform;
  658    var DateTransform = __dependency16__.DateTransform;
  659    var NumberTransform = __dependency16__.NumberTransform;
  660    var StringTransform = __dependency16__.StringTransform;
  661    var BooleanTransform = __dependency16__.BooleanTransform;
  662
  663    var hasMany = __dependency17__.hasMany;
  664    var belongsTo = __dependency17__.belongsTo;
  665    var setupContainer = __dependency19__["default"];
  666
  667    var ContainerProxy = __dependency20__["default"];
  668    var Relationship = __dependency21__.Relationship;
  669
  670    DS.Store         = Store;
  671    DS.PromiseArray  = PromiseArray;
  672    DS.PromiseObject = PromiseObject;
  673
  674    DS.Model     = Model;
  675    DS.RootState = RootState;
  676    DS.attr      = attr;
  677    DS.Errors    = Errors;
  678
  679    DS.Adapter      = Adapter;
  680    DS.InvalidError = InvalidError;
  681
  682    DS.DebugAdapter = DebugAdapter;
  683
  684    DS.RecordArray                 = RecordArray;
  685    DS.FilteredRecordArray         = FilteredRecordArray;
  686    DS.AdapterPopulatedRecordArray = AdapterPopulatedRecordArray;
  687    DS.ManyArray                   = ManyArray;
  688
  689    DS.RecordArrayManager = RecordArrayManager;
  690
  691    DS.RESTAdapter    = RESTAdapter;
  692    DS.FixtureAdapter = FixtureAdapter;
  693
  694    DS.RESTSerializer = RESTSerializer;
  695    DS.JSONSerializer = JSONSerializer;
  696
  697    DS.Transform       = Transform;
  698    DS.DateTransform   = DateTransform;
  699    DS.StringTransform = StringTransform;
  700    DS.NumberTransform = NumberTransform;
  701    DS.BooleanTransform = BooleanTransform;
  702
  703    DS.ActiveModelAdapter    = ActiveModelAdapter;
  704    DS.ActiveModelSerializer = ActiveModelSerializer;
  705    DS.EmbeddedRecordsMixin  = EmbeddedRecordsMixin;
  706
  707    DS.belongsTo = belongsTo;
  708    DS.hasMany   = hasMany;
  709
  710    DS.Relationship  = Relationship;
  711
  712    DS.ContainerProxy = ContainerProxy;
  713
  714    DS._setupContainer = setupContainer;
  715
  716    Ember.lookup.DS = DS;
  717
  718    __exports__["default"] = DS;
  719  });
  720define("ember-data/adapters",
  721  ["ember-data/adapters/fixture_adapter","ember-data/adapters/rest_adapter","exports"],
  722  function(__dependency1__, __dependency2__, __exports__) {
  723    "use strict";
  724    /**
  725      @module ember-data
  726    */
  727
  728    var FixtureAdapter = __dependency1__["default"];
  729    var RESTAdapter = __dependency2__["default"];
  730
  731    __exports__.RESTAdapter = RESTAdapter;
  732    __exports__.FixtureAdapter = FixtureAdapter;
  733  });
  734define("ember-data/adapters/fixture_adapter",
  735  ["ember-data/system/adapter","exports"],
  736  function(__dependency1__, __exports__) {
  737    "use strict";
  738    /**
  739      @module ember-data
  740    */
  741
  742    var get = Ember.get;
  743    var fmt = Ember.String.fmt;
  744    var indexOf = Ember.EnumerableUtils.indexOf;
  745
  746    var counter = 0;
  747
  748    var Adapter = __dependency1__["default"];
  749
  750    /**
  751      `DS.FixtureAdapter` is an adapter that loads records from memory.
  752      It's primarily used for development and testing. You can also use
  753      `DS.FixtureAdapter` while working on the API but is not ready to
  754      integrate yet. It is a fully functioning adapter. All CRUD methods
  755      are implemented. You can also implement query logic that a remote
  756      system would do. It's possible to develop your entire application
  757      with `DS.FixtureAdapter`.
  758
  759      For information on how to use the `FixtureAdapter` in your
  760      application please see the [FixtureAdapter
  761      guide](/guides/models/the-fixture-adapter/).
  762
  763      @class FixtureAdapter
  764      @namespace DS
  765      @extends DS.Adapter
  766    */
  767    __exports__["default"] = Adapter.extend({
  768      // by default, fixtures are already in normalized form
  769      serializer: null,
  770
  771      /**
  772        If `simulateRemoteResponse` is `true` the `FixtureAdapter` will
  773        wait a number of milliseconds before resolving promises with the
  774        fixture values. The wait time can be configured via the `latency`
  775        property.
  776
  777        @property simulateRemoteResponse
  778        @type {Boolean}
  779        @default true
  780      */
  781      simulateRemoteResponse: true,
  782
  783      /**
  784        By default the `FixtureAdapter` will simulate a wait of the
  785        `latency` milliseconds before resolving promises with the fixture
  786        values. This behavior can be turned off via the
  787        `simulateRemoteResponse` property.
  788
  789        @property latency
  790        @type {Number}
  791        @default 50
  792      */
  793      latency: 50,
  794
  795      /**
  796        Implement this method in order to provide data associated with a type
  797
  798        @method fixturesForType
  799        @param {Subclass of DS.Model} type
  800        @return {Array}
  801      */
  802      fixturesForType: function(type) {
  803        if (type.FIXTURES) {
  804          var fixtures = Ember.A(type.FIXTURES);
  805          return fixtures.map(function(fixture){
  806            var fixtureIdType = typeof fixture.id;
  807            if(fixtureIdType !== "number" && fixtureIdType !== "string"){
  808              throw new Error(fmt('the id property must be defined as a number or string for fixture %@', [fixture]));
  809            }
  810            fixture.id = fixture.id + '';
  811            return fixture;
  812          });
  813        }
  814        return null;
  815      },
  816
  817      /**
  818        Implement this method in order to query fixtures data
  819
  820        @method queryFixtures
  821        @param {Array} fixture
  822        @param {Object} query
  823        @param {Subclass of DS.Model} type
  824        @return {Promise|Array}
  825      */
  826      queryFixtures: function(fixtures, query, type) {
  827        Ember.assert('Not implemented: You must override the DS.FixtureAdapter::queryFixtures method to support querying the fixture store.');
  828      },
  829
  830      /**
  831        @method updateFixtures
  832        @param {Subclass of DS.Model} type
  833        @param {Array} fixture
  834      */
  835      updateFixtures: function(type, fixture) {
  836        if(!type.FIXTURES) {
  837          type.FIXTURES = [];
  838        }
  839
  840        var fixtures = type.FIXTURES;
  841
  842        this.deleteLoadedFixture(type, fixture);
  843
  844        fixtures.push(fixture);
  845      },
  846
  847      /**
  848        Implement this method in order to provide json for CRUD methods
  849
  850        @method mockJSON
  851        @param {Subclass of DS.Model} type
  852        @param {DS.Model} record
  853      */
  854      mockJSON: function(store, type, record) {
  855        return store.serializerFor(type).serialize(record, { includeId: true });
  856      },
  857
  858      /**
  859        @method generateIdForRecord
  860        @param {DS.Store} store
  861        @param {DS.Model} record
  862        @return {String} id
  863      */
  864      generateIdForRecord: function(store) {
  865        return "fixture-" + counter++;
  866      },
  867
  868      /**
  869        @method find
  870        @param {DS.Store} store
  871        @param {subclass of DS.Model} type
  872        @param {String} id
  873        @return {Promise} promise
  874      */
  875      find: function(store, type, id) {
  876        var fixtures = this.fixturesForType(type);
  877        var fixture;
  878
  879        Ember.assert("Unable to find fixtures for model type "+type.toString() +". If you're defining your fixtures using `Model.FIXTURES = ...`, please change it to `Model.reopenClass({ FIXTURES: ... })`.", fixtures);
  880
  881        if (fixtures) {
  882          fixture = Ember.A(fixtures).findBy('id', id);
  883        }
  884
  885        if (fixture) {
  886          return this.simulateRemoteCall(function() {
  887            return fixture;
  888          }, this);
  889        }
  890      },
  891
  892      /**
  893        @method findMany
  894        @param {DS.Store} store
  895        @param {subclass of DS.Model} type
  896        @param {Array} ids
  897        @return {Promise} promise
  898      */
  899      findMany: function(store, type, ids) {
  900        var fixtures = this.fixturesForType(type);
  901
  902        Ember.assert("Unable to find fixtures for model type "+type.toString(), fixtures);
  903
  904        if (fixtures) {
  905          fixtures = fixtures.filter(function(item) {
  906            return indexOf(ids, item.id) !== -1;
  907          });
  908        }
  909
  910        if (fixtures) {
  911          return this.simulateRemoteCall(function() {
  912            return fixtures;
  913          }, this);
  914        }
  915      },
  916
  917      /**
  918        @private
  919        @method findAll
  920        @param {DS.Store} store
  921        @param {subclass of DS.Model} type
  922        @param {String} sinceToken
  923        @return {Promise} promise
  924      */
  925      findAll: function(store, type) {
  926        var fixtures = this.fixturesForType(type);
  927
  928        Ember.assert("Unable to find fixtures for model type "+type.toString(), fixtures);
  929
  930        return this.simulateRemoteCall(function() {
  931          return fixtures;
  932        }, this);
  933      },
  934
  935      /**
  936        @private
  937        @method findQuery
  938        @param {DS.Store} store
  939        @param {subclass of DS.Model} type
  940        @param {Object} query
  941        @param {DS.AdapterPopulatedRecordArray} recordArray
  942        @return {Promise} promise
  943      */
  944      findQuery: function(store, type, query, array) {
  945        var fixtures = this.fixturesForType(type);
  946
  947        Ember.assert("Unable to find fixtures for model type " + type.toString(), fixtures);
  948
  949        fixtures = this.queryFixtures(fixtures, query, type);
  950
  951        if (fixtures) {
  952          return this.simulateRemoteCall(function() {
  953            return fixtures;
  954          }, this);
  955        }
  956      },
  957
  958      /**
  959        @method createRecord
  960        @param {DS.Store} store
  961        @param {subclass of DS.Model} type
  962        @param {DS.Model} record
  963        @return {Promise} promise
  964      */
  965      createRecord: function(store, type, record) {
  966        var fixture = this.mockJSON(store, type, record);
  967
  968        this.updateFixtures(type, fixture);
  969
  970        return this.simulateRemoteCall(function() {
  971          return fixture;
  972        }, this);
  973      },
  974
  975      /**
  976        @method updateRecord
  977        @param {DS.Store} store
  978        @param {subclass of DS.Model} type
  979        @param {DS.Model} record
  980        @return {Promise} promise
  981      */
  982      updateRecord: function(store, type, record) {
  983        var fixture = this.mockJSON(store, type, record);
  984
  985        this.updateFixtures(type, fixture);
  986
  987        return this.simulateRemoteCall(function() {
  988          return fixture;
  989        }, this);
  990      },
  991
  992      /**
  993        @method deleteRecord
  994        @param {DS.Store} store
  995        @param {subclass of DS.Model} type
  996        @param {DS.Model} record
  997        @return {Promise} promise
  998      */
  999      deleteRecord: function(store, type, record) {
 1000        this.deleteLoadedFixture(type, record);
 1001
 1002        return this.simulateRemoteCall(function() {
 1003          // no payload in a deletion
 1004          return null;
 1005        });
 1006      },
 1007
 1008      /*
 1009        @method deleteLoadedFixture
 1010        @private
 1011        @param type
 1012        @param record
 1013      */
 1014      deleteLoadedFixture: function(type, record) {
 1015        var existingFixture = this.findExistingFixture(type, record);
 1016
 1017        if (existingFixture) {
 1018          var index = indexOf(type.FIXTURES, existingFixture);
 1019          type.FIXTURES.splice(index, 1);
 1020          return true;
 1021        }
 1022      },
 1023
 1024      /*
 1025        @method findExistingFixture
 1026        @private
 1027        @param type
 1028        @param record
 1029      */
 1030      findExistingFixture: function(type, record) {
 1031        var fixtures = this.fixturesForType(type);
 1032        var id = get(record, 'id');
 1033
 1034        return this.findFixtureById(fixtures, id);
 1035      },
 1036
 1037      /*
 1038        @method findFixtureById
 1039        @private
 1040        @param fixtures
 1041        @param id
 1042      */
 1043      findFixtureById: function(fixtures, id) {
 1044        return Ember.A(fixtures).find(function(r) {
 1045          if (''+get(r, 'id') === ''+id) {
 1046            return true;
 1047          } else {
 1048            return false;
 1049          }
 1050        });
 1051      },
 1052
 1053      /*
 1054        @method simulateRemoteCall
 1055        @private
 1056        @param callback
 1057        @param context
 1058      */
 1059      simulateRemoteCall: function(callback, context) {
 1060        var adapter = this;
 1061
 1062        return new Ember.RSVP.Promise(function(resolve) {
 1063          var value = Ember.copy(callback.call(context), true);
 1064          if (get(adapter, 'simulateRemoteResponse')) {
 1065            // Schedule with setTimeout
 1066            Ember.run.later(function() {
 1067              resolve(value);
 1068            }, get(adapter, 'latency'));
 1069          } else {
 1070            // Asynchronous, but at the of the runloop with zero latency
 1071            Ember.run.schedule('actions', null, function() {
 1072              resolve(value);
 1073            });
 1074          }
 1075        }, "DS: FixtureAdapter#simulateRemoteCall");
 1076      }
 1077    });
 1078  });
 1079define("ember-data/adapters/rest_adapter",
 1080  ["ember-data/system/adapter","ember-data/system/map","exports"],
 1081  function(__dependency1__, __dependency2__, __exports__) {
 1082    "use strict";
 1083    /**
 1084      @module ember-data
 1085    */
 1086
 1087    var Adapter = __dependency1__.Adapter;
 1088    var InvalidError = __dependency1__.InvalidError;
 1089    var MapWithDefault = __dependency2__.MapWithDefault;
 1090    var get = Ember.get;
 1091    var forEach = Ember.ArrayPolyfills.forEach;
 1092
 1093    /**
 1094      The REST adapter allows your store to communicate with an HTTP server by
 1095      transmitting JSON via XHR. Most Ember.js apps that consume a JSON API
 1096      should use the REST adapter.
 1097
 1098      This adapter is designed around the idea that the JSON exchanged with
 1099      the server should be conventional.
 1100
 1101      ## JSON Structure
 1102
 1103      The REST adapter expects the JSON returned from your server to follow
 1104      these conventions.
 1105
 1106      ### Object Root
 1107
 1108      The JSON payload should be an object that contains the record inside a
 1109      root property. For example, in response to a `GET` request for
 1110      `/posts/1`, the JSON should look like this:
 1111
 1112      ```js
 1113      {
 1114        "post": {
 1115          "id": 1,
 1116          "title": "I'm Running to Reform the W3C's Tag",
 1117          "author": "Yehuda Katz"
 1118        }
 1119      }
 1120      ```
 1121
 1122      Similarly, in response to a `GET` request for `/posts`, the JSON should
 1123      look like this:
 1124
 1125      ```js
 1126      {
 1127        "posts": [
 1128          {
 1129            "id": 1,
 1130            "title": "I'm Running to Reform the W3C's Tag",
 1131            "author": "Yehuda Katz"
 1132          },
 1133          {
 1134            "id": 2,
 1135            "title": "Rails is omakase",
 1136            "author": "D2H"
 1137          }
 1138        ]
 1139      }
 1140      ```
 1141
 1142      ### Conventional Names
 1143
 1144      Attribute names in your JSON payload should be the camelCased versions of
 1145      the attributes in your Ember.js models.
 1146
 1147      For example, if you have a `Person` model:
 1148
 1149      ```js
 1150      App.Person = DS.Model.extend({
 1151        firstName: DS.attr('string'),
 1152        lastName: DS.attr('string'),
 1153        occupation: DS.attr('string')
 1154      });
 1155      ```
 1156
 1157      The JSON returned should look like this:
 1158
 1159      ```js
 1160      {
 1161        "person": {
 1162          "id": 5,
 1163          "firstName": "Barack",
 1164          "lastName": "Obama",
 1165          "occupation": "President"
 1166        }
 1167      }
 1168      ```
 1169
 1170      ## Customization
 1171
 1172      ### Endpoint path customization
 1173
 1174      Endpoint paths can be prefixed with a `namespace` by setting the namespace
 1175      property on the adapter:
 1176
 1177      ```js
 1178      DS.RESTAdapter.reopen({
 1179        namespace: 'api/1'
 1180      });
 1181      ```
 1182      Requests for `App.Person` would now target `/api/1/people/1`.
 1183
 1184      ### Host customization
 1185
 1186      An adapter can target other hosts by setting the `host` property.
 1187
 1188      ```js
 1189      DS.RESTAdapter.reopen({
 1190        host: 'https://api.example.com'
 1191      });
 1192      ```
 1193
 1194      ### Headers customization
 1195
 1196      Some APIs require HTTP headers, e.g. to provide an API key. Arbitrary
 1197      headers can be set as key/value pairs on the `RESTAdapter`'s `headers`
 1198      object and Ember Data will send them along with each ajax request.
 1199
 1200
 1201      ```js
 1202      App.ApplicationAdapter = DS.RESTAdapter.extend({
 1203        headers: {
 1204          "API_KEY": "secret key",
 1205          "ANOTHER_HEADER": "Some header value"
 1206        }
 1207      });
 1208      ```
 1209
 1210      `headers` can also be used as a computed property to support dynamic
 1211      headers. In the example below, the `session` object has been
 1212      injected into an adapter by Ember's container.
 1213
 1214      ```js
 1215      App.ApplicationAdapter = DS.RESTAdapter.extend({
 1216        headers: function() {
 1217          return {
 1218            "API_KEY": this.get("session.authToken"),
 1219            "ANOTHER_HEADER": "Some header value"
 1220          };
 1221        }.property("session.authToken")
 1222      });
 1223      ```
 1224
 1225      In some cases, your dynamic headers may require data from some
 1226      object outside of Ember's observer system (for example
 1227      `document.cookie`). You can use the
 1228      [volatile](/api/classes/Ember.ComputedProperty.html#method_volatile)
 1229      function to set the property into a non-cached mode causing the headers to
 1230      be recomputed with every request.
 1231
 1232      ```js
 1233      App.ApplicationAdapter = DS.RESTAdapter.extend({
 1234        headers: function() {
 1235          return {
 1236            "API_KEY": Ember.get(document.cookie.match(/apiKey\=([^;]*)/), "1"),
 1237            "ANOTHER_HEADER": "Some header value"
 1238          };
 1239        }.property().volatile()
 1240      });
 1241      ```
 1242
 1243      @class RESTAdapter
 1244      @constructor
 1245      @namespace DS
 1246      @extends DS.Adapter
 1247    */
 1248    __exports__["default"] = Adapter.extend({
 1249      defaultSerializer: '-rest',
 1250
 1251      /**
 1252        By default the RESTAdapter will send each find request coming from a `store.find`
 1253        or from accessing a relationship separately to the server. If your server supports passing
 1254        ids as a query string, you can set coalesceFindRequests to true to coalesce all find requests
 1255        within a single runloop.
 1256
 1257        For example, if you have an initial payload of
 1258        ```javascript
 1259        post: {
 1260          id:1,
 1261          comments: [1,2]
 1262        }
 1263        ```
 1264
 1265        By default calling `post.get('comments')` will trigger the following requests(assuming the
 1266        comments haven't been loaded before):
 1267
 1268        ```
 1269        GET /comments/1
 1270        GET /comments/2
 1271        ```
 1272
 1273        If you set coalesceFindRequests to `true` it will instead trigger the following request:
 1274
 1275        ```
 1276        GET /comments?ids[]=1&ids[]=2
 1277        ```
 1278
 1279        Setting coalesceFindRequests to `true` also works for `store.find` requests and `belongsTo`
 1280        relationships accessed within the same runloop. If you set `coalesceFindRequests: true`
 1281
 1282        ```javascript
 1283        store.find('comment', 1);
 1284        store.find('comment', 2);
 1285        ```
 1286
 1287        will also send a request to: `GET /comments?ids[]=1&ids[]=2`
 1288
 1289        Note: Requests coalescing rely on URL building strategy. So if you override `buildUrl` in your app
 1290        `groupRecordsForFindMany` more likely should be overriden as well in order for coalescing to work.
 1291
 1292        @property coalesceFindRequests
 1293        @type {boolean}
 1294      */
 1295      coalesceFindRequests: false,
 1296
 1297      /**
 1298        Endpoint paths can be prefixed with a `namespace` by setting the namespace
 1299        property on the adapter:
 1300
 1301        ```javascript
 1302        DS.RESTAdapter.reopen({
 1303          namespace: 'api/1'
 1304        });
 1305        ```
 1306
 1307        Requests for `App.Post` would now target `/api/1/post/`.
 1308
 1309        @property namespace
 1310        @type {String}
 1311      */
 1312
 1313      /**
 1314        An adapter can target other hosts by setting the `host` property.
 1315
 1316        ```javascript
 1317        DS.RESTAdapter.reopen({
 1318          host: 'https://api.example.com'
 1319        });
 1320        ```
 1321
 1322        Requests for `App.Post` would now target `https://api.example.com/post/`.
 1323
 1324        @property host
 1325        @type {String}
 1326      */
 1327
 1328      /**
 1329        Some APIs require HTTP headers, e.g. to provide an API
 1330        key. Arbitrary headers can be set as key/value pairs on the
 1331        `RESTAdapter`'s `headers` object and Ember Data will send them
 1332        along with each ajax request. For dynamic headers see [headers
 1333        customization](/api/data/classes/DS.RESTAdapter.html#toc_headers-customization).
 1334
 1335        ```javascript
 1336        App.ApplicationAdapter = DS.RESTAdapter.extend({
 1337          headers: {
 1338            "API_KEY": "secret key",
 1339            "ANOTHER_HEADER": "Some header value"
 1340          }
 1341        });
 1342        ```
 1343
 1344        @property headers
 1345        @type {Object}
 1346      */
 1347
 1348      /**
 1349        Called by the store in order to fetch the JSON for a given
 1350        type and ID.
 1351
 1352        The `find` method makes an Ajax request to a URL computed by `buildURL`, and returns a
 1353        promise for the resulting payload.
 1354
 1355        This method performs an HTTP `GET` request with the id provided as part of the query string.
 1356
 1357        @method find
 1358        @param {DS.Store} store
 1359        @param {subclass of DS.Model} type
 1360        @param {String} id
 1361        @param {DS.Model} record
 1362        @return {Promise} promise
 1363      */
 1364      find: function(store, type, id, record) {
 1365        return this.ajax(this.buildURL(type.typeKey, id, record), 'GET');
 1366      },
 1367
 1368      /**
 1369        Called by the store in order to fetch a JSON array for all
 1370        of the records for a given type.
 1371
 1372        The `findAll` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
 1373        promise for the resulting payload.
 1374
 1375        @private
 1376        @method findAll
 1377        @param {DS.Store} store
 1378        @param {subclass of DS.Model} type
 1379        @param {String} sinceToken
 1380        @return {Promise} promise
 1381      */
 1382      findAll: function(store, type, sinceToken) {
 1383        var query;
 1384
 1385        if (sinceToken) {
 1386          query = { since: sinceToken };
 1387        }
 1388
 1389        return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query });
 1390      },
 1391
 1392      /**
 1393        Called by the store in order to fetch a JSON array for
 1394        the records that match a particular query.
 1395
 1396        The `findQuery` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
 1397        promise for the resulting payload.
 1398
 1399        The `query` argument is a simple JavaScript object that will be passed directly
 1400        to the server as parameters.
 1401
 1402        @private
 1403        @method findQuery
 1404        @param {DS.Store} store
 1405        @param {subclass of DS.Model} type
 1406        @param {Object} query
 1407        @return {Promise} promise
 1408      */
 1409      findQuery: function(store, type, query) {
 1410        return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query });
 1411      },
 1412
 1413      /**
 1414        Called by the store in order to fetch several records together if `coalesceFindRequests` is true
 1415
 1416        For example, if the original payload looks like:
 1417
 1418        ```js
 1419        {
 1420          "id": 1,
 1421          "title": "Rails is omakase",
 1422          "comments": [ 1, 2, 3 ]
 1423        }
 1424        ```
 1425
 1426        The IDs will be passed as a URL-encoded Array of IDs, in this form:
 1427
 1428        ```
 1429        ids[]=1&ids[]=2&ids[]=3
 1430        ```
 1431
 1432        Many servers, such as Rails and PHP, will automatically convert this URL-encoded array
 1433        into an Array for you on the server-side. If you want to encode the
 1434        IDs, differently, just override this (one-line) method.
 1435
 1436        The `findMany` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
 1437        promise for the resulting payload.
 1438
 1439        @method findMany
 1440        @param {DS.Store} store
 1441        @param {subclass of DS.Model} type
 1442        @param {Array} ids
 1443        @param {Array} records
 1444        @return {Promise} promise
 1445      */
 1446      findMany: function(store, type, ids, records) {
 1447        return this.ajax(this.buildURL(type.typeKey, ids, records), 'GET', { data: { ids: ids } });
 1448      },
 1449
 1450      /**
 1451        Called by the store in order to fetch a JSON array for
 1452        the unloaded records in a has-many relationship that were originally
 1453        specified as a URL (inside of `links`).
 1454
 1455        For example, if your original payload looks like this:
 1456
 1457        ```js
 1458        {
 1459          "post": {
 1460            "id": 1,
 1461            "title": "Rails is omakase",
 1462            "links": { "comments": "/posts/1/comments" }
 1463          }
 1464        }
 1465        ```
 1466
 1467        This method will be called with the parent record and `/posts/1/comments`.
 1468
 1469        The `findHasMany` method will make an Ajax (HTTP GET) request to the originally specified URL.
 1470        If the URL is host-relative (starting with a single slash), the
 1471        request will use the host specified on the adapter (if any).
 1472
 1473        @method findHasMany
 1474        @param {DS.Store} store
 1475        @param {DS.Model} record
 1476        @param {String} url
 1477        @return {Promise} promise
 1478      */
 1479      findHasMany: function(store, record, url, relationship) {
 1480        var host = get(this, 'host');
 1481        var id   = get(record, 'id');
 1482        var type = record.constructor.typeKey;
 1483
 1484        if (host && url.charAt(0) === '/' && url.charAt(1) !== '/') {
 1485          url = host + url;
 1486        }
 1487
 1488        return this.ajax(this.urlPrefix(url, this.buildURL(type, id)), 'GET');
 1489      },
 1490
 1491      /**
 1492        Called by the store in order to fetch a JSON array for
 1493        the unloaded records in a belongs-to relationship that were originally
 1494        specified as a URL (inside of `links`).
 1495
 1496        For example, if your original payload looks like this:
 1497
 1498        ```js
 1499        {
 1500          "person": {
 1501            "id": 1,
 1502            "name": "Tom Dale",
 1503            "links": { "group": "/people/1/group" }
 1504          }
 1505        }
 1506        ```
 1507
 1508        This method will be called with the parent record and `/people/1/group`.
 1509
 1510        The `findBelongsTo` method will make an Ajax (HTTP GET) request to the originally specified URL.
 1511
 1512        @method findBelongsTo
 1513        @param {DS.Store} store
 1514        @param {DS.Model} record
 1515        @param {String} url
 1516        @return {Promise} promise
 1517      */
 1518      findBelongsTo: function(store, record, url, relationship) {
 1519        var id   = get(record, 'id');
 1520        var type = record.constructor.typeKey;
 1521
 1522        return this.ajax(this.urlPrefix(url, this.buildURL(type, id)), 'GET');
 1523      },
 1524
 1525      /**
 1526        Called by the store when a newly created record is
 1527        saved via the `save` method on a model record instance.
 1528
 1529        The `createRecord` method serializes the record and makes an Ajax (HTTP POST) request
 1530        to a URL computed by `buildURL`.
 1531
 1532        See `serialize` for information on how to customize the serialized form
 1533        of a record.
 1534
 1535        @method createRecord
 1536        @param {DS.Store} store
 1537        @param {subclass of DS.Model} type
 1538        @param {DS.Model} record
 1539        @return {Promise} promise
 1540      */
 1541      createRecord: function(store, type, record) {
 1542        var data = {};
 1543        var serializer = store.serializerFor(type.typeKey);
 1544
 1545        serializer.serializeIntoHash(data, type, record, { includeId: true });
 1546
 1547        return this.ajax(this.buildURL(type.typeKey, null, record), "POST", { data: data });
 1548      },
 1549
 1550      /**
 1551        Called by the store when an existing record is saved
 1552        via the `save` method on a model record instance.
 1553
 1554        The `updateRecord` method serializes the record and makes an Ajax (HTTP PUT) request
 1555        to a URL computed by `buildURL`.
 1556
 1557        See `serialize` for information on how to customize the serialized form
 1558        of a record.
 1559
 1560        @method updateRecord
 1561        @param {DS.Store} store
 1562        @param {subclass of DS.Model} type
 1563        @param {DS.Model} record
 1564        @return {Promise} promise
 1565      */
 1566      updateRecord: function(store, type, record) {
 1567        var data = {};
 1568        var serializer = store.serializerFor(type.typeKey);
 1569
 1570        serializer.serializeIntoHash(data, type, record);
 1571
 1572        var id = get(record, 'id');
 1573
 1574        return this.ajax(this.buildURL(type.typeKey, id, record), "PUT", { data: data });
 1575      },
 1576
 1577      /**
 1578        Called by the store when a record is deleted.
 1579
 1580        The `deleteRecord` method  makes an Ajax (HTTP DELETE) request to a URL computed by `buildURL`.
 1581
 1582        @method deleteRecord
 1583        @param {DS.Store} store
 1584        @param {subclass of DS.Model} type
 1585        @param {DS.Model} record
 1586        @return {Promise} promise
 1587      */
 1588      deleteRecord: function(store, type, record) {
 1589        var id = get(record, 'id');
 1590
 1591        return this.ajax(this.buildURL(type.typeKey, id, record), "DELETE");
 1592      },
 1593
 1594      /**
 1595        Builds a URL for a given type and optional ID.
 1596
 1597        By default, it pluralizes the type's name (for example, 'post'
 1598        becomes 'posts' and 'person' becomes 'people'). To override the
 1599        pluralization see [pathForType](#method_pathForType).
 1600
 1601        If an ID is specified, it adds the ID to the path generated
 1602        for the type, separated by a `/`.
 1603
 1604        @method buildURL
 1605        @param {String} type
 1606        @param {String} id
 1607        @param {DS.Model} record
 1608        @return {String} url
 1609      */
 1610      buildURL: function(type, id, record) {
 1611        var url = [],
 1612            host = get(this, 'host'),
 1613            prefix = this.urlPrefix();
 1614
 1615        if (type) { url.push(this.pathForType(type)); }
 1616
 1617        //We might get passed in an array of ids from findMany
 1618        //in which case we don't want to modify the url, as the
 1619        //ids will be passed in through a query param
 1620        if (id && !Ember.isArray(id)) { url.push(encodeURIComponent(id)); }
 1621
 1622        if (prefix) { url.unshift(prefix); }
 1623
 1624        url = url.join('/');
 1625        if (!host && url) { url = '/' + url; }
 1626
 1627        return url;
 1628      },
 1629
 1630      /**
 1631        @method urlPrefix
 1632        @private
 1633        @param {String} path
 1634        @param {String} parentUrl
 1635        @return {String} urlPrefix
 1636      */
 1637      urlPrefix: function(path, parentURL) {
 1638        var host = get(this, 'host');
 1639        var namespace = get(this, 'namespace');
 1640        var url = [];
 1641
 1642        if (path) {
 1643          // Absolute path
 1644          if (path.charAt(0) === '/') {
 1645            if (host) {
 1646              path = path.slice(1);
 1647              url.push(host);
 1648            }
 1649          // Relative path
 1650          } else if (!/^http(s)?:\/\//.test(path)) {
 1651            url.push(parentURL);
 1652          }
 1653        } else {
 1654          if (host) { url.push(host); }
 1655          if (namespace) { url.push(namespace); }
 1656        }
 1657
 1658        if (path) {
 1659          url.push(path);
 1660        }
 1661
 1662        return url.join('/');
 1663      },
 1664
 1665      _stripIDFromURL: function(store, record) {
 1666        var type = store.modelFor(record);
 1667        var url = this.buildURL(type.typeKey, record.get('id'), record);
 1668
 1669        var expandedURL = url.split('/');
 1670        //Case when the url is of the format ...something/:id
 1671        var lastSegment = expandedURL[ expandedURL.length - 1 ];
 1672        var id = record.get('id');
 1673        if (lastSegment === id) {
 1674          expandedURL[expandedURL.length - 1] = "";
 1675        } else if(endsWith(lastSegment, '?id=' + id)) {
 1676          //Case when the url is of the format ...something?id=:id
 1677          expandedURL[expandedURL.length - 1] = lastSegment.substring(0, lastSegment.length - id.length - 1);
 1678        }
 1679
 1680        return expandedURL.join('/');
 1681      },
 1682
 1683      /**
 1684        Organize records into groups, each of which is to be passed to separate
 1685        calls to `findMany`.
 1686
 1687        This implementation groups together records that have the same base URL but
 1688        differing ids. For example `/comments/1` and `/comments/2` will be grouped together
 1689        because we know findMany can coalesce them together as `/comments?ids[]=1&ids[]=2`
 1690
 1691        It also supports urls where ids are passed as a query param, such as `/comments?id=1`
 1692        but not those where there is more than 1 query param such as `/comments?id=2&name=David`
 1693        Currently only the query param of `id` is supported. If you need to support others, please
 1694        override this or the `_stripIDFromURL` method.
 1695
 1696        It does not group records that have differing base urls, such as for example: `/posts/1/comments/2`
 1697        and `/posts/2/comments/3`
 1698
 1699        @method groupRecordsForFindMany
 1700        @param {Array} records
 1701        @return {Array}  an array of arrays of records, each of which is to be
 1702                          loaded separately by `findMany`.
 1703      */
 1704      groupRecordsForFindMany: function (store, records) {
 1705        var groups = MapWithDefault.create({defaultValue: function(){return [];}});
 1706        var adapter = this;
 1707
 1708        forEach.call(records, function(record){
 1709          var baseUrl = adapter._stripIDFromURL(store, record);
 1710          groups.get(baseUrl).push(record);
 1711        });
 1712
 1713        function splitGroupToFitInUrl(group, maxUrlLength) {
 1714          var baseUrl = adapter._stripIDFromURL(store, group[0]);
 1715          var idsSize = 0;
 1716          var splitGroups = [[]];
 1717
 1718          forEach.call(group, function(record) {
 1719            var additionalLength = '&ids[]='.length + record.get('id.length');
 1720            if (baseUrl.length + idsSize + additionalLength >= maxUrlLength) {
 1721              idsSize = 0;
 1722              splitGroups.push([]);
 1723            }
 1724
 1725            idsSize += additionalLength;
 1726
 1727            var lastGroupIndex = splitGroups.length - 1;
 1728            splitGroups[lastGroupIndex].push(record);
 1729          });
 1730
 1731          return splitGroups;
 1732        }
 1733
 1734        var groupsArray = [];
 1735        groups.forEach(function(group, key){
 1736          // http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
 1737          var maxUrlLength = 2048;
 1738          var splitGroups = splitGroupToFitInUrl(group, maxUrlLength);
 1739
 1740          forEach.call(splitGroups, function(splitGroup) {
 1741            groupsArray.push(splitGroup);
 1742          });
 1743        });
 1744
 1745        return groupsArray;
 1746      },
 1747
 1748      /**
 1749        Determines the pathname for a given type.
 1750
 1751        By default, it pluralizes the type's name (for example,
 1752        'post' becomes 'posts' and 'person' becomes 'people').
 1753
 1754        ### Pathname customization
 1755
 1756        For example if you have an object LineItem with an
 1757        endpoint of "/line_items/".
 1758
 1759        ```js
 1760        App.ApplicationAdapter = DS.RESTAdapter.extend({
 1761          pathForType: function(type) {
 1762            var decamelized = Ember.String.decamelize(type);
 1763            return Ember.String.pluralize(decamelized);
 1764          }
 1765        });
 1766        ```
 1767
 1768        @method pathForType
 1769        @param {String} type
 1770        @return {String} path
 1771      **/
 1772      pathForType: function(type) {
 1773        var camelized = Ember.String.camelize(type);
 1774        return Ember.String.pluralize(camelized);
 1775      },
 1776
 1777      /**
 1778        Takes an ajax response, and returns a relevant error.
 1779
 1780        Returning a `DS.InvalidError` from this method will cause the
 1781        record to transition into the `invalid` state and make the
 1782        `errors` object available on the record.
 1783
 1784        ```javascript
 1785        App.ApplicationAdapter = DS.RESTAdapter.extend({
 1786          ajaxError: function(jqXHR) {
 1787            var error = this._super(jqXHR);
 1788
 1789            if (jqXHR && jqXHR.status === 422) {
 1790              var jsonErrors = Ember.$.parseJSON(jqXHR.responseText)["errors"];
 1791
 1792              return new DS.InvalidError(jsonErrors);
 1793            } else {
 1794              return error;
 1795            }
 1796          }
 1797        });
 1798        ```
 1799
 1800        Note: As a correctness optimization, the default implementation of
 1801        the `ajaxError` method strips out the `then` method from jquery's
 1802        ajax response (jqXHR). This is important because the jqXHR's
 1803        `then` method fulfills the promise with itself resulting in a
 1804        circular "thenable" chain which may cause problems for some
 1805        promise libraries.
 1806
 1807        @method ajaxError
 1808        @param  {Object} jqXHR
 1809        @param  {Object} responseText
 1810        @return {Object} jqXHR
 1811      */
 1812      ajaxError: function(jqXHR, responseText) {
 1813        if (jqXHR && typeof jqXHR === 'object') {
 1814          jqXHR.then = null;
 1815        }
 1816
 1817        return jqXHR;
 1818      },
 1819
 1820      /**
 1821        Takes an ajax response, and returns the json payload.
 1822
 1823        By default this hook just returns the jsonPayload passed to it.
 1824        You might want to override it in two cases:
 1825
 1826        1. Your API might return useful results in the request headers.
 1827        If you need to access these, you can override this hook to copy them
 1828        from jqXHR to the payload object so they can be processed in you serializer.
 1829
 1830
 1831        2. Your API might return errors as successful responses with status code
 1832        200 and an Errors text or object. You can return a DS.InvalidError from
 1833        this hook and it will automatically reject the promise and put your record
 1834        into the invald state.
 1835
 1836        @method ajaxError
 1837        @param  {Object} jqXHR
 1838        @param  {Object} jsonPayload
 1839        @return {Object} jqXHR
 1840      */
 1841
 1842      ajaxSuccess: function(jqXHR, jsonPayload) {
 1843        return jsonPayload;
 1844      },
 1845
 1846      /**
 1847        Takes a URL, an HTTP method and a hash of data, and makes an
 1848        HTTP request.
 1849
 1850        When the server responds with a payload, Ember Data will call into `extractSingle`
 1851        or `extractArray` (depending on whether the original query was for one record or
 1852        many records).
 1853
 1854        By default, `ajax` method has the following behavior:
 1855
 1856        * It sets the response `dataType` to `"json"`
 1857        * If the HTTP method is not `"GET"`, it sets the `Content-Type` to be
 1858          `application/json; charset=utf-8`
 1859        * If the HTTP method is not `"GET"`, it stringifies the data passed in. The
 1860          data is the serialized record in the case of a save.
 1861        * Registers success and failure handlers.
 1862
 1863        @method ajax
 1864        @private
 1865        @param {String} url
 1866        @param {String} type The request type GET, POST, PUT, DELETE etc.
 1867        @param {Object} hash
 1868        @return {Promise} promise
 1869      */
 1870      ajax: function(url, type, options) {
 1871        var adapter = this;
 1872
 1873        return new Ember.RSVP.Promise(function(resolve, reject) {
 1874          var hash = adapter.ajaxOptions(url, type, options);
 1875
 1876          hash.success = function(json, textStatus, jqXHR) {
 1877            json = adapter.ajaxSuccess(jqXHR, json);
 1878            if (json instanceof InvalidError) {
 1879              Ember.run(null, reject, json);
 1880            } else {
 1881              Ember.run(null, resolve, json);
 1882            }
 1883          };
 1884
 1885          hash.error = function(jqXHR, textStatus, errorThrown) {
 1886            Ember.run(null, reject, adapter.ajaxError(jqXHR, jqXHR.responseText));
 1887          };
 1888
 1889          Ember.$.ajax(hash);
 1890        }, "DS: RESTAdapter#ajax " + type + " to " + url);
 1891      },
 1892
 1893      /**
 1894        @method ajaxOptions
 1895        @private
 1896        @param {String} url
 1897        @param {String} type The request type GET, POST, PUT, DELETE etc.
 1898        @param {Object} hash
 1899        @return {Object} hash
 1900      */
 1901      ajaxOptions: function(url, type, options) {
 1902        var hash = options || {};
 1903        hash.url = url;
 1904        hash.type = type;
 1905        hash.dataType = 'json';
 1906        hash.context = this;
 1907
 1908        if (hash.data && type !== 'GET') {
 1909          hash.contentType = 'application/json; charset=utf-8';
 1910          hash.data = JSON.stringify(hash.data);
 1911        }
 1912
 1913        var headers = get(this, 'headers');
 1914        if (headers !== undefined) {
 1915          hash.beforeSend = function (xhr) {
 1916            forEach.call(Ember.keys(headers), function(key) {
 1917              xhr.setRequestHeader(key, headers[key]);
 1918            });
 1919          };
 1920        }
 1921
 1922        return hash;
 1923      }
 1924    });
 1925
 1926    //From http://stackoverflow.com/questions/280634/endswith-in-javascript
 1927    function endsWith(string, suffix){
 1928      if (typeof String.prototype.endsWith !== 'function') {
 1929        return string.indexOf(suffix, string.length - suffix.length) !== -1;
 1930      } else {
 1931        return string.endsWith(suffix);
 1932      }
 1933    }
 1934  });
 1935define("ember-data/core",
 1936  ["exports"],
 1937  function(__exports__) {
 1938    "use strict";
 1939    /**
 1940      @module ember-data
 1941    */
 1942
 1943    /**
 1944      All Ember Data methods and functions are defined inside of this namespace.
 1945
 1946      @class DS
 1947      @static
 1948    */
 1949    var DS;
 1950    if ('undefined' === typeof DS) {
 1951      /**
 1952        @property VERSION
 1953        @type String
 1954        @default '1.0.0-beta.11'
 1955        @static
 1956      */
 1957      DS = Ember.Namespace.create({
 1958        VERSION: '1.0.0-beta.11'
 1959      });
 1960
 1961      if (Ember.libraries) {
 1962        Ember.libraries.registerCoreLibrary('Ember Data', DS.VERSION);
 1963      }
 1964    }
 1965
 1966    __exports__["default"] = DS;
 1967  });
 1968define("ember-data/ember-initializer",
 1969  ["ember-data/setup-container"],
 1970  function(__dependency1__) {
 1971    "use strict";
 1972    var setupContainer = __dependency1__["default"];
 1973
 1974    var K = Ember.K;
 1975
 1976    /**
 1977      @module ember-data
 1978    */
 1979
 1980    /*
 1981
 1982      This code initializes Ember-Data onto an Ember application.
 1983
 1984      If an Ember.js developer defines a subclass of DS.Store on their application,
 1985      as `App.ApplicationStore` (or via a module system that resolves to `store:application`)
 1986      this code will automatically instantiate it and make it available on the
 1987      router.
 1988
 1989      Additionally, after an application's controllers have been injected, they will
 1990      each have the store made available to them.
 1991
 1992      For example, imagine an Ember.js application with the following classes:
 1993
 1994      App.ApplicationStore = DS.Store.extend({
 1995        adapter: 'custom'
 1996      });
 1997
 1998      App.PostsController = Ember.ArrayController.extend({
 1999        // ...
 2000      });
 2001
 2002      When the application is initialized, `App.ApplicationStore` will automatically be
 2003      instantiated, and the instance of `App.PostsController` will have its `store`
 2004      property set to that instance.
 2005
 2006      Note that this code will only be run if the `ember-application` package is
 2007      loaded. If Ember Data is being used in an environment other than a
 2008      typical application (e.g., node.js where only `ember-runtime` is available),
 2009      this code will be ignored.
 2010    */
 2011
 2012    Ember.onLoad('Ember.Application', function(Application) {
 2013
 2014      Application.initializer({
 2015        name:       "ember-data",
 2016        initialize: setupContainer
 2017      });
 2018
 2019      // Deprecated initializers to satisfy old code that depended on them
 2020
 2021      Application.initializer({
 2022        name:       "store",
 2023        after:      "ember-data",
 2024        initialize: K
 2025      });
 2026
 2027      Application.initializer({
 2028        name:       "activeModelAdapter",
 2029        before:     "store",
 2030        initialize: K
 2031      });
 2032
 2033      Application.initializer({
 2034        name:       "transforms",
 2035        before:     "store",
 2036        initialize: K
 2037      });
 2038
 2039      Application.initializer({
 2040        name:       "data-adapter",
 2041        before:     "store",
 2042        initialize: K
 2043      });
 2044
 2045      Application.initializer({
 2046        name:       "injectStore",
 2047        before:     "store",
 2048        initialize: K
 2049      });
 2050    });
 2051  });
 2052define("ember-data/ext/date",
 2053  [],
 2054  function() {
 2055    "use strict";
 2056    /**
 2057      @module ember-data
 2058    */
 2059
 2060    /**
 2061      Date.parse with progressive enhancement for ISO 8601 <https://github.com/csnover/js-iso8601>
 2062
 2063      © 2011 Colin Snover <http://zetafleet.com>
 2064
 2065      Released under MIT license.
 2066
 2067      @class Date
 2068      @namespace Ember
 2069      @static
 2070    */
 2071    Ember.Date = Ember.Date || {};
 2072
 2073    var origParse = Date.parse, numericKeys = [ 1, 4, 5, 6, 7, 10, 11 ];
 2074
 2075    /**
 2076      @method parse
 2077      @param {Date} date
 2078      @return {Number} timestamp
 2079    */
 2080    Ember.Date.parse = function (date) {
 2081        var timestamp, struct, minutesOffset = 0;
 2082
 2083        // ES5 §15.9.4.2 states that the string should attempt to be parsed as a Date Time String Format string
 2084        // before falling back to any implementation-specific date parsing, so that’s what we do, even if native
 2085        // implementations could be faster
 2086        //              1 YYYY                2 MM       3 DD           4 HH    5 mm       6 ss        7 msec        8 Z 9 ±    10 tzHH    11 tzmm
 2087        if ((struct = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(date))) {
 2088            // avoid NaN timestamps caused by “undefined” values being passed to Date.UTC
 2089            for (var i = 0, k; (k = numericKeys[i]); ++i) {
 2090                struct[k] = +struct[k] || 0;
 2091            }
 2092
 2093            // allow undefined days and months
 2094            struct[2] = (+struct[2] || 1) - 1;
 2095            struct[3] = +struct[3] || 1;
 2096
 2097            if (struct[8] !== 'Z' && struct[9] !== undefined) {
 2098                minutesOffset = struct[10] * 60 + struct[11];
 2099
 2100                if (struct[9] === '+') {
 2101                    minutesOffset = 0 - minutesOffset;
 2102                }
 2103            }
 2104
 2105            timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
 2106        }
 2107        else {
 2108            timestamp = origParse ? origParse(date) : NaN;
 2109        }
 2110
 2111        return timestamp;
 2112    };
 2113
 2114    if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Date) {
 2115      Date.parse = Ember.Date.parse;
 2116    }
 2117  });
 2118define("ember-data/initializers/data_adapter",
 2119  ["ember-data/system/debug/debug_adapter","exports"],
 2120  function(__dependency1__, __exports__) {
 2121    "use strict";
 2122    var DebugAdapter = __dependency1__["default"];
 2123
 2124    /**
 2125      Configures a container with injections on Ember applications
 2126      for the Ember-Data store. Accepts an optional namespace argument.
 2127
 2128      @method initializeStoreInjections
 2129      @param {Ember.Container} container
 2130    */
 2131    __exports__["default"] = function initializeDebugAdapter(container){
 2132      container.register('data-adapter:main', DebugAdapter);
 2133    };
 2134  });
 2135define("ember-data/initializers/store",
 2136  ["ember-data/serializers","ember-data/adapters","ember-data/system/container_proxy","ember-data/system/store","exports"],
 2137  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
 2138    "use strict";
 2139    var JSONSerializer = __dependency1__.JSONSerializer;
 2140    var RESTSerializer = __dependency1__.RESTSerializer;
 2141    var RESTAdapter = __dependency2__.RESTAdapter;
 2142    var ContainerProxy = __dependency3__["default"];
 2143    var Store = __dependency4__["default"];
 2144
 2145    /**
 2146      Configures a container for use with an Ember-Data
 2147      store. Accepts an optional namespace argument.
 2148
 2149      @method initializeStore
 2150      @param {Ember.Container} container
 2151      @param {Object} [application] an application namespace
 2152    */
 2153    __exports__["default"] = function initializeStore(container, application){
 2154      Ember.deprecate('Specifying a custom Store for Ember Data on your global namespace as `App.Store` ' +
 2155                      'has been deprecated. Please use `App.ApplicationStore` instead.', !(application && application.Store));
 2156
 2157      container.register('store:main', container.lookupFactory('store:application') || (application && application.Store) || Store);
 2158
 2159      // allow older names to be looked up
 2160
 2161      var proxy = new ContainerProxy(container);
 2162      proxy.registerDeprecations([
 2163        { deprecated: 'serializer:_default',  valid: 'serializer:-default' },
 2164        { deprecated: 'serializer:_rest',     valid: 'serializer:-rest' },
 2165        { deprecated: 'adapter:_rest',        valid: 'adapter:-rest' }
 2166      ]);
 2167
 2168      // new go forward paths
 2169      container.register('serializer:-default', JSONSerializer);
 2170      container.register('serializer:-rest', RESTSerializer);
 2171      container.register('adapter:-rest', RESTAdapter);
 2172
 2173      // Eagerly generate the store so defaultStore is populated.
 2174      // TODO: Do this in a finisher hook
 2175      container.lookup('store:main');
 2176    };
 2177  });
 2178define("ember-data/initializers/store_injections",
 2179  ["exports"],
 2180  function(__exports__) {
 2181    "use strict";
 2182    /**
 2183      Configures a container with injections on Ember applications
 2184      for the Ember-Data store. Accepts an optional namespace argument.
 2185
 2186      @method initializeStoreInjections
 2187      @param {Ember.Container} container
 2188    */
 2189    __exports__["default"] = function initializeStoreInjections(container){
 2190      container.injection('controller',   'store', 'store:main');
 2191      container.injection('route',        'store', 'store:main');
 2192      container.injection('serializer',   'store', 'store:main');
 2193      container.injection('data-adapter', 'store', 'store:main');
 2194    };
 2195  });
 2196define("ember-data/initializers/transforms",
 2197  ["ember-data/transforms","exports"],
 2198  function(__dependency1__, __exports__) {
 2199    "use strict";
 2200    var BooleanTransform = __dependency1__.BooleanTransform;
 2201    var DateTransform = __dependency1__.DateTransform;
 2202    var StringTransform = __dependency1__.StringTransform;
 2203    var NumberTransform = __dependency1__.NumberTransform;
 2204
 2205    /**
 2206      Configures a container for use with Ember-Data
 2207      transforms.
 2208
 2209      @method initializeTransforms
 2210      @param {Ember.Container} container
 2211    */
 2212    __exports__["default"] = function initializeTransforms(container){
 2213      container.register('transform:boolean', BooleanTransform);
 2214      container.register('transform:date',    DateTransform);
 2215      container.register('transform:number',  NumberTransform);
 2216      container.register('transform:string',  StringTransform);
 2217    };
 2218  });
 2219define("ember-data/serializers",
 2220  ["ember-data/serializers/json_serializer","ember-data/serializers/rest_serializer","exports"],
 2221  function(__dependency1__, __dependency2__, __exports__) {
 2222    "use strict";
 2223    var JSONSerializer = __dependency1__["default"];
 2224    var RESTSerializer = __dependency2__["default"];
 2225
 2226    __exports__.JSONSerializer = JSONSerializer;
 2227    __exports__.RESTSerializer = RESTSerializer;
 2228  });
 2229define("ember-data/serializers/embedded_records_mixin",
 2230  ["exports"],
 2231  function(__exports__) {
 2232    "use strict";
 2233    var get = Ember.get;
 2234    var forEach = Ember.EnumerableUtils.forEach;
 2235    var camelize = Ember.String.camelize;
 2236
 2237    /**
 2238      ## Using Embedded Records
 2239
 2240      `DS.EmbeddedRecordsMixin` supports serializing embedded records.
 2241
 2242      To set up embedded records, include the mixin when extending a serializer
 2243      then define and configure embedded (model) relationships.
 2244
 2245      Below is an example of a per-type serializer ('post' type).
 2246
 2247      ```js
 2248      App.PostSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
 2249        attrs: {
 2250          author: { embedded: 'always' },
 2251          comments: { serialize: 'ids' }
 2252        }
 2253      });
 2254      ```
 2255      Note that this use of `{ embedded: 'always' }` is unrelated to
 2256      the `{ embedded: 'always' }` that is defined as an option on `DS.attr` as part of
 2257      defining a model while working with the ActiveModelSerializer.  Nevertheless,
 2258      using `{ embedded: 'always' }` as an option to DS.attr is not a valid way to setup
 2259      embedded records.
 2260
 2261      The `attrs` option for a resource `{ embedded: 'always' }` is shorthand for:
 2262
 2263      ```js
 2264      { 
 2265        serialize: 'records',
 2266        deserialize: 'records'
 2267      }
 2268      ```
 2269
 2270      ### Configuring Attrs
 2271
 2272      A resource's `attrs` option may be set to use `ids`, `records` or false for the
 2273      `serialize`  and `deserialize` settings.
 2274
 2275      The `attrs` property can be set on the ApplicationSerializer or a per-type
 2276      serializer.
 2277
 2278      In the case where embedded JSON is expected while extracting a payload (reading)
 2279      the setting is `deserialize: 'records'`, there is no need to use `ids` when
 2280      extracting as that is the default behavior without this mixin if you are using
 2281      the vanilla EmbeddedRecordsMixin. Likewise, to embed JSON in the payload while
 2282      serializing `serialize: 'records'` is the setting to use. There is an option of
 2283      not embedding JSON in the serialized payload by using `serialize: 'ids'`. If you
 2284      do not want the relationship sent at all, you can use `serialize: false`.
 2285
 2286
 2287      ### EmbeddedRecordsMixin defaults
 2288      If you do not overwrite `attrs` for a specific relationship, the `EmbeddedRecordsMixin`
 2289      will behave in the following way:
 2290
 2291      BelongsTo: `{ serialize: 'id', deserialize: 'id' }`  
 2292      HasMany:   `{ serialize: false, deserialize: 'ids' }`
 2293
 2294      ### Model Relationships
 2295
 2296      Embedded records must have a model defined to be extracted and serialized. Note that
 2297      when defining any relationships on your model such as `belongsTo` and `hasMany`, you
 2298      should not both specify `async:true` and also indicate through the serializer's
 2299      `attrs` attribute that the related model should be embedded.  If a model is
 2300      declared embedded, then do not use `async:true`.
 2301
 2302      To successfully extract and serialize embedded records the model relationships
 2303      must be setup correcty See the
 2304      [defining relationships](/guides/models/defining-models/#toc_defining-relationships)
 2305      section of the **Defining Models** guide page.
 2306
 2307      Records without an `id` property are not considered embedded records, model
 2308      instances must have an `id` property to be used with Ember Data.
 2309
 2310      ### Example JSON payloads, Models and Serializers
 2311
 2312      **When customizing a serializer it is important to grok what the customizations
 2313      are. Please read the docs for the methods this mixin provides, in case you need
 2314      to modify it to fit your specific needs.**
 2315
 2316      For example review the docs for each method of this mixin:
 2317      * [normalize](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_normalize)
 2318      * [serializeBelongsTo](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_serializeBelongsTo)
 2319      * [serializeHasMany](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_serializeHasMany)
 2320
 2321      @class EmbeddedRecordsMixin
 2322      @namespace DS
 2323    */
 2324    var EmbeddedRecordsMixin = Ember.Mixin.create({
 2325
 2326      /**
 2327        Normalize the record and recursively normalize/extract all the embedded records
 2328        while pushing them into the store as they are encountered
 2329
 2330        A payload with an attr configured for embedded records needs to be extracted:
 2331
 2332        ```js
 2333        {
 2334          "post": {
 2335            "id": "1"
 2336            "title": "Rails is omakase",
 2337            "comments": [{
 2338              "id": "1",
 2339              "body": "Rails is unagi"
 2340            }, {
 2341              "id": "2",
 2342              "body": "Omakase O_o"
 2343            }]
 2344          }
 2345        }
 2346        ```
 2347       @method normalize
 2348       @param {subclass of DS.Model} type
 2349       @param {Object} hash to be normalized
 2350       @param {String} key the hash has been referenced by
 2351       @return {Object} the normalized hash
 2352      **/
 2353      normalize: function(type, hash, prop) {
 2354        var normalizedHash = this._super(type, hash, prop);
 2355        return extractEmbeddedRecords(this, this.store, type, normalizedHash);
 2356      },
 2357
 2358      keyForRelationship: function(key, type){
 2359        if (this.hasDeserializeRecordsOption(key)) {
 2360          return this.keyForAttribute(key);
 2361        } else {
 2362          return this._super(key, type) || key;
 2363        }
 2364      },
 2365
 2366      /**
 2367        Serialize `belongsTo` relationship when it is configured as an embedded object.
 2368
 2369        This example of an author model belongs to a post model:
 2370
 2371        ```js
 2372        Post = DS.Model.extend({
 2373          title:    DS.attr('string'),
 2374          body:     DS.attr('string'),
 2375          author:   DS.belongsTo('author')
 2376        });
 2377
 2378        Author = DS.Model.extend({
 2379          name:     DS.attr('string'),
 2380          post:     DS.belongsTo('post')
 2381        });
 2382        ```
 2383
 2384        Use a custom (type) serializer for the post model to configure embedded author
 2385
 2386        ```js
 2387        App.PostSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
 2388          attrs: {
 2389            author: {embedded: 'always'}
 2390          }
 2391        })
 2392        ```
 2393
 2394        A payload with an attribute configured for embedded records can serialize
 2395        the records together under the root attribute's payload:
 2396
 2397        ```js
 2398        {
 2399          "post": {
 2400            "id": "1"
 2401            "title": "Rails is omakase",
 2402            "author": {
 2403              "id": "2"
 2404              "name": "dhh"
 2405            }
 2406          }
 2407        }
 2408        ```
 2409
 2410        @method serializeBelongsTo
 2411        @param {DS.Model} record
 2412        @param {Object} json
 2413        @param {Object} relationship
 2414      */
 2415      serializeBelongsTo: function(record, json, relationship) {
 2416        var attr = relationship.key;
 2417        if (this.noSerializeOptionSpecified(attr)) {
 2418          this._super(record, json, relationship);
 2419          return;
 2420        }
 2421        var includeIds = this.hasSerializeIdsOption(attr);
 2422        var includeRecords = this.hasSerializeRecordsOption(attr);
 2423        var embeddedRecord = record.get(attr);
 2424        var key;
 2425        if (includeIds) {
 2426          key = this.keyForRelationship(attr, relationship.kind);
 2427          if (!embeddedRecord) {
 2428            json[key] = null;
 2429          } else {
 2430            json[key] = get(embeddedRecord, 'id');
 2431          }
 2432        } else if (includeRecords) {
 2433          key = this.keyForAttribute(attr);
 2434          if (!embeddedRecord) {
 2435            json[key] = null;
 2436          } else {
 2437            json[key] = embeddedRecord.serialize({includeId: true});
 2438            this.removeEmbeddedForeignKey(record, embeddedRecord, relationship, json[key]);
 2439          }
 2440        }
 2441      },
 2442
 2443      /**
 2444        Serialize `hasMany` relationship when it is configured as embedded objects.
 2445
 2446        This example of a post model has many comments:
 2447
 2448        ```js
 2449        Post = DS.Model.extend({
 2450          title:    DS.attr('string'),
 2451          body:     DS.attr('string'),
 2452          comments: DS.hasMany('comment')
 2453        });
 2454
 2455        Comment = DS.Model.extend({
 2456          body:     DS.attr('string'),
 2457          post:     DS.belongsTo('post')
 2458        });
 2459        ```
 2460
 2461        Use a custom (type) serializer for the post model to configure embedded comments
 2462
 2463        ```js
 2464        App.PostSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
 2465          attrs: {
 2466            comments: {embedded: 'always'}
 2467          }
 2468        })
 2469        ```
 2470
 2471        A payload with an attribute configured for embedded records can serialize
 2472        the records together under the root attribute's payload:
 2473
 2474        ```js
 2475        {
 2476          "post": {
 2477            "id": "1"
 2478            "title": "Rails is omakase",
 2479            "body": "I want this for my ORM, I want that for my template language..."
 2480            "comments": [{
 2481              "id": "1",
 2482              "body": "Rails is unagi"
 2483            }, {
 2484              "id": "2",
 2485              "body": "Omakase O_o"
 2486            }]
 2487          }
 2488        }
 2489        ```
 2490
 2491        The attrs options object can use more specific instruction for extracting and
 2492        serializing. When serializing, an option to embed `ids` or `records` can be set.
 2493        When extracting the only option is `records`.
 2494
 2495        So `{embedded: 'always'}` is shorthand for:
 2496        `{serialize: 'records', deserialize: 'records'}`
 2497
 2498        To embed the `ids` for a related object (using a hasMany relationship):
 2499
 2500        ```js
 2501        App.PostSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
 2502          attrs: {
 2503            comments: {serialize: 'ids', deserialize: 'records'}
 2504          }
 2505        })
 2506        ```
 2507
 2508        ```js
 2509        {
 2510          "post": {
 2511            "id": "1"
 2512            "title": "Rails is omakase",
 2513            "body": "I want this for my ORM, I want that for my template language..."
 2514            "comments": ["1", "2"]
 2515          }
 2516        }
 2517        ```
 2518
 2519        @method serializeHasMany
 2520        @param {DS.Model} record
 2521        @param {Object} json
 2522        @param {Object} relationship
 2523      */
 2524      serializeHasMany: function(record, json, relationship) {
 2525        var attr = relationship.key;
 2526        if (this.noSerializeOptionSpecified(attr)) {
 2527          this._super(record, json, relationship);
 2528          return;
 2529        }
 2530        var includeIds = this.hasSerializeIdsOption(attr);
 2531        var includeRecords = this.hasSerializeRecordsOption(attr);
 2532        var key;
 2533        if (includeIds) {
 2534          key = this.keyForRelationship(attr, relationship.kind);
 2535          json[key] = get(record, attr).mapBy('id');
 2536        } else if (includeRecords) {
 2537          key = this.keyForAttribute(attr);
 2538          json[key] = get(record, attr).map(function(embeddedRecord) {
 2539            var serializedEmbeddedRecord = embeddedRecord.serialize({includeId: true});
 2540            this.removeEmbeddedForeignKey(record, embeddedRecord, relationship, serializedEmbeddedRecord);
 2541            return serializedEmbeddedRecord;
 2542          }, this);
 2543        }
 2544      },
 2545
 2546      /**
 2547        When serializing an embedded record, modify the property (in the json payload)
 2548        that refers to the parent record (foreign key for relationship).
 2549
 2550        Serializing a `belongsTo` relationship removes the property that refers to the
 2551        parent record
 2552
 2553        Serializing a `hasMany` relationship does not remove the property that refers to
 2554        the parent record.
 2555
 2556        @method removeEmbeddedForeignKey
 2557        @param {DS.Model} record
 2558        @param {DS.Model} embeddedRecord
 2559        @param {Object} relationship
 2560        @param {Object} json
 2561      */
 2562      removeEmbeddedForeignKey: function (record, embeddedRecord, relationship, json) {
 2563        if (relationship.kind === 'hasMany') {
 2564          return;
 2565        } else if (relationship.kind === 'belongsTo') {
 2566          var parentRecord = record.constructor.inverseFor(relationship.key);
 2567          if (parentRecord) {
 2568            var name = parentRecord.name;
 2569            var embeddedSerializer = this.store.serializerFor(embeddedRecord.constructor);
 2570            var parentKey = embeddedSerializer.keyForRelationship(name, parentRecord.kind);
 2571            if (parentKey) {
 2572              delete json[parentKey];
 2573            }
 2574          }
 2575        }
 2576      },
 2577
 2578      // checks config for attrs option to embedded (always) - serialize and deserialize
 2579      hasEmbeddedAlwaysOption: function (attr) {
 2580        var option = this.attrsOption(attr);
 2581        return option && option.embedded === 'always';
 2582      },
 2583
 2584      // checks config for attrs option to serialize ids
 2585      hasSerializeRecordsOption: function(attr) {
 2586        var alwaysEmbed = this.hasEmbeddedAlwaysOption(attr);
 2587        var option = this.attrsOption(attr);
 2588        return alwaysEmbed || (option && (option.serialize === 'records'));
 2589      },
 2590
 2591      // checks config for attrs option to serialize records
 2592      hasSerializeIdsOption: function(attr) {
 2593        var option = this.attrsOption(attr);
 2594        return option && (option.serialize === 'ids' || option.serialize === 'id');
 2595      },
 2596
 2597      // checks config for attrs option to serialize records
 2598      noSerializeOptionSpecified: function(attr) {
 2599        var option = this.attrsOption(attr);
 2600        return !(option && (option.serialize || option.embedded));
 2601      },
 2602
 2603      // checks config for attrs option to deserialize records
 2604      // a defined option object for a resource is treated the same as
 2605      // `deserialize: 'records'`
 2606      hasDeserializeRecordsOption: function(attr) {
 2607        var alwaysEmbed = this.hasEmbeddedAlwaysOption(attr);
 2608        var option = this.attrsOption(attr);
 2609        return alwaysEmbed || (option && option.deserialize === 'records');
 2610      },
 2611
 2612      attrsOption: function(attr) {
 2613        var attrs = this.get('attrs');
 2614        return attrs && (attrs[camelize(attr)] || attrs[attr]);
 2615      }
 2616    });
 2617
 2618    // chooses a relationship kind to branch which function is used to update payload
 2619    // does not change payload if attr is not embedded
 2620    function extractEmbeddedRecords(serializer, store, type, partial) {
 2621
 2622      type.eachRelationship(function(key, relationship) {
 2623        if (serializer.hasDeserializeRecordsOption(key)) {
 2624          var embeddedType = store.modelFor(relationship.type.typeKey);
 2625          if (relationship.kind === "hasMany") {
 2626            if (relationship.options.polymorphic) {
 2627              extractEmbeddedHasManyPolymorphic(store, key, partial);
 2628            }
 2629            else {
 2630              extractEmbeddedHasMany(store, key, embeddedType, partial);
 2631            }
 2632          }
 2633          if (relationship.kind === "belongsTo") {
 2634            extractEmbeddedBelongsTo(store, key, embeddedType, partial);
 2635          }
 2636        }
 2637      });
 2638
 2639      return partial;
 2640    }
 2641
 2642    // handles embedding for `hasMany` relationship
 2643    function extractEmbeddedHasMany(store, key, embeddedType, hash) {
 2644      if (!hash[key]) {
 2645        return hash;
 2646      }
 2647
 2648      var ids = [];
 2649
 2650      var embeddedSerializer = store.serializerFor(embeddedType.typeKey);
 2651      forEach(hash[key], function(data) {
 2652        var embeddedRecord = embeddedSerializer.normalize(embeddedType, data, null);
 2653        store.push(embeddedType, embeddedRecord);
 2654        ids.push(embeddedRecord.id);
 2655      });
 2656
 2657      hash[key] = ids;
 2658      return hash;
 2659    }
 2660
 2661    function extractEmbeddedHasManyPolymorphic(store, key, hash) {
 2662      if (!hash[key]) {
 2663        return hash;
 2664      }
 2665
 2666      var ids = [];
 2667
 2668      forEach(hash[key], function(data) {
 2669        var typeKey = data.type;
 2670        var embeddedSerializer = store.serializerFor(typeKey);
 2671        var embeddedType = store.modelFor(typeKey);
 2672        var primaryKey = get(embeddedSerializer, 'primaryKey');
 2673
 2674        var embeddedRecord = embeddedSerializer.normalize(embeddedType, data, null);
 2675        store.push(embeddedType, embeddedRecord);
 2676        ids.push({ id: embeddedRecord[primaryKey], type: typeKey });
 2677      });
 2678
 2679      hash[key] = ids;
 2680      return hash;
 2681    }
 2682
 2683    function extractEmbeddedBelongsTo(store, key, embeddedType, hash) {
 2684      if (!hash[key]) {
 2685        return hash;
 2686      }
 2687
 2688      var embeddedSerializer = store.serializerFor(embeddedType.typeKey);
 2689      var embeddedRecord = embeddedSerializer.normalize(embeddedType, hash[key], null);
 2690      store.push(embeddedType, embeddedRecord);
 2691
 2692      hash[key] = embeddedRecord.id;
 2693      //TODO Need to add a reference to the parent later so relationship works between both `belongsTo` records
 2694      return hash;
 2695    }
 2696
 2697    __exports__["default"] = EmbeddedRecordsMixin;
 2698  });
 2699define("ember-data/serializers/json_serializer",
 2700  ["exports"],
 2701  function(__exports__) {
 2702    "use strict";
 2703    var get = Ember.get;
 2704    var isNone = Ember.isNone;
 2705    var map = Ember.ArrayPolyfills.map;
 2706    var merge = Ember.merge;
 2707
 2708    /**
 2709      In Ember Data a Serializer is used to serialize and deserialize
 2710      records when they are transferred in and out of an external source.
 2711      This process involves normalizing property names, transforming
 2712      attribute values and serializing relationships.
 2713
 2714      For maximum performance Ember Data recommends you use the
 2715      [RESTSerializer](DS.RESTSerializer.html) or one of its subclasses.
 2716
 2717      `JSONSerializer` is useful for simpler or legacy backends that may
 2718      not support the http://jsonapi.org/ spec.
 2719
 2720      @class JSONSerializer
 2721      @namespace DS
 2722    */
 2723    __exports__["default"] = Ember.Object.extend({
 2724      /**
 2725        The primaryKey is used when serializing and deserializing
 2726        data. Ember Data always uses the `id` property to store the id of
 2727        the record. The external source may not always follow this
 2728        convention. In these cases it is useful to override the
 2729        primaryKey property to match the primaryKey of your external
 2730        store.
 2731
 2732        Example
 2733
 2734        ```javascript
 2735        App.ApplicationSerializer = DS.JSONSerializer.extend({
 2736          primaryKey: '_id'
 2737        });
 2738        ```
 2739
 2740        @property primaryKey
 2741        @type {String}
 2742        @default 'id'
 2743      */
 2744      primaryKey: 'id',
 2745
 2746      /**
 2747        The `attrs` object can be used to declare a simple mapping between
 2748        property names on `DS.Model` records and payload keys in the
 2749        serialized JSON object representing the record. An object with the
 2750        property `key` can also be used to designate the attribute's key on
 2751        the response payload.
 2752
 2753        Example
 2754
 2755        ```javascript
 2756        App.Person = DS.Model.extend({
 2757          firstName: DS.attr('string'),
 2758          lastName: DS.attr('string'),
 2759          occupation: DS.attr('string'),
 2760          admin: DS.attr('boolean')
 2761        });
 2762
 2763        App.PersonSerializer = DS.JSONSerializer.extend({
 2764          attrs: {
 2765            admin: 'is_admin',
 2766            occupation: {key: 'career'}
 2767          }
 2768        });
 2769        ```
 2770
 2771        You can also remove attributes by setting the `serialize` key to
 2772        false in your mapping object.
 2773
 2774        Example
 2775
 2776        ```javascript
 2777        App.PersonSerializer = DS.JSONSerializer.extend({
 2778          attrs: {
 2779            admin: {serialize: false},
 2780            occupation: {key: 'career'}
 2781          }
 2782        });
 2783        ```
 2784
 2785        When serialized:
 2786
 2787        ```javascript
 2788        {
 2789          "career": "magician"
 2790        }
 2791        ```
 2792
 2793        Note that the `admin` is now not included in the payload.
 2794
 2795        @property attrs
 2796        @type {Object}
 2797      */
 2798
 2799      /**
 2800       Given a subclass of `DS.Model` and a JSON object this method will
 2801       iterate through each attribute of the `DS.Model` and invoke the
 2802       `DS.Transform#deserialize` method on the matching property of the
 2803       JSON object.  This method is typically called after the
 2804       serializer's `normalize` method.
 2805
 2806       @method applyTransforms
 2807       @private
 2808       @param {subclass of DS.Model} type
 2809       @param {Object} data The data to transform
 2810       @return {Object} data The transformed data object
 2811      */
 2812      applyTransforms: function(type, data) {
 2813        type.eachTransformedAttribute(function applyTransform(key, type) {
 2814          if (!data.hasOwnProperty(key)) { return; }
 2815
 2816          var transform = this.transformFor(type);
 2817          data[key] = transform.deserialize(data[key]);
 2818        }, this);
 2819
 2820        return data;
 2821      },
 2822
 2823      /**
 2824        Normalizes a part of the JSON payload returned by
 2825        the server. You should override this method, munge the hash
 2826        and call super if you have generic normalization to do.
 2827
 2828        It takes the type of the record that is being normalized
 2829        (as a DS.Model class), the property where the hash was
 2830        originally found, and the hash to normalize.
 2831
 2832        You can use this method, for example, to normalize underscored keys to camelized
 2833        or other general-purpose normalizations.
 2834
 2835        Example
 2836
 2837        ```javascript
 2838        App.ApplicationSerializer = DS.JSONSerializer.extend({
 2839          normalize: function(type, hash) {
 2840            var fields = Ember.get(type, 'fields');
 2841            fields.forEach(function(field) {
 2842              var payloadField = Ember.String.underscore(field);
 2843              if (field === payloadField) { return; }
 2844
 2845              hash[field] = hash[payloadField];
 2846              delete hash[payloadField];
 2847            });
 2848            return this._super.apply(this, arguments);
 2849          }
 2850        });
 2851        ```
 2852
 2853        @method normalize
 2854        @param {subclass of DS.Model} type
 2855        @param {Object} hash
 2856        @return {Object}
 2857      */
 2858      normalize: function(type, hash) {
 2859        if (!hash) { return hash; }
 2860
 2861        this.normalizeId(hash);
 2862        this.normalizeAttributes(type, hash);
 2863        this.normalizeRelationships(type, hash);
 2864
 2865        this.normalizeUsingDeclaredMapping(type, hash);
 2866        this.applyTransforms(type, hash);
 2867        return hash;
 2868      },
 2869
 2870      /**
 2871        You can use this method to normalize all payloads, regardless of whether they
 2872        represent single records or an array.
 2873
 2874        For example, you might want to remove some extraneous data from the payload:
 2875
 2876        ```js
 2877        App.ApplicationSerializer = DS.JSONSerializer.extend({
 2878          normalizePayload: function(payload) {
 2879            delete payload.version;
 2880            delete payload.status;
 2881            return payload;
 2882          }
 2883        });
 2884        ```
 2885
 2886        @method normalizePayload
 2887        @param {Object} payload
 2888        @return {Object} the normalized payload
 2889      */
 2890      normalizePayload: function(payload) {
 2891        return payload;
 2892      },
 2893
 2894      /**
 2895        @method normalizeAttributes
 2896        @private
 2897      */
 2898      normalizeAttributes: function(type, hash) {
 2899        var payloadKey;
 2900
 2901        if (this.keyForAttribute) {
 2902          type.eachAttribute(function(key) {
 2903            payloadKey = this.keyForAttribute(key);
 2904            if (key === payloadKey) { return; }
 2905            if (!hash.hasOwnProperty(payloadKey)) { return; }
 2906
 2907            hash[key] = hash[payloadKey];
 2908            delete hash[payloadKey];
 2909          }, this);
 2910        }
 2911      },
 2912
 2913      /**
 2914        @method normalizeRelationships
 2915        @private
 2916      */
 2917      normalizeRelationships: function(type, hash) {
 2918        var payloadKey;
 2919
 2920        if (this.keyForRelationship) {
 2921          type.eachRelationship(function(key, relationship) {
 2922            payloadKey = this.keyForRelationship(key, relationship.kind);
 2923            if (key === payloadKey) { return; }
 2924            if (!hash.hasOwnProperty(payloadKey)) { return; }
 2925
 2926            hash[key] = hash[payloadKey];
 2927            delete hash[payloadKey];
 2928          }, this);
 2929        }
 2930      },
 2931
 2932      /**
 2933        @method normalizeUsingDeclaredMapping
 2934        @private
 2935      */
 2936      normalizeUsingDeclaredMapping: function(type, hash) {
 2937        var attrs = get(this, 'attrs'), payloadKey, key;
 2938
 2939        if (attrs) {
 2940          for (key in attrs) {
 2941            payloadKey = this._getMappedKey(key);
 2942            if (!hash.hasOwnProperty(payloadKey)) { continue; }
 2943
 2944            if (payloadKey !== key) {
 2945              hash[key] = hash[payloadKey];
 2946              delete hash[payloadKey];
 2947            }
 2948          }
 2949        }
 2950      },
 2951
 2952      /**
 2953        @method normalizeId
 2954        @private
 2955      */
 2956      normalizeId: function(hash) {
 2957        var primaryKey = get(this, 'primaryKey');
 2958
 2959        if (primaryKey === 'id') { return; }
 2960
 2961        hash.id = hash[primaryKey];
 2962        delete hash[primaryKey];
 2963      },
 2964
 2965      /**
 2966        Looks up the property key that was set by the custom `attr` mapping
 2967        passed to the serializer.
 2968
 2969        @method _getMappedKey
 2970        @private
 2971        @param {String} key
 2972        @return {String} key
 2973      */
 2974      _getMappedKey: function(key) {
 2975        var attrs = get(this, 'attrs');
 2976        var mappedKey;
 2977        if (attrs && attrs[key]) {
 2978          mappedKey = attrs[key];
 2979          //We need to account for both the {title: 'post_title'} and
 2980          //{title: {key: 'post_title'}} forms
 2981          if (mappedKey.key){
 2982            mappedKey = mappedKey.key;
 2983          }
 2984          if (typeof mappedKey === 'string'){
 2985            key = mappedKey;
 2986          }
 2987        }
 2988
 2989        return key;
 2990      },
 2991
 2992      /**
 2993        Check attrs.key.serialize property to inform if the `key`
 2994        can be serialized
 2995
 2996        @method _canSerialize
 2997        @private
 2998        @param {String} key
 2999        @return {boolean} true if the key can be serialized
 3000      */
 3001      _canSerialize: function(key) {
 3002        var attrs = get(this, 'attrs');
 3003
 3004        return !attrs || !attrs[key] || attrs[key].serialize !== false;
 3005      },
 3006
 3007      // SERIALIZE
 3008      /**
 3009        Called when a record is saved in order to convert the
 3010        record into JSON.
 3011
 3012        By default, it creates a JSON object with a key for
 3013        each attribute and belongsTo relationship.
 3014
 3015        For example, consider this model:
 3016
 3017        ```javascript
 3018        App.Comment = DS.Model.extend({
 3019          title: DS.attr(),
 3020          body: DS.attr(),
 3021
 3022          author: DS.belongsTo('user')
 3023        });
 3024        ```
 3025
 3026        The default serialization would create a JSON object like:
 3027
 3028        ```javascript
 3029        {
 3030          "title": "Rails is unagi",
 3031          "body": "Rails? Omakase? O_O",
 3032          "author": 12
 3033        }
 3034        ```
 3035
 3036        By default, attributes are passed through as-is, unless
 3037        you specified an attribute type (`DS.attr('date')`). If
 3038        you specify a transform, the JavaScript value will be
 3039        serialized when inserted into the JSON hash.
 3040
 3041        By default, belongs-to relationships are converted into
 3042        IDs when inserted into the JSON hash.
 3043
 3044        ## IDs
 3045
 3046        `serialize` takes an options hash with a single option:
 3047        `includeId`. If this option is `true`, `serialize` will,
 3048        by default include the ID in the JSON object it builds.
 3049
 3050        The adapter passes in `includeId: true` when serializing
 3051        a record for `createRecord`, but not for `updateRecord`.
 3052
 3053        ## Customization
 3054
 3055        Your server may expect a different JSON format than the
 3056        built-in serialization format.
 3057
 3058        In that case, you can implement `serialize` yourself and
 3059        return a JSON hash of your choosing.
 3060
 3061        ```javascript
 3062        App.PostSerializer = DS.JSONSerializer.extend({
 3063          serialize: function(post, options) {
 3064            var json = {
 3065              POST_TTL: post.get('title'),
 3066              POST_BDY: post.get('body'),
 3067              POST_CMS: post.get('comments').mapBy('id')
 3068            }
 3069
 3070            if (options.includeId) {
 3071              json.POST_ID_ = post.get('id');
 3072            }
 3073
 3074            return json;
 3075          }
 3076        });
 3077        ```
 3078
 3079        ## Customizing an App-Wide Serializer
 3080
 3081        If you want to define a serializer for your entire
 3082        application, you'll probably want to use `eachAttribute`
 3083        and `eachRelationship` on the record.
 3084
 3085        ```javascript
 3086        App.ApplicationSerializer = DS.JSONSerializer.extend({
 3087          serialize: function(record, options) {
 3088            var json = {};
 3089
 3090            record.eachAttribute(function(name) {
 3091              json[serverAttributeName(name)] = record.get(name);
 3092            })
 3093
 3094            record.eachRelationship(function(name, relationship) {
 3095              if (relationship.kind === 'hasMany') {
 3096                json[serverHasManyName(name)] = record.get(name).mapBy('id');
 3097              }
 3098            });
 3099
 3100            if (options.includeId) {
 3101              json.ID_ = record.get('id');
 3102            }
 3103
 3104            return json;
 3105          }
 3106        });
 3107
 3108        function serverAttributeName(attribute) {
 3109          return attribute.underscore().toUpperCase();
 3110        }
 3111
 3112        function serverHasManyName(name) {
 3113          return serverAttributeName(name.singularize()) + "_IDS";
 3114        }
 3115        ```
 3116
 3117        This serializer will generate JSON that looks like this:
 3118
 3119        ```javascript
 3120        {
 3121          "TITLE": "Rails is omakase",
 3122          "BODY": "Yep. Omakase.",
 3123          "COMMENT_IDS": [ 1, 2, 3 ]
 3124        }
 3125        ```
 3126
 3127        ## Tweaking the Default JSON
 3128
 3129        If you just want to do some small tweaks on the default JSON,
 3130        you can call super first and make the tweaks on the returned
 3131        JSON.
 3132
 3133        ```javascript
 3134        App.PostSerializer = DS.JSONSerializer.extend({
 3135          serialize: function(record, options) {
 3136            var json = this._super.apply(this, arguments);
 3137
 3138            json.subject = json.title;
 3139            delete json.title;
 3140
 3141            return json;
 3142          }
 3143        });
 3144        ```
 3145
 3146        @method serialize
 3147        @param {subclass of DS.Model} record
 3148        @param {Object} options
 3149        @return {Object} json
 3150      */
 3151      serialize: function(record, options) {
 3152        var json = {};
 3153
 3154        if (options && options.includeId) {
 3155          var id = get(record, 'id');
 3156
 3157          if (id) {
 3158            json[get(this, 'primaryKey')] = id;
 3159          }
 3160        }
 3161
 3162        record.eachAttribute(function(key, attribute) {
 3163          this.serializeAttribute(record, json, key, attribute);
 3164        }, this);
 3165
 3166        record.eachRelationship(function(key, relationship) {
 3167          if (relationship.kind === 'belongsTo') {
 3168            this.serializeBelongsTo(record, json, relationship);
 3169          } else if (relationship.kind === 'hasMany') {
 3170            this.serializeHasMany(record, json, relationship);
 3171          }
 3172        }, this);
 3173
 3174        return json;
 3175      },
 3176
 3177      /**
 3178        You can use this method to customize how a serialized record is added to the complete
 3179        JSON hash to be sent to the server. By default the JSON Serializer does not namespace
 3180        the payload and just sends the raw serialized JSON object.
 3181        If your server expects namespaced keys, you should consider using the RESTSerializer.
 3182        Otherwise you can override this method to customize how the record is added to the hash.
 3183
 3184        For example, your server may expect underscored root objects.
 3185
 3186        ```js
 3187        App.ApplicationSerializer = DS.RESTSerializer.extend({
 3188          serializeIntoHash: function(data, type, record, options) {
 3189            var root = Ember.String.decamelize(type.typeKey);
 3190            data[root] = this.serialize(record, options);
 3191          }
 3192        });
 3193        ```
 3194
 3195        @method serializeIntoHash
 3196        @param {Object} hash
 3197        @param {subclass of DS.Model} type
 3198        @param {DS.Model} record
 3199        @param {Object} options
 3200      */
 3201      serializeIntoHash: function(hash, type, record, options) {
 3202        merge(hash, this.serialize(record, options));
 3203      },
 3204
 3205      /**
 3206       `serializeAttribute` can be used to customize how `DS.attr`
 3207       properties are serialized
 3208
 3209       For example if you wanted to ensure all your attributes were always
 3210       serialized as properties on an `attributes` object you could
 3211       write:
 3212
 3213       ```javascript
 3214       App.ApplicationSerializer = DS.JSONSerializer.extend({
 3215         serializeAttribute: function(record, json, key, attributes) {
 3216           json.attributes = json.attributes || {};
 3217           this._super(record, json.attributes, key, attributes);
 3218         }
 3219       });
 3220       ```
 3221
 3222       @method serializeAttribute
 3223       @param {DS.Model} record
 3224       @param {Object} json
 3225       @param {String} key
 3226       @param {Object} attribute
 3227      */
 3228      serializeAttribute: function(record, json, key, attribute) {
 3229        var type = attribute.type;
 3230
 3231        if (this._canSerialize(key)) {
 3232          var value = get(record, key);
 3233          if (type) {
 3234            var transform = this.transformFor(type);
 3235            value = transform.serialize(value);
 3236          }
 3237
 3238          // if provided, use the mapping provided by `attrs` in
 3239          // the serializer
 3240          var payloadKey =  this._getMappedKey(key);
 3241
 3242          if (payloadKey === key && this.keyForAttribute) {
 3243            payloadKey = this.keyForAttribute(key);
 3244          }
 3245
 3246          json[payloadKey] = value;
 3247        }
 3248      },
 3249
 3250      /**
 3251       `serializeBelongsTo` can be used to customize how `DS.belongsTo`
 3252       properties are serialized.
 3253
 3254       Example
 3255
 3256       ```javascript
 3257       App.PostSerializer = DS.JSONSerializer.extend({
 3258         serializeBelongsTo: function(record, json, relationship) {
 3259           var key = relationship.key;
 3260
 3261           var belongsTo = get(record, key);
 3262
 3263           key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo") : key;
 3264
 3265           json[key] = Ember.isNone(belongsTo) ? belongsTo : belongsTo.toJSON();
 3266         }
 3267       });
 3268       ```
 3269
 3270       @method serializeBelongsTo
 3271       @param {DS.Model} record
 3272       @param {Object} json
 3273       @param {Object} relationship
 3274      */
 3275      serializeBelongsTo: function(record, json, relationship) {
 3276        var key = relationship.key;
 3277
 3278        if (this._canSerialize(key)) {
 3279          var belongsTo = get(record, key);
 3280
 3281          // if provided, use the mapping provided by `attrs` in
 3282          // the serializer
 3283          var payloadKey = this._getMappedKey(key);
 3284          if (payloadKey === key && this.keyForRelationship) {
 3285            payloadKey = this.keyForRelationship(key, "belongsTo");
 3286          }
 3287
 3288          //Need to check whether the id is there for new&async records
 3289          if (isNone(belongsTo) || isNone(get(belongsTo, 'id'))) {
 3290            json[payloadKey] = null;
 3291          } else {
 3292            json[payloadKey] = get(belongsTo, 'id');
 3293          }
 3294
 3295          if (relationship.options.polymorphic) {
 3296            this.serializePolymorphicType(record, json, relationship);
 3297          }
 3298        }
 3299      },
 3300
 3301      /**
 3302       `serializeHasMany` can be used to customize how `DS.hasMany`
 3303       properties are serialized.
 3304
 3305       Example
 3306
 3307       ```javascript
 3308       App.PostSerializer = DS.JSONSerializer.extend({
 3309         serializeHasMany: function(record, json, relationship) {
 3310           var key = relationship.key;
 3311           if (key === 'comments') {
 3312             return;
 3313           } else {
 3314             this._super.apply(this, arguments);
 3315           }
 3316         }
 3317       });
 3318       ```
 3319
 3320       @method serializeHasMany
 3321       @param {DS.Model} record
 3322       @param {Object} json
 3323       @param {Object} relationship
 3324      */
 3325      serializeHasMany: function(record, json, relationship) {
 3326        var key = relationship.key;
 3327
 3328        if (this._canSerialize(key)) {
 3329          var payloadKey;
 3330
 3331          // if provided, use the mapping provided by `attrs` in
 3332          // the serializer
 3333          payloadKey = this._getMappedKey(key);
 3334          if (payloadKey === key && this.keyForRelationship) {
 3335            payloadKey = this.keyForRelationship(key, "hasMany");
 3336          }
 3337
 3338          var relationshipType = record.constructor.determineRelationshipType(relationship);
 3339
 3340          if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany') {
 3341            json[payloadKey] = get(record, key).mapBy('id');
 3342            // TODO support for polymorphic manyToNone and manyToMany relationships
 3343          }
 3344        }
 3345      },
 3346
 3347      /**
 3348        You can use this method to customize how polymorphic objects are
 3349        serialized. Objects are considered to be polymorphic if
 3350        `{polymorphic: true}` is pass as the second argument to the
 3351        `DS.belongsTo` function.
 3352
 3353        Example
 3354
 3355        ```javascript
 3356        App.CommentSerializer = DS.JSONSerializer.extend({
 3357          serializePolymorphicType: function(record, json, relationship) {
 3358            var key = relationship.key,
 3359                belongsTo = get(record, key);
 3360            key = this.keyForAttribute ? this.keyForAttribute(key) : key;
 3361
 3362            if (Ember.isNone(belongsTo)) {
 3363              json[key + "_type"] = null;
 3364            } else {
 3365              json[key + "_type"] = belongsTo.constructor.typeKey;
 3366            }
 3367          }
 3368        });
 3369       ```
 3370
 3371        @method serializePolymorphicType
 3372        @param {DS.Model} record
 3373        @param {Object} json
 3374        @param {Object} relationship
 3375      */
 3376      serializePolymorphicType: Ember.K,
 3377
 3378      // EXTRACT
 3379
 3380      /**
 3381        The `extract` method is used to deserialize payload data from the
 3382        server. By default the `JSONSerializer` does not push the records
 3383        into the store. However records that subclass `JSONSerializer`
 3384        such as the `RESTSerializer` may push records into the store as
 3385        part of the extract call.
 3386
 3387        This method delegates to a more specific extract method based on
 3388        the `requestType`.
 3389
 3390        Example
 3391
 3392        ```javascript
 3393        var get = Ember.get;
 3394        socket.on('message', function(message) {
 3395          var modelName = message.model;
 3396          var data = message.data;
 3397          var type = store.modelFor(modelName);
 3398          var serializer = store.serializerFor(type.typeKey);
 3399          var record = serializer.extract(store, type, data, get(data, 'id'), 'single');
 3400          store.push(modelName, record);
 3401        });
 3402        ```
 3403
 3404        @method extract
 3405        @param {DS.Store} store
 3406        @param {subclass of DS.Model} type
 3407        @param {Object} payload
 3408        @param {String or Number} id
 3409        @param {String} requestType
 3410        @return {Object} json The deserialized payload
 3411      */
 3412      extract: function(store, type, payload, id, requestType) {
 3413        this.extractMeta(store, type, payload);
 3414
 3415        var specificExtract = "extract" + requestType.charAt(0).toUpperCase() + requestType.substr(1);
 3416        return this[specificExtract](store, type, payload, id, requestType);
 3417      },
 3418
 3419      /**
 3420        `extractFindAll` is a hook into the extract method used when a
 3421        call is made to `DS.Store#findAll`. By default this method is an
 3422        alias for [extractArray](#method_extractArray).
 3423
 3424        @method extractFindAll
 3425        @param {DS.Store} store
 3426        @param {subclass of DS.Model} type
 3427        @param {Object} payload
 3428        @param {String or Number} id
 3429        @param {String} requestType
 3430        @return {Array} array An array of deserialized objects
 3431      */
 3432      extractFindAll: function(store, type, payload, id, requestType){
 3433        return this.extractArray(store, type, payload, id, requestType);
 3434      },
 3435      /**
 3436        `extractFindQuery` is a hook into the extract method used when a
 3437        call is made to `DS.Store#findQuery`. By default this method is an
 3438        alias for [extractArray](#method_extractArray).
 3439
 3440        @method extractFindQuery
 3441        @param {DS.Store} store
 3442        @param {subclass of DS.Model} type
 3443        @param {Object} payload
 3444        @param {String or Number} id
 3445        @param {String} requestType
 3446        @return {Array} array An array of deserialized objects
 3447      */
 3448      extractFindQuery: function(store, type, payload, id, requestType){
 3449        return this.extractArray(store, type, payload, id, requestType);
 3450      },
 3451      /**
 3452        `extractFindMany` is a hook into the extract method used when a
 3453        call is made to `DS.Store#findMany`. By default this method is
 3454        alias for [extractArray](#method_extractArray).
 3455
 3456        @method extractFindMany
 3457        @param {DS.Store} store
 3458        @param {subclass of DS.Model} type
 3459        @param {Object} payload
 3460        @param {String or Number} id
 3461        @param {String} requestType
 3462        @return {Array} array An array of deserialized objects
 3463      */
 3464      extractFindMany: function(store, type, payload, id, requestType){
 3465        return this.extractArray(store, type, payload, id, requestType);
 3466      },
 3467      /**
 3468        `extractFindHasMany` is a hook into the extract method used when a
 3469        call is made to `DS.Store#findHasMany`. By default this method is
 3470        alias for [extractArray](#method_extractArray).
 3471
 3472        @method extractFindHasMany
 3473        @param {DS.Store} store
 3474        @param {subclass of DS.Model} type
 3475        @param {Object} payload
 3476        @param {String or Number} id
 3477        @param {String} requestType
 3478        @return {Array} array An array of deserialized objects
 3479      */
 3480      extractFindHasMany: function(store, type, payload, id, requestType){
 3481        return this.extractArray(store, type, payload, id, requestType);
 3482      },
 3483
 3484      /**
 3485        `extractCreateRecord` is a hook into the extract method used when a
 3486        call is made to `DS.Store#createRecord`. By default this method is
 3487        alias for [extractSave](#method_extractSave).
 3488
 3489        @method extractCreateRecord
 3490        @param {DS.Store} store
 3491        @param {subclass of DS.Model} type
 3492        @param {Object} payload
 3493        @param {String or Number} id
 3494        @param {String} requestType
 3495        @return {Object} json The deserialized payload
 3496      */
 3497      extractCreateRecord: function(store, type, payload, id, requestType) {
 3498        return this.extractSave(store, type, payload, id, requestType);
 3499      },
 3500      /**
 3501        `extractUpdateRecord` is a hook into the extract method used when
 3502        a call is made to `DS.Store#update`. By default this method is alias
 3503        for [extractSave](#method_extractSave).
 3504
 3505        @method extractUpdateRecord
 3506        @param {DS.Store} store
 3507        @param {subclass of DS.Model} type
 3508        @param {Object} payload
 3509        @param {String or Number} id
 3510        @param {String} requestType
 3511        @return {Object} json The deserialized payload
 3512      */
 3513      extractUpdateRecord: function(store, type, payload, id, requestType) {
 3514        return this.extractSave(store, type, payload, id, requestType);
 3515      },
 3516      /**
 3517        `extractDeleteRecord` is a hook into the extract method used when
 3518        a call is made to `DS.Store#deleteRecord`. By default this method is
 3519        alias for [extractSave](#method_extractSave).
 3520
 3521        @method extractDeleteRecord
 3522        @param {DS.Store} store
 3523        @param {subclass of DS.Model} type
 3524        @param {Object} payload
 3525        @param {String or Number} id
 3526        @param {String} requestType
 3527        @return {Object} json The deserialized payload
 3528      */
 3529      extractDeleteRecord: function(store, type, payload, id, requestType) {
 3530        return this.extractSave(store, type, payload, id, requestType);
 3531      },
 3532
 3533      /**
 3534        `extractFind` is a hook into the extract method used when
 3535        a call is made to `DS.Store#find`. By default this method is
 3536        alias for [extractSingle](#method_extractSingle).
 3537
 3538        @method extractFind
 3539        @param {DS.Store} store
 3540        @param {subclass of DS.Model} type
 3541        @param {Object} payload
 3542        @param {String or Number} id
 3543        @param {String} requestType
 3544        @return {Object} json The deserialized payload
 3545      */
 3546      extractFind: function(store, type, payload, id, requestType) {
 3547        return this.extractSingle(store, type, payload, id, requestType);
 3548      },
 3549      /**
 3550        `extractFindBelongsTo` is a hook into the extract method used when
 3551        a call is made to `DS.Store#findBelongsTo`. By default this method is
 3552        alias for [extractSingle](#method_extractSingle).
 3553
 3554        @method extractFindBelongsTo
 3555        @param {DS.Store} store
 3556        @param {subclass of DS.Model} type
 3557        @param {Object} payload
 3558        @param {String or Number} id
 3559        @param {String} requestType
 3560        @return {Object} json The deserialized payload
 3561      */
 3562      extractFindBelongsTo: function(store, type, payload, id, requestType) {
 3563        return this.extractSingle(store, type, payload, id, requestType);
 3564      },
 3565      /**
 3566        `extractSave` is a hook into the extract method used when a call
 3567        is made to `DS.Model#save`. By default this method is alias
 3568        for [extractSingle](#method_extractSingle).
 3569
 3570        @method extractSave
 3571        @param {DS.Store} store
 3572        @param {subclass of DS.Model} type
 3573        @param {Object} payload
 3574        @param {String or Number} id
 3575        @param {String} requestType
 3576        @return {Object} json The deserialized payload
 3577      */
 3578      extractSave: function(store, type, payload, id, requestType) {
 3579        return this.extractSingle(store, type, payload, id, requestType);
 3580      },
 3581
 3582      /**
 3583        `extractSingle` is used to deserialize a single record returned
 3584        from the adapter.
 3585
 3586        Example
 3587
 3588        ```javascript
 3589        App.PostSerializer = DS.JSONSerializer.extend({
 3590          extractSingle: function(store, type, payload) {
 3591            payload.comments = payload._embedded.comment;
 3592            delete payload._embedded;
 3593
 3594            return this._super(store, type, payload);
 3595          },
 3596        });
 3597        ```
 3598
 3599        @method extractSingle
 3600        @param {DS.Store} store
 3601        @param {subclass of DS.Model} type
 3602        @param {Object} payload
 3603        @param {String or Number} id
 3604        @param {String} requestType
 3605        @return {Object} json The deserialized payload
 3606      */
 3607      extractSingle: function(store, type, payload, id, requestType) {
 3608        payload = this.normalizePayload(payload);
 3609        return this.normalize(type, payload);
 3610      },
 3611
 3612      /**
 3613        `extractArray` is used to deserialize an array of records
 3614        returned from the adapter.
 3615
 3616        Example
 3617
 3618        ```javascript
 3619        App.PostSerializer = DS.JSONSerializer.extend({
 3620          extractArray: function(store, type, payload) {
 3621            return payload.map(function(json) {
 3622              return this.extractSingle(store, type, json);
 3623            }, this);
 3624          }
 3625        });
 3626        ```
 3627
 3628        @method extractArray
 3629        @param {DS.Store} store
 3630        @param {subclass of DS.Model} type
 3631        @param {Object} payload
 3632        @param {String or Number} id
 3633        @param {String} requestType
 3634        @return {Array} array An array of deserialized objects
 3635      */
 3636      extractArray: function(store, type, arrayPayload, id, requestType) {
 3637        var normalizedPayload = this.normalizePayload(arrayPayload);
 3638        var serializer = this;
 3639
 3640        return map.call(normalizedPayload, function(singlePayload) {
 3641          return serializer.normalize(type, singlePayload);
 3642        });
 3643      },
 3644
 3645      /**
 3646        `extractMeta` is used to deserialize any meta information in the
 3647        adapter payload. By default Ember Data expects meta information to
 3648        be located on the `meta` property of the payload object.
 3649
 3650        Example
 3651
 3652        ```javascript
 3653        App.PostSerializer = DS.JSONSerializer.extend({
 3654          extractMeta: function(store, type, payload) {
 3655            if (payload && payload._pagination) {
 3656              store.metaForType(type, payload._pagination);
 3657              delete payload._pagination;
 3658            }
 3659          }
 3660        });
 3661        ```
 3662
 3663        @method extractMeta
 3664        @param {DS.Store} store
 3665        @param {subclass of DS.Model} type
 3666        @param {Object} payload
 3667      */
 3668      extractMeta: function(store, type, payload) {
 3669        if (payload && payload.meta) {
 3670          store.metaForType(type, payload.meta);
 3671          delete payload.meta;
 3672        }
 3673      },
 3674
 3675      /**
 3676       `keyForAttribute` can be used to define rules for how to convert an
 3677       attribute name in your model to a key in your JSON.
 3678
 3679       Example
 3680
 3681       ```javascript
 3682       App.ApplicationSerializer = DS.RESTSerializer.extend({
 3683         keyForAttribute: function(attr) {
 3684           return Ember.String.underscore(attr).toUpperCase();
 3685         }
 3686       });
 3687       ```
 3688
 3689       @method keyForAttribute
 3690       @param {String} key
 3691       @return {String} normalized key
 3692      */
 3693      keyForAttribute: function(key){
 3694        return key;
 3695      },
 3696
 3697      /**
 3698       `keyForRelationship` can be used to define a custom key when
 3699       serializing relationship properties. By default `JSONSerializer`
 3700       does not provide an implementation of this method.
 3701
 3702       Example
 3703
 3704        ```javascript
 3705        App.PostSerializer = DS.JSONSerializer.extend({
 3706          keyForRelationship: function(key, relationship) {
 3707             return 'rel_' + Ember.String.underscore(key);
 3708          }
 3709        });
 3710        ```
 3711
 3712       @method keyForRelationship
 3713       @param {String} key
 3714       @param {String} relationship type
 3715       @return {String} normalized key
 3716      */
 3717
 3718      keyForRelationship: function(key, type){
 3719        return key;
 3720      },
 3721
 3722      // HELPERS
 3723
 3724      /**
 3725       @method transformFor
 3726       @private
 3727       @param {String} attributeType
 3728       @param {Boolean} skipAssertion
 3729       @return {DS.Transform} transform
 3730      */
 3731      transformFor: function(attributeType, skipAssertion) {
 3732        var transform = this.container.lookup('transform:' + attributeType);
 3733        Ember.assert("Unable to find transform for '" + attributeType + "'", skipAssertion || !!transform);
 3734        return transform;
 3735      }
 3736    });
 3737  });
 3738define("ember-data/serializers/rest_serializer",
 3739  ["ember-data/serializers/json_serializer","ember-inflector/system/string","exports"],
 3740  function(__dependency1__, __dependency2__, __exports__) {
 3741    "use strict";
 3742    /**
 3743      @module ember-data
 3744    */
 3745
 3746    var JSONSerializer = __dependency1__["default"];
 3747    var get = Ember.get;
 3748    var forEach = Ember.ArrayPolyfills.forEach;
 3749    var map = Ember.ArrayPolyfills.map;
 3750    var camelize = Ember.String.camelize;
 3751
 3752    var singularize = __dependency2__.singularize;
 3753
 3754    function coerceId(id) {
 3755      return id == null ? null : id + '';
 3756    }
 3757
 3758    /**
 3759      Normally, applications will use the `RESTSerializer` by implementing
 3760      the `normalize` method and individual normalizations under
 3761      `normalizeHash`.
 3762
 3763      This allows you to do whatever kind of munging you need, and is
 3764      especially useful if your server is inconsistent and you need to
 3765      do munging differently for many different kinds of responses.
 3766
 3767      See the `normalize` documentation for more information.
 3768
 3769      ## Across the Board Normalization
 3770
 3771      There are also a number of hooks that you might find useful to define
 3772      across-the-board rules for your payload. These rules will be useful
 3773      if your server is consistent, or if you're building an adapter for
 3774      an infrastructure service, like Parse, and want to encode service
 3775      conventions.
 3776
 3777      For example, if all of your keys are underscored and all-caps, but
 3778      otherwise consistent with the names you use in your models, you
 3779      can implement across-the-board rules for how to convert an attribute
 3780      name in your model to a key in your JSON.
 3781
 3782      ```js
 3783      App.ApplicationSerializer = DS.RESTSerializer.extend({
 3784        keyForAttribute: function(attr) {
 3785          return Ember.String.underscore(attr).toUpperCase();
 3786        }
 3787      });
 3788      ```
 3789
 3790      You can also implement `keyForRelationship`, which takes the name
 3791      of the relationship as the first parameter, and the kind of
 3792      relationship (`hasMany` or `belongsTo`) as the second parameter.
 3793
 3794      @class RESTSerializer
 3795      @namespace DS
 3796      @extends DS.JSONSerializer
 3797    */
 3798    var RESTSerializer = JSONSerializer.extend({
 3799      /**
 3800        If you want to do normalizations specific to some part of the payload, you
 3801        can specify those under `normalizeHash`.
 3802
 3803        For example, given the following json where the the `IDs` under
 3804        `"comments"` are provided as `_id` instead of `id`.
 3805
 3806        ```javascript
 3807        {
 3808          "post": {
 3809            "id": 1,
 3810            "title": "Rails is omakase",
 3811            "comments": [ 1, 2 ]
 3812          },
 3813          "comments": [{
 3814            "_id": 1,
 3815            "body": "FIRST"
 3816          }, {
 3817            "_id": 2,
 3818            "body": "Rails is unagi"
 3819          }]
 3820        }
 3821        ```
 3822
 3823        You use `normalizeHash` to normalize just the comments:
 3824
 3825        ```javascript
 3826        App.PostSerializer = DS.RESTSerializer.extend({
 3827          normalizeHash: {
 3828            comments: function(hash) {
 3829              hash.id = hash._id;
 3830              delete hash._id;
 3831              return hash;
 3832            }
 3833          }
 3834        });
 3835        ```
 3836
 3837        The key under `normalizeHash` is usually just the original key
 3838        that was in the original payload. However, key names will be
 3839        impacted by any modifications done in the `normalizePayload`
 3840        method. The `DS.RESTSerializer`'s default implementation makes no
 3841        changes to the payload keys.
 3842
 3843        @property normalizeHash
 3844        @type {Object}
 3845        @default undefined
 3846      */
 3847
 3848      /**
 3849        Normalizes a part of the JSON payload returned by
 3850        the server. You should override this method, munge the hash
 3851        and call super if you have generic normalization to do.
 3852
 3853        It takes the type of the record that is being normalized
 3854        (as a DS.Model class), the property where the hash was
 3855        originally found, and the hash to normalize.
 3856
 3857        For example, if you have a payload that looks like this:
 3858
 3859        ```js
 3860        {
 3861          "post": {
 3862            "id": 1,
 3863            "title": "Rails is omakase",
 3864            "comments": [ 1, 2 ]
 3865          },
 3866          "comments": [{
 3867            "id": 1,
 3868            "body": "FIRST"
 3869          }, {
 3870            "id": 2,
 3871            "body": "Rails is unagi"
 3872          }]
 3873        }
 3874        ```
 3875
 3876        The `normalize` method will be called three times:
 3877
 3878        * With `App.Post`, `"posts"` and `{ id: 1, title: "Rails is omakase", ... }`
 3879        * With `App.Comment`, `"comments"` and `{ id: 1, body: "FIRST" }`
 3880        * With `App.Comment`, `"comments"` and `{ id: 2, body: "Rails is unagi" }`
 3881
 3882        You can use this method, for example, to normalize underscored keys to camelized
 3883        or other general-purpose normalizations.
 3884
 3885        If you want to do normalizations specific to some part of the payload, you
 3886        can specify those under `normalizeHash`.
 3887
 3888        For example, if the `IDs` under `"comments"` are provided as `_id` instead of
 3889        `id`, you can specify how to normalize just the comments:
 3890
 3891        ```js
 3892        App.PostSerializer = DS.RESTSerializer.extend({
 3893          normalizeHash: {
 3894            comments: function(hash) {
 3895              hash.id = hash._id;
 3896              delete hash._id;
 3897              return hash;
 3898            }
 3899          }
 3900        });
 3901        ```
 3902
 3903        The key under `normalizeHash` is just the original key that was in the original
 3904        payload.
 3905
 3906        @method normalize
 3907        @param {subclass of DS.Model} type
 3908        @param {Object} hash
 3909        @param {String} prop
 3910        @return {Object}
 3911      */
 3912      normalize: function(type, hash, prop) {
 3913        this.normalizeId(hash);
 3914        this.normalizeAttributes(type, hash);
 3915        this.normalizeRelationships(type, hash);
 3916
 3917        this.normalizeUsingDeclaredMapping(type, hash);
 3918
 3919        if (this.normalizeHash && this.normalizeHash[prop]) {
 3920          this.normalizeHash[prop](hash);
 3921        }
 3922
 3923        this.applyTransforms(type, hash);
 3924        return hash;
 3925      },
 3926
 3927
 3928      /**
 3929        Called when the server has returned a payload representing
 3930        a single record, such as in response to a `find` or `save`.
 3931
 3932        It is your opportunity to clean up the server's response into the normalized
 3933        form expected by Ember Data.
 3934
 3935        If you want, you can just restructure the top-level of your payload, and
 3936        do more fine-grained normalization in the `normalize` method.
 3937
 3938        For example, if you have a payload like this in response to a request for
 3939        post 1:
 3940
 3941        ```js
 3942        {
 3943          "id": 1,
 3944          "title": "Rails is omakase",
 3945
 3946          "_embedded": {
 3947            "comment": [{
 3948              "_id": 1,
 3949              "comment_title": "FIRST"
 3950            }, {
 3951              "_id": 2,
 3952              "comment_title": "Rails is unagi"
 3953            }]
 3954          }
 3955        }
 3956        ```
 3957
 3958        You could implement a serializer that looks like this to get your payload
 3959        into shape:
 3960
 3961        ```js
 3962        App.PostSerializer = DS.RESTSerializer.extend({
 3963          // First, restructure the top-level so it's organized by type
 3964          extractSingle: function(store, type, payload, id) {
 3965            var comments = payload._embedded.comment;
 3966            delete payload._embedded;
 3967
 3968            payload = { comments: comments, post: payload };
 3969            return this._super(store, type, payload, id);
 3970          },
 3971
 3972          normalizeHash: {
 3973            // Next, normalize individual comments, which (after `extract`)
 3974            // are now located under `comments`
 3975            comments: function(hash) {
 3976              hash.id = hash._id;
 3977              hash.title = hash.comment_title;
 3978              delete hash._id;
 3979              delete hash.comment_title;
 3980              return hash;
 3981            }
 3982          }
 3983        })
 3984        ```
 3985
 3986        When you call super from your own implementation of `extractSingle`, the
 3987        built-in implementation will find the primary record in your normalized
 3988        payload and push the remaining records into the store.
 3989
 3990        The primary record is the single hash found under `post` or the first
 3991        element of the `posts` array.
 3992
 3993        The primary record has special meaning when the record is being created
 3994        for the first time or updated (`createRecord` or `updateRecord`). In
 3995        particular, it will update the properties of the record that was saved.
 3996
 3997        @method extractSingle
 3998        @param {DS.Store} store
 3999        @param {subclass of DS.Model} primaryType
 4000        @param {Object} payload
 4001        @param {String} recordId
 4002        @return {Object} the primary response to the original request
 4003      */
 4004      extractSingle: function(store, primaryType, rawPayload, recordId) {
 4005        var payload = this.normalizePayload(rawPayload);
 4006        var primaryTypeName = primaryType.typeKey;
 4007        var primaryRecord;
 4008
 4009        for (var prop in payload) {
 4010          var typeName  = this.typeForRoot(prop);
 4011          if (!store.modelFactoryFor(typeName)){
 4012            Ember.warn(this.warnMessageNoModelForKey(prop, typeName), false);
 4013            continue;
 4014          }
 4015          var type = store.modelFor(typeName);
 4016          var isPrimary = type.typeKey === primaryTypeName;
 4017          var value = payload[prop];
 4018
 4019          // legacy support for singular resources
 4020          if (isPrimary && Ember.typeOf(value) !== "array" ) {
 4021            primaryRecord = this.normalize(primaryType, value, prop);
 4022            continue;
 4023          }
 4024
 4025          /*jshint loopfunc:true*/
 4026          forEach.call(value, function(hash) {
 4027            var typeName = this.typeForRoot(prop);
 4028            var type = store.modelFor(typeName);
 4029            var typeSerializer = store.serializerFor(type);
 4030
 4031            hash = typeSerializer.normalize(type, hash, prop);
 4032
 4033            var isFirstCreatedRecord = isPrimary && !recordId && !primaryRecord;
 4034            var isUpdatedRecord = isPrimary && coerceId(hash.id) === recordId;
 4035
 4036            // find the primary record.
 4037            //
 4038            // It's either:
 4039            // * the record with the same ID as the original request
 4040            // * in the case of a newly created record that didn't have an ID, the first
 4041            //   record in the Array
 4042            if (isFirstCreatedRecord || isUpdatedRecord) {
 4043              primaryRecord = hash;
 4044            } else {
 4045              store.push(typeName, hash);
 4046            }
 4047          }, this);
 4048        }
 4049
 4050        return primaryRecord;
 4051      },
 4052
 4053      /**
 4054        Called when the server has returned a payload representing
 4055        multiple records, such as in response to a `findAll` or `findQuery`.
 4056
 4057        It is your opportunity to clean up the server's response into the normalized
 4058        form expected by Ember Data.
 4059
 4060        If you want, you can just restructure the top-level of your payload, and
 4061        do more fine-grained normalization in the `normalize` method.
 4062
 4063        For example, if you have a payload like this in response to a request for
 4064        all posts:
 4065
 4066        ```js
 4067        {
 4068          "_embedded": {
 4069            "post": [{
 4070              "id": 1,
 4071              "title": "Rails is omakase"
 4072            }, {
 4073              "id": 2,
 4074              "title": "The Parley Letter"
 4075            }],
 4076            "comment": [{
 4077              "_id": 1,
 4078              "comment_title": "Rails is unagi"
 4079              "post_id": 1
 4080            }, {
 4081              "_id": 2,
 4082              "comment_title": "Don't tread on me",
 4083              "post_id": 2
 4084            }]
 4085          }
 4086        }
 4087        ```
 4088
 4089        You could implement a serializer that looks like this to get your payload
 4090        into shape:
 4091
 4092        ```js
 4093        App.PostSerializer = DS.RESTSerializer.extend({
 4094          // First, restructure the top-level so it's organized by type
 4095          // and the comments are listed under a post's `comments` key.
 4096          extractArray: function(store, type, payload) {
 4097            var posts = payload._embedded.post;
 4098            var comments = [];
 4099            var postCache = {};
 4100
 4101            posts.forEach(function(post) {
 4102              post.comments = [];
 4103              postCache[post.id] = post;
 4104            });
 4105
 4106            payload._embedded.comment.forEach(function(comment) {
 4107              comments.push(comment);
 4108              postCache[comment.post_id].comments.push(comment);
 4109              delete comment.post_id;
 4110            });
 4111
 4112            payload = { comments: comments, posts: payload };
 4113
 4114            return this._super(store, type, payload);
 4115          },
 4116
 4117          normalizeHash: {
 4118            // Next, normalize individual comments, which (after `extract`)
 4119            // are now located under `comments`
 4120            comments: function(hash) {
 4121              hash.id = hash._id;
 4122              hash.title = hash.comment_title;
 4123              delete hash._id;
 4124              delete hash.comment_title;
 4125              return hash;
 4126            }
 4127          }
 4128        })
 4129        ```
 4130
 4131        When you call super from your own implementation of `extractArray`, the
 4132        built-in implementation will find the primary array in your normalized
 4133        payload and push the remaining records into the store.
 4134
 4135        The primary array is the array found under `posts`.
 4136
 4137        The primary record has special meaning when responding to `findQuery`
 4138        or `findHasMany`. In particular, the primary array will become the
 4139        list of records in the record array that kicked off the request.
 4140
 4141        If your primary array contains secondary (embedded) records of the same type,
 4142        you cannot place these into the primary array `posts`. Instead, place the
 4143        secondary items into an underscore prefixed property `_posts`, which will
 4144        push these items into the store and will not affect the resulting query.
 4145
 4146        @method extractArray
 4147        @param {DS.Store} store
 4148        @param {subclass of DS.Model} primaryType
 4149        @param {Object} payload
 4150        @return {Array} The primary array that was returned in response
 4151          to the original query.
 4152      */
 4153      extractArray: function(store, primaryType, rawPayload) {
 4154        var payload = this.normalizePayload(rawPayload);
 4155        var primaryTypeName = primaryType.typeKey;
 4156        var primaryArray;
 4157
 4158        for (var prop in payload) {
 4159          var typeKey = prop;
 4160          var forcedSecondary = false;
 4161
 4162          if (prop.charAt(0) === '_') {
 4163            forcedSecondary = true;
 4164            typeKey = prop.substr(1);
 4165          }
 4166
 4167          var typeName = this.typeForRoot(typeKey);
 4168          if (!store.modelFactoryFor(typeName)) {
 4169            Ember.warn(this.warnMessageNoModelForKey(prop, typeName), false);
 4170            continue;
 4171          }
 4172          var type = store.modelFor(typeName);
 4173          var typeSerializer = store.serializerFor(type);
 4174          var isPrimary = (!forcedSecondary && (type.typeKey === primaryTypeName));
 4175
 4176          /*jshint loopfunc:true*/
 4177          var normalizedArray = map.call(payload[prop], function(hash) {
 4178            return typeSerializer.normalize(type, hash, prop);
 4179          }, this);
 4180
 4181          if (isPrimary) {
 4182            primaryArray = normalizedArray;
 4183          } else {
 4184            store.pushMany(typeName, normalizedArray);
 4185          }
 4186        }
 4187
 4188        return primaryArray;
 4189      },
 4190
 4191      /**
 4192        This method allows you to push a payload containing top-level
 4193        collections of records organized per type.
 4194
 4195        ```js
 4196        {
 4197          "posts": [{
 4198            "id": "1",
 4199            "title": "Rails is omakase",
 4200            "author", "1",
 4201            "comments": [ "1" ]
 4202          }],
 4203          "comments": [{
 4204            "id": "1",
 4205            "body": "FIRST"
 4206          }],
 4207          "users": [{
 4208            "id": "1",
 4209            "name": "@d2h"
 4210          }]
 4211        }
 4212        ```
 4213
 4214        It will first normalize the payload, so you can use this to push
 4215        in data streaming in from your server structured the same way
 4216        that fetches and saves are structured.
 4217
 4218        @method pushPayload
 4219        @param {DS.Store} store
 4220        @param {Object} payload
 4221      */
 4222      pushPayload: function(store, rawPayload) {
 4223        var payload = this.normalizePayload(rawPayload);
 4224
 4225        for (var prop in payload) {
 4226          var typeName = this.typeForRoot(prop);
 4227          if (!store.modelFactoryFor(typeName, prop)){
 4228            Ember.warn(this.warnMessageNoModelForKey(prop, typeName), false);
 4229            continue;
 4230          }
 4231          var type = store.modelFor(typeName);
 4232          var typeSerializer = store.serializerFor(type);
 4233
 4234          /*jshint loopfunc:true*/
 4235          var normalizedArray = map.call(Ember.makeArray(payload[prop]), function(hash) {
 4236            return typeSerializer.normalize(type, hash, prop);
 4237          }, this);
 4238
 4239          store.pushMany(typeName, normalizedArray);
 4240        }
 4241      },
 4242
 4243      /**
 4244        This method is used to convert each JSON root key in the payload
 4245        into a typeKey that it can use to look up the appropriate model for
 4246        that part of the payload. By default the typeKey for a model is its
 4247        name in camelCase, so if your JSON root key is 'fast-car' you would
 4248        use typeForRoot to convert it to 'fastCar' so that Ember Data finds
 4249        the `FastCar` model.
 4250
 4251        If you diverge from this norm you should also consider changes to
 4252        store._normalizeTypeKey as well.
 4253
 4254        For example, your server may return prefixed root keys like so:
 4255
 4256        ```js
 4257        {
 4258          "response-fast-car": {
 4259            "id": "1",
 4260            "name": "corvette"
 4261          }
 4262        }
 4263        ```
 4264
 4265        In order for Ember Data to know that the model corresponding to
 4266        the 'response-fast-car' hash is `FastCar` (typeKey: 'fastCar'),
 4267        you can override typeForRoot to convert 'response-fast-car' to
 4268        'fastCar' like so:
 4269
 4270        ```js
 4271        App.ApplicationSerializer = DS.RESTSerializer.extend({
 4272          typeForRoot: function(root) {
 4273            // 'response-fast-car' should become 'fast-car'
 4274            var subRoot = root.substring(9);
 4275
 4276            // _super normalizes 'fast-car' to 'fastCar'
 4277            return this._super(subRoot);
 4278          }
 4279        });
 4280        ```
 4281
 4282        @method typeForRoot
 4283        @param {String} key
 4284        @return {String} the model's typeKey
 4285      */
 4286      typeForRoot: function(key) {
 4287        return camelize(singularize(key));
 4288      },
 4289
 4290      // SERIALIZE
 4291
 4292      /**
 4293        Called when a record is saved in order to convert the
 4294        record into JSON.
 4295
 4296        By default, it creates a JSON object with a key for
 4297        each attribute and belongsTo relationship.
 4298
 4299        For example, consider this model:
 4300
 4301        ```js
 4302        App.Comment = DS.Model.extend({
 4303          title: DS.attr(),
 4304          body: DS.attr(),
 4305
 4306          author: DS.belongsTo('user')
 4307        });
 4308        ```
 4309
 4310        The default serialization would create a JSON object like:
 4311
 4312        ```js
 4313        {
 4314          "title": "Rails is unagi",
 4315          "body": "Rails? Omakase? O_O",
 4316          "author": 12
 4317        }
 4318        ```
 4319
 4320        By default, attributes are passed through as-is, unless
 4321        you specified an attribute type (`DS.attr('date')`). If
 4322        you specify a transform, the JavaScript value will be
 4323        serialized when inserted into the JSON hash.
 4324
 4325        By default, belongs-to relationships are converted into
 4326        IDs when inserted into the JSON hash.
 4327
 4328        ## IDs
 4329
 4330        `serialize` takes an options hash with a single option:
 4331        `includeId`. If this option is `true`, `serialize` will,
 4332        by default include the ID in the JSON object it builds.
 4333
 4334        The adapter passes in `includeId: true` when serializing
 4335        a record for `createRecord`, but not for `updateRecord`.
 4336
 4337        ## Customization
 4338
 4339        Your server may expect a different JSON format than the
 4340        built-in serialization format.
 4341
 4342        In that case, you can implement `serialize` yourself and
 4343        return a JSON hash of your choosing.
 4344
 4345        ```js
 4346        App.PostSerializer = DS.RESTSerializer.extend({
 4347          serialize: function(post, options) {
 4348            var json = {
 4349              POST_TTL: post.get('title'),
 4350              POST_BDY: post.get('body'),
 4351              POST_CMS: post.get('comments').mapBy('id')
 4352            }
 4353
 4354            if (options.includeId) {
 4355              json.POST_ID_ = post.get('id');
 4356            }
 4357
 4358            return json;
 4359          }
 4360        });
 4361        ```
 4362
 4363        ## Customizing an App-Wide Serializer
 4364
 4365        If you want to define a serializer for your entire
 4366        application, you'll probably want to use `eachAttribute`
 4367        and `eachRelationship` on the record.
 4368
 4369        ```js
 4370        App.ApplicationSerializer = DS.RESTSerializer.extend({
 4371          serialize: function(record, options) {
 4372            var json = {};
 4373
 4374            record.eachAttribute(function(name) {
 4375              json[serverAttributeName(name)] = record.get(name);
 4376            })
 4377
 4378            record.eachRelationship(function(name, relationship) {
 4379              if (relationship.kind === 'hasMany') {
 4380                json[serverHasManyName(name)] = record.get(name).mapBy('id');
 4381              }
 4382            });
 4383
 4384            if (options.includeId) {
 4385              json.ID_ = record.get('id');
 4386            }
 4387
 4388            return json;
 4389          }
 4390        });
 4391
 4392        function serverAttributeName(attribute) {
 4393          return attribute.underscore().toUpperCase();
 4394        }
 4395
 4396        function serverHasManyName(name) {
 4397          return serverAttributeName(name.singularize()) + "_IDS";
 4398        }
 4399        ```
 4400
 4401        This serializer will generate JSON that looks like this:
 4402
 4403        ```js
 4404        {
 4405          "TITLE": "Rails is omakase",
 4406          "BODY": "Yep. Omakase.",
 4407          "COMMENT_IDS": [ 1, 2, 3 ]
 4408        }
 4409        ```
 4410
 4411        ## Tweaking the Default JSON
 4412
 4413        If you just want to do some small tweaks on the default JSON,
 4414        you can call super first and make the tweaks on the returned
 4415        JSON.
 4416
 4417        ```js
 4418        App.PostSerializer = DS.RESTSerializer.extend({
 4419          serialize: function(record, options) {
 4420            var json = this._super(record, options);
 4421
 4422            json.subject = json.title;
 4423            delete json.title;
 4424
 4425            return json;
 4426          }
 4427        });
 4428        ```
 4429
 4430        @method serialize
 4431        @param {subclass of DS.Model} record
 4432        @param {Object} options
 4433        @return {Object} json
 4434      */
 4435      serialize: function(record, options) {
 4436        return this._super.apply(this, arguments);
 4437      },
 4438
 4439      /**
 4440        You can use this method to customize the root keys serialized into the JSON.
 4441        By default the REST Serializer sends the typeKey of a model, which is a camelized
 4442        version of the name.
 4443
 4444        For example, your server may expect underscored root objects.
 4445
 4446        ```js
 4447        App.ApplicationSerializer = DS.RESTSerializer.extend({
 4448          serializeIntoHash: function(data, type, record, options) {
 4449            var root = Ember.String.decamelize(type.typeKey);
 4450            data[root] = this.serialize(record, options);
 4451          }
 4452        });
 4453        ```
 4454
 4455        @method serializeIntoHash
 4456        @param {Object} hash
 4457        @param {subclass of DS.Model} type
 4458        @param {DS.Model} record
 4459        @param {Object} options
 4460      */
 4461      serializeIntoHash: function(hash, type, record, options) {
 4462        hash[type.typeKey] = this.serialize(record, options);
 4463      },
 4464
 4465      /**
 4466        You can use this method to customize how polymorphic objects are serialized.
 4467        By default the JSON Serializer creates the key by appending `Type` to
 4468        the attribute and value from the model's camelcased model name.
 4469
 4470        @method serializePolymorphicType
 4471        @param {DS.Model} record
 4472        @param {Object} json
 4473        @param {Object} relationship
 4474      */
 4475      serializePolymorphicType: function(record, json, relationship) {
 4476        var key = relationship.key;
 4477        var belongsTo = get(record, key);
 4478        key = this.keyForAttribute ? this.keyForAttribute(key) : key;
 4479        if (Ember.isNone(belongsTo)) {
 4480          json[key + "Type"] = null;
 4481        } else {
 4482          json[key + "Type"] = Ember.String.camelize(belongsTo.constructor.typeKey);
 4483        }
 4484      }
 4485    });
 4486
 4487    Ember.runInDebug(function(){
 4488      RESTSerializer.reopen({
 4489        warnMessageNoModelForKey: function(prop, typeKey){
 4490          return 'Encountered "' + prop + '" in payload, but no model was found for model name "' + typeKey + '" (resolved model name using ' + this.constructor.toString() + '.typeForRoot("' + prop + '"))';
 4491        }
 4492      });
 4493    });
 4494
 4495    __exports__["default"] = RESTSerializer;
 4496  });
 4497define("ember-data/setup-container",
 4498  ["ember-data/initializers/store","ember-data/initializers/transforms","ember-data/initializers/store_injections","ember-data/initializers/data_adapter","activemodel-adapter/setup-container","exports"],
 4499  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
 4500    "use strict";
 4501    var initializeStore = __dependency1__["default"];
 4502    var initializeTransforms = __dependency2__["default"];
 4503    var initializeStoreInjections = __dependency3__["default"];
 4504    var initializeDataAdapter = __dependency4__["default"];
 4505    var setupActiveModelContainer = __dependency5__["default"];
 4506
 4507    __exports__["default"] = function setupContainer(container, application){
 4508      // application is not a required argument. This ensures
 4509      // testing setups can setup a container without booting an
 4510      // entire ember application.
 4511
 4512      initializeDataAdapter(container, application);
 4513      initializeTransforms(container, application);
 4514      initializeStoreInjections(container, application);
 4515      initializeStore(container, application);
 4516      setupActiveModelContainer(container, application);
 4517    };
 4518  });
 4519define("ember-data/system/adapter",
 4520  ["exports"],
 4521  function(__exports__) {
 4522    "use strict";
 4523    /**
 4524      @module ember-data
 4525    */
 4526
 4527    var get = Ember.get;
 4528
 4529    var errorProps = [
 4530      'description',
 4531      'fileName',
 4532      'lineNumber',
 4533      'message',
 4534      'name',
 4535      'number',
 4536      'stack'
 4537    ];
 4538
 4539    /**
 4540      A `DS.InvalidError` is used by an adapter to signal the external API
 4541      was unable to process a request because the content was not
 4542      semantically correct or meaningful per the API. Usually this means a
 4543      record failed some form of server side validation. When a promise
 4544      from an adapter is rejected with a `DS.InvalidError` the record will
 4545      transition to the `invalid` state and the errors will be set to the
 4546      `errors` property on the record.
 4547
 4548      Example
 4549
 4550      ```javascript
 4551      App.ApplicationAdapter = DS.RESTAdapter.extend({
 4552        ajaxError: function(jqXHR) {
 4553          var error = this._super(jqXHR);
 4554
 4555          if (jqXHR && jqXHR.status === 422) {
 4556            var jsonErrors = Ember.$.parseJSON(jqXHR.responseText)["errors"];
 4557            return new DS.InvalidError(jsonErrors);
 4558          } else {
 4559            return error;
 4560          }
 4561        }
 4562      });
 4563      ```
 4564
 4565      The `DS.InvalidError` must be constructed with a single object whose
 4566      keys are the invalid model properties, and whose values are the
 4567      corresponding error messages. For example:
 4568
 4569      ```javascript
 4570      return new DS.InvalidError({
 4571        length: 'Must be less than 15',
 4572        name: 'Must not be blank
 4573      });
 4574      ```
 4575
 4576      @class InvalidError
 4577      @namespace DS
 4578    */
 4579    function InvalidError(errors) {
 4580      var tmp = Error.prototype.constructor.call(this, "The backend rejected the commit because it was invalid: " + Ember.inspect(errors));
 4581      this.errors = errors;
 4582
 4583      for (var i=0, l=errorProps.length; i<l; i++) {
 4584        this[errorProps[i]] = tmp[errorProps[i]];
 4585      }
 4586    }
 4587
 4588    InvalidError.prototype = Ember.create(Error.prototype);
 4589
 4590    /**
 4591      An adapter is an object that receives requests from a store and
 4592      translates them into the appropriate action to take against your
 4593      persistence layer. The persistence layer is usually an HTTP API, but
 4594      may be anything, such as the browser's local storage. Typically the
 4595      adapter is not invoked directly instead its functionality is accessed
 4596      through the `store`.
 4597
 4598      ### Creating an Adapter
 4599
 4600      Create a new subclass of `DS.Adapter`, then assign
 4601      it to the `ApplicationAdapter` property of the application.
 4602
 4603      ```javascript
 4604      var MyAdapter = DS.Adapter.extend({
 4605        // ...your code here
 4606      });
 4607
 4608      App.ApplicationAdapter = MyAdapter;
 4609      ```
 4610
 4611      Model-specific adapters can be created by assigning your adapter
 4612      class to the `ModelName` + `Adapter` property of the application.
 4613
 4614      ```javascript
 4615      var MyPostAdapter = DS.Adapter.extend({
 4616        // ...Post-specific adapter code goes here
 4617      });
 4618
 4619      App.PostAdapter = MyPostAdapter;
 4620      ```
 4621
 4622      `DS.Adapter` is an abstract base class that you should override in your
 4623      application to customize it for your backend. The minimum set of methods
 4624      that you should implement is:
 4625
 4626        * `find()`
 4627        * `createRecord()`
 4628        * `updateRecord()`
 4629        * `deleteRecord()`
 4630        * `findAll()`
 4631        * `findQuery()`
 4632
 4633      To improve the network performance of your application, you can optimize
 4634      your adapter by overriding these lower-level methods:
 4635
 4636        * `findMany()`
 4637
 4638
 4639      For an example implementation, see `DS.RESTAdapter`, the
 4640      included REST adapter.
 4641
 4642      @class Adapter
 4643      @namespace DS
 4644      @extends Ember.Object
 4645    */
 4646
 4647    var Adapter = Ember.Object.extend({
 4648
 4649      /**
 4650        If you would like your adapter to use a custom serializer you can
 4651        set the `defaultSerializer` property to be the name of the custom
 4652        serializer.
 4653
 4654        Note the `defaultSerializer` serializer has a lower priority than
 4655        a model specific serializer (i.e. `PostSerializer`) or the
 4656        `application` serializer.
 4657
 4658        ```javascript
 4659        var DjangoAdapter = DS.Adapter.extend({
 4660          defaultSerializer: 'django'
 4661        });
 4662        ```
 4663
 4664        @property defaultSerializer
 4665        @type {String}
 4666      */
 4667
 4668      /**
 4669        The `find()` method is invoked when the store is asked for a record that
 4670        has not previously been loaded. In response to `find()` being called, you
 4671        should query your persistence layer for a record with the given ID. Once
 4672        found, you can asynchronously call the store's `push()` method to push
 4673        the record into the store.
 4674
 4675        Here is an example `find` implementation:
 4676
 4677        ```javascript
 4678        App.ApplicationAdapter = DS.Adapter.extend({
 4679          find: function(store, type, id) {
 4680            var url = [type.typeKey, id].join('/');
 4681
 4682            return new Ember.RSVP.Promise(function(resolve, reject) {
 4683              jQuery.getJSON(url).then(function(data) {
 4684                Ember.run(null, resolve, data);
 4685              }, function(jqXHR) {
 4686                jqXHR.then = null; // tame jQuery's ill mannered promises
 4687                Ember.run(null, reject, jqXHR);
 4688              });
 4689            });
 4690          }
 4691        });
 4692        ```
 4693
 4694        @method find
 4695        @param {DS.Store} store
 4696        @param {subclass of DS.Model} type
 4697        @param {String} id
 4698        @return {Promise} promise
 4699      */
 4700      find: Ember.required(Function),
 4701
 4702      /**
 4703        The `findAll()` method is called when you call `find` on the store
 4704        without an ID (i.e. `store.find('post')`).
 4705
 4706        Example
 4707
 4708        ```javascript
 4709        App.ApplicationAdapter = DS.Adapter.extend({
 4710          findAll: function(store, type, sinceToken) {
 4711            var url = type;
 4712            var query = { since: sinceToken };
 4713            return new Ember.RSVP.Promise(function(resolve, reject) {
 4714              jQuery.getJSON(url, query).then(function(data) {
 4715                Ember.run(null, resolve, data);
 4716              }, function(jqXHR) {
 4717                jqXHR.then = null; // tame jQuery's ill mannered promises
 4718                Ember.run(null, reject, jqXHR);
 4719              });
 4720            });
 4721          }
 4722        });
 4723        ```
 4724
 4725        @private
 4726        @method findAll
 4727        @param {DS.Store} store
 4728        @param {subclass of DS.Model} type
 4729        @param {String} sinceToken
 4730        @return {Promise} promise
 4731      */
 4732      findAll: null,
 4733
 4734      /**
 4735        This method is called when you call `find` on the store with a
 4736        query object as the second parameter (i.e. `store.find('person', {
 4737        page: 1 })`).
 4738
 4739        Example
 4740
 4741        ```javascript
 4742        App.ApplicationAdapter = DS.Adapter.extend({
 4743          findQuery: function(store, type, query) {
 4744            var url = type;
 4745            return new Ember.RSVP.Promise(function(resolve, reject) {
 4746              jQuery.getJSON(url, query).then(function(data) {
 4747                Ember.run(null, resolve, data);
 4748              }, function(jqXHR) {
 4749                jqXHR.then = null; // tame jQuery's ill mannered promises
 4750                Ember.run(null, reject, jqXHR);
 4751              });
 4752            });
 4753          }
 4754        });
 4755        ```
 4756
 4757        @private
 4758        @method findQuery
 4759        @param {DS.Store} store
 4760        @param {subclass of DS.Model} type
 4761        @param {Object} query
 4762        @param {DS.AdapterPopulatedRecordArray} recordArray
 4763        @return {Promise} promise
 4764      */
 4765      findQuery: null,
 4766
 4767      /**
 4768        If the globally unique IDs for your records should be generated on the client,
 4769        implement the `generateIdForRecord()` method. This method will be invoked
 4770        each time you create a new record, and the value returned from it will be
 4771        assigned to the record's `primaryKey`.
 4772
 4773        Most traditional REST-like HTTP APIs will not use this method. Instead, the ID
 4774        of the record will be set by the server, and your adapter will update the store
 4775        with the new ID when it calls `didCreateRecord()`. Only implement this method if
 4776        you intend to generate record IDs on the client-side.
 4777
 4778        The `generateIdForRecord()` method will be invoked with the requesting store as
 4779        the first parameter and the newly created record as the second parameter:
 4780
 4781        ```javascript
 4782        generateIdForRecord: function(store, record) {
 4783          var uuid = App.generateUUIDWithStatisticallyLowOddsOfCollision();
 4784          return uuid;
 4785        }
 4786        ```
 4787
 4788        @method generateIdForRecord
 4789        @param {DS.Store} store
 4790        @param {DS.Model} record
 4791        @return {String|Number} id
 4792      */
 4793      generateIdForRecord: null,
 4794
 4795      /**
 4796        Proxies to the serializer's `serialize` method.
 4797
 4798        Example
 4799
 4800        ```javascript
 4801        App.ApplicationAdapter = DS.Adapter.extend({
 4802          createRecord: function(store, type, record) {
 4803            var data = this.serialize(record, { includeId: true });
 4804            var url = type;
 4805
 4806            // ...
 4807          }
 4808        });
 4809        ```
 4810
 4811        @method serialize
 4812        @param {DS.Model} record
 4813        @param {Object}   options
 4814        @return {Object} serialized record
 4815      */
 4816      serialize: function(record, options) {
 4817        return get(record, 'store').serializerFor(record.constructor.typeKey).serialize(record, options);
 4818      },
 4819
 4820      /**
 4821        Implement this method in a subclass to handle the creation of
 4822        new records.
 4823
 4824        Serializes the record and send it to the server.
 4825
 4826        Example
 4827
 4828        ```javascript
 4829        App.ApplicationAdapter = DS.Adapter.extend({
 4830          createRecord: function(store, type, record) {
 4831            var data = this.serialize(record, { includeId: true });
 4832            var url = type;
 4833
 4834            return new Ember.RSVP.Promise(function(resolve, reject) {
 4835              jQuery.ajax({
 4836                type: 'POST',
 4837                url: url,
 4838                dataType: 'json',
 4839                data: data
 4840              }).then(function(data) {
 4841                Ember.run(null, resolve, data);
 4842              }, function(jqXHR) {
 4843                jqXHR.then = null; // tame jQuery's ill mannered promises
 4844                Ember.run(null, reject, jqXHR);
 4845              });
 4846            });
 4847          }
 4848        });
 4849        ```
 4850
 4851        @method createRecord
 4852        @param {DS.Store} store
 4853        @param {subclass of DS.Model} type   the DS.Model class of the record
 4854        @param {DS.Model} record
 4855        @return {Promise} promise
 4856      */
 4857      createRecord: Ember.required(Function),
 4858
 4859      /**
 4860        Implement this method in a subclass to handle the updating of
 4861        a record.
 4862
 4863        Serializes the record update and send it to the server.
 4864
 4865        Example
 4866
 4867        ```javascript
 4868        App.ApplicationAdapter = DS.Adapter.extend({
 4869          updateRecord: function(store, type, record) {
 4870            var data = this.serialize(record, { includeId: true });
 4871            var id = record.get('id');
 4872            var url = [type, id].join('/');
 4873
 4874            return new Ember.RSVP.Promise(function(resolve, reject) {
 4875              jQuery.ajax({
 4876                type: 'PUT',
 4877                url: url,
 4878                dataType: 'json',
 4879                data: data
 4880              }).then(function(data) {
 4881                Ember.run(null, resolve, data);
 4882              }, function(jqXHR) {
 4883                jqXHR.then = null; // tame jQuery's ill mannered promises
 4884                Ember.run(null, reject, jqXHR);
 4885              });
 4886            });
 4887          }
 4888        });
 4889        ```
 4890
 4891        @method updateRecord
 4892        @param {DS.Store} store
 4893        @param {subclass of DS.Model} type   the DS.Model class of the record
 4894        @param {DS.Model} record
 4895        @return {Promise} promise
 4896      */
 4897      updateRecord: Ember.required(Function),
 4898
 4899      /**
 4900        Implement this method in a subclass to handle the deletion of
 4901        a record.
 4902
 4903        Sends a delete request for the record to the server.
 4904
 4905        Example
 4906
 4907        ```javascript
 4908        App.ApplicationAdapter = DS.Adapter.extend({
 4909          deleteRecord: function(store, type, record) {
 4910            var data = this.serialize(record, { includeId: true });
 4911            var id = record.get('id');
 4912            var url = [type, id].join('/');
 4913
 4914            return new Ember.RSVP.Promise(function(resolve, reject) {
 4915              jQuery.ajax({
 4916                type: 'DELETE',
 4917                url: url,
 4918                dataType: 'json',
 4919                data: data
 4920              }).then(function(data) {
 4921                Ember.run(null, resolve, data);
 4922              }, function(jqXHR) {
 4923                jqXHR.then = null; // tame jQuery's ill mannered promises
 4924                Ember.run(null, reject, jqXHR);
 4925              });
 4926            });
 4927          }
 4928        });
 4929        ```
 4930
 4931        @method deleteRecord
 4932        @param {DS.Store} store
 4933        @param {subclass of DS.Model} type   the DS.Model class of the record
 4934        @param {DS.Model} record
 4935        @return {Promise} promise
 4936      */
 4937      deleteRecord: Ember.required(Function),
 4938
 4939      /**
 4940        By default the store will try to coalesce all `fetchRecord` calls within the same runloop
 4941        into as few requests as possible by calling groupRecordsForFindMany and passing it into a findMany call.
 4942        You can opt out of this behaviour by either not implementing the findMany hook or by setting
 4943        coalesceFindRequests to false
 4944
 4945        @property coalesceFindRequests
 4946        @type {boolean}
 4947      */
 4948      coalesceFindRequests: true,
 4949
 4950      /**
 4951        Find multiple records at once if coalesceFindRequests is true
 4952
 4953        @method findMany
 4954        @param {DS.Store} store
 4955        @param {subclass of DS.Model} type   the DS.Model class of the records
 4956        @param {Array}    ids
 4957        @param {Array} records
 4958        @return {Promise} promise
 4959      */
 4960
 4961      /**
 4962        Organize records into groups, each of which is to be passed to separate
 4963        calls to `findMany`.
 4964
 4965        For example, if your api has nested URLs that depend on the parent, you will
 4966        want to group records by their parent.
 4967
 4968        The default implementation returns the records as a single group.
 4969
 4970        @method groupRecordsForFindMany
 4971        @param {Array} records
 4972        @return {Array}  an array of arrays of records, each of which is to be
 4973                          loaded separately by `findMany`.
 4974      */
 4975      groupRecordsForFindMany: function (store, records) {
 4976        return [records];
 4977      }
 4978    });
 4979
 4980    __exports__.InvalidError = InvalidError;
 4981    __exports__.Adapter = Adapter;
 4982    __exports__["default"] = Adapter;
 4983  });
 4984define("ember-data/system/container_proxy",
 4985  ["exports"],
 4986  function(__exports__) {
 4987    "use strict";
 4988    /**
 4989      This is used internally to enable deprecation of container paths and provide
 4990      a decent message to the user indicating how to fix the issue.
 4991
 4992      @class ContainerProxy
 4993      @namespace DS
 4994      @private
 4995    */
 4996    function ContainerProxy(container){
 4997      this.container = container;
 4998    }
 4999
 5000    ContainerProxy.prototype.aliasedFactory = function(path, preLookup) {
 5001      var _this = this;
 5002
 5003      return {create: function(){
 5004        if (preLookup) { preLookup(); }
 5005
 5006        return _this.container.lookup(path);
 5007      }};
 5008    };
 5009
 5010    ContainerProxy.prototype.registerAlias = function(source, dest, preLookup) {
 5011      var factory = this.aliasedFactory(dest, preLookup);
 5012
 5013      return this.container.register(source, factory);
 5014    };
 5015
 5016    ContainerProxy.prototype.registerDeprecation = function(deprecated, valid) {
 5017      var preLookupCallback = function(){
 5018        Ember.deprecate("You tried to look up '" + deprecated + "', " +
 5019                        "but this has been deprecated in favor of '" + valid + "'.", false);
 5020      };
 5021
 5022      return this.registerAlias(deprecated, valid, preLookupCallback);
 5023    };
 5024
 5025    ContainerProxy.prototype.registerDeprecations = function(proxyPairs) {
 5026      var i, proxyPair, deprecated, valid;
 5027
 5028      for (i = proxyPairs.length; i > 0; i--) {
 5029        proxyPair = proxyPairs[i - 1];
 5030        deprecated = proxyPair['deprecated'];
 5031        valid = proxyPair['valid'];
 5032
 5033        this.registerDeprecation(deprecated, valid);
 5034      }
 5035    };
 5036
 5037    __exports__["default"] = ContainerProxy;
 5038  });
 5039define("ember-data/system/debug",
 5040  ["ember-data/system/debug/debug_info","ember-data/system/debug/debug_adapter","exports"],
 5041  function(__dependency1__, __dependency2__, __exports__) {
 5042    "use strict";
 5043    /**
 5044      @module ember-data
 5045    */
 5046
 5047    var DebugAdapter = __dependency2__["default"];
 5048
 5049    __exports__["default"] = DebugAdapter;
 5050  });
 5051define("ember-data/system/debug/debug_adapter",
 5052  ["ember-data/system/model","exports"],
 5053  function(__dependency1__, __exports__) {
 5054    "use strict";
 5055    /**
 5056      @module ember-data
 5057    */
 5058    var Model = __dependency1__.Model;
 5059    var get = Ember.get;
 5060    var capitalize = Ember.String.capitalize;
 5061    var underscore = Ember.String.underscore;
 5062
 5063    /**
 5064      Extend `Ember.DataAdapter` with ED specific code.
 5065
 5066      @class DebugAdapter
 5067      @namespace DS
 5068      @extends Ember.DataAdapter
 5069      @private
 5070    */
 5071    __exports__["default"] = Ember.DataAdapter.extend({
 5072      getFilters: function() {
 5073        return [
 5074          { name: 'isNew', desc: 'New' },
 5075          { name: 'isModified', desc: 'Modified' },
 5076          { name: 'isClean', desc: 'Clean' }
 5077        ];
 5078      },
 5079
 5080      detect: function(klass) {
 5081        return klass !== Model && Model.detect(klass);
 5082      },
 5083
 5084      columnsForType: function(type) {
 5085        var columns = [{
 5086          name: 'id',
 5087          desc: 'Id'
 5088        }];
 5089        var count = 0;
 5090        var self = this;
 5091        get(type, 'attributes').forEach(function(meta, name) {
 5092            if (count++ > self.attributeLimit) { return false; }
 5093            var desc = capitalize(underscore(name).replace('_', ' '));
 5094            columns.push({ name: name, desc: desc });
 5095        });
 5096        return columns;
 5097      },
 5098
 5099      getRecords: function(type) {
 5100        return this.get('store').all(type);
 5101      },
 5102
 5103      getRecordColumnValues: function(record) {
 5104        var self = this, count = 0;
 5105        var columnValues = { id: get(record, 'id') };
 5106
 5107        record.eachAttribute(function(key) {
 5108          if (count++ > self.attributeLimit) {
 5109            return false;
 5110          }
 5111          var value = get(record, key);
 5112          columnValues[key] = value;
 5113        });
 5114        return columnValues;
 5115      },
 5116
 5117      getRecordKeywords: function(record) {
 5118        var keywords = [];
 5119        var keys = Ember.A(['id']);
 5120        record.eachAttribute(function(key) {
 5121          keys.push(key);
 5122        });
 5123        keys.forEach(function(key) {
 5124          keywords.push(get(record, key));
 5125        });
 5126        return keywords;
 5127      },
 5128
 5129      getRecordFilterValues: function(record) {
 5130        return {
 5131          isNew: record.get('isNew'),
 5132          isModified: record.get('isDirty') && !record.get('isNew'),
 5133          isClean: !record.get('isDirty')
 5134        };
 5135      },
 5136
 5137      getRecordColor: function(record) {
 5138        var color = 'black';
 5139        if (record.get('isNew')) {
 5140          color = 'green';
 5141        } else if (record.get('isDirty')) {
 5142          color = 'blue';
 5143        }
 5144        return color;
 5145      },
 5146
 5147      observeRecord: function(record, recordUpdated) {
 5148        var releaseMethods = Ember.A(), self = this;
 5149        var keysToObserve = Ember.A(['id', 'isNew', 'isDirty']);
 5150
 5151        record.eachAttribute(function(key) {
 5152          keysToObserve.push(key);
 5153        });
 5154
 5155        keysToObserve.forEach(function(key) {
 5156          var handler = function() {
 5157            recordUpdated(self.wrapRecord(record));
 5158          };
 5159          Ember.addObserver(record, key, handler);
 5160          releaseMethods.push(function() {
 5161            Ember.removeObserver(record, key, handler);
 5162          });
 5163        });
 5164
 5165        var release = function() {
 5166          releaseMethods.forEach(function(fn) { fn(); } );
 5167        };
 5168
 5169        return release;
 5170      }
 5171
 5172    });
 5173  });
 5174define("ember-data/system/debug/debug_info",
 5175  ["ember-data/system/model","exports"],
 5176  function(__dependency1__, __exports__) {
 5177    "use strict";
 5178    var Model = __dependency1__.Model;
 5179
 5180    Model.reopen({
 5181
 5182      /**
 5183        Provides info about the model for debugging purposes
 5184        by grouping the properties into more semantic groups.
 5185
 5186        Meant to be used by debugging tools such as the Chrome Ember Extension.
 5187
 5188        - Groups all attributes in "Attributes" group.
 5189        - Groups all belongsTo relationships in "Belongs To" group.
 5190        - Groups all hasMany relationships in "Has Many" group.
 5191        - Groups all flags in "Flags" group.
 5192        - Flags relationship CPs as expensive properties.
 5193
 5194        @method _debugInfo
 5195        @for DS.Model
 5196        @private
 5197      */
 5198      _debugInfo: function() {
 5199        var attributes = ['id'],
 5200            relationships = { belongsTo: [], hasMany: [] },
 5201            expensiveProperties = [];
 5202
 5203        this.eachAttribute(function(name, meta) {
 5204          attributes.push(name);
 5205        }, this);
 5206
 5207        this.eachRelationship(function(name, relationship) {
 5208          relationships[relationship.kind].push(name);
 5209          expensiveProperties.push(name);
 5210        });
 5211
 5212        var groups = [
 5213          {
 5214            name: 'Attributes',
 5215            properties: attributes,
 5216            expand: true
 5217          },
 5218          {
 5219            name: 'Belongs To',
 5220            properties: relationships.belongsTo,
 5221            expand: true
 5222          },
 5223          {
 5224            name: 'Has Many',
 5225            properties: relationships.hasMany,
 5226            expand: true
 5227          },
 5228          {
 5229            name: 'Flags',
 5230            properties: ['isLoaded', 'isDirty', 'isSaving', 'isDeleted', 'isError', 'isNew', 'isValid']
 5231          }
 5232        ];
 5233
 5234        return {
 5235          propertyInfo: {
 5236            // include all other mixins / properties (not just the grouped ones)
 5237            includeOtherProperties: true,
 5238            groups: groups,
 5239            // don't pre-calculate unless cached
 5240            expensiveProperties: expensiveProperties
 5241          }
 5242        };
 5243      }
 5244    });
 5245
 5246    __exports__["default"] = Model;
 5247  });
 5248define("ember-data/system/map",
 5249  ["exports"],
 5250  function(__exports__) {
 5251    "use strict";
 5252    /**
 5253     * Polyfill Ember.Map behavior for Ember <= 1.7
 5254     * This can probably be removed before 1.0 final
 5255    */
 5256    var mapForEach, deleteFn;
 5257
 5258    function OrderedSet(){
 5259      Ember.OrderedSet.apply(this, arguments);
 5260    }
 5261
 5262    function Map() {
 5263      Ember.Map.apply(this, arguments);
 5264    }
 5265
 5266    function MapWithDefault(){
 5267      Ember.MapWithDefault.apply(this, arguments);
 5268    }
 5269
 5270    var testMap = Ember.Map.create();
 5271    testMap.set('key', 'value');
 5272
 5273    var usesOldBehavior = false;
 5274
 5275    testMap.forEach(function(value, key){
 5276      usesOldBehavior = value === 'key' && key === 'value';
 5277    });
 5278
 5279    Map.prototype            = Object.create(Ember.Map.prototype);
 5280    MapWithDefault.prototype = Object.create(Ember.MapWithDefault.prototype);
 5281    OrderedSet.prototype     = Object.create(Ember.OrderedSet.prototype);
 5282
 5283    OrderedSet.create = function(){
 5284      return new OrderedSet();
 5285    };
 5286
 5287    /**
 5288     * returns a function that calls the original
 5289     * callback function in the correct order.
 5290     * if we are in pre-Ember.1.8 land, Map/MapWithDefault
 5291     * forEach calls with key, value, in that order.
 5292     * >= 1.8 forEach is called with the order value, key as per
 5293     * the ES6 spec.
 5294    */
 5295    function translate(valueKeyOrderedCallback){
 5296      return function(key, value){
 5297        valueKeyOrderedCallback.call(this, value, key);
 5298      };
 5299    }
 5300
 5301    // old, non ES6 compliant behavior
 5302    if (usesOldBehavior){
 5303      mapForEach = function(callback, thisArg){
 5304        this.__super$forEach(translate(callback), thisArg);
 5305      };
 5306
 5307      /* alias to remove */
 5308      deleteFn = function(thing){
 5309        this.remove(thing);
 5310      };
 5311
 5312      Map.prototype.__super$forEach = Ember.Map.prototype.forEach;
 5313      Map.prototype.forEach = mapForEach;
 5314      Map.prototype["delete"] = deleteFn;
 5315
 5316      MapWithDefault.prototype.forEach = mapForEach;
 5317      MapWithDefault.prototype.__super$forEach = Ember.MapWithDefault.prototype.forEach;
 5318      MapWithDefault.prototype["delete"] = deleteFn;
 5319
 5320      OrderedSet.prototype["delete"] = deleteFn;
 5321    }
 5322
 5323    MapWithDefault.constructor = MapWithDefault;
 5324    Map.constructor = Map;
 5325
 5326    MapWithDefault.create = function(options){
 5327      if (options) {
 5328        return new MapWithDefault(options);
 5329      } else {
 5330        return new Map();
 5331      }
 5332    };
 5333
 5334    Map.create = function(){
 5335      return new this.constructor();
 5336    };
 5337
 5338    __exports__["default"] = Map;
 5339    __exports__.Map = Map;
 5340    __exports__.MapWithDefault = MapWithDefault;
 5341    __exports__.OrderedSet = OrderedSet;
 5342  });
 5343define("ember-data/system/model",
 5344  ["ember-data/system/model/model","ember-data/system/model/attributes","ember-data/system/model/states","ember-data/system/model/errors","exports"],
 5345  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
 5346    "use strict";
 5347    /**
 5348      @module ember-data
 5349    */
 5350
 5351    var Model = __dependency1__["default"];
 5352    var attr = __dependency2__["default"];
 5353    var RootState = __dependency3__["default"];
 5354    var Errors = __dependency4__["default"];
 5355
 5356    __exports__.Model = Model;
 5357    __exports__.RootState = RootState;
 5358    __exports__.attr = attr;
 5359    __exports__.Errors = Errors;
 5360  });
 5361define("ember-data/system/model/attributes",
 5362  ["ember-data/system/model/model","ember-data/system/map","exports"],
 5363  function(__dependency1__, __dependency2__, __exports__) {
 5364    "use strict";
 5365    var Model = __dependency1__["default"];
 5366    var Map = __dependency2__.Map;
 5367
 5368    /**
 5369      @module ember-data
 5370    */
 5371
 5372    var get = Ember.get;
 5373
 5374    /**
 5375      @class Model
 5376      @namespace DS
 5377    */
 5378    Model.reopenClass({
 5379      /**
 5380        A map whose keys are the attributes of the model (properties
 5381        described by DS.attr) and whose values are the meta object for the
 5382        property.
 5383
 5384        Example
 5385
 5386        ```javascript
 5387
 5388        App.Person = DS.Model.extend({
 5389          firstName: attr('string'),
 5390          lastName: attr('string'),
 5391          birthday: attr('date')
 5392        });
 5393
 5394        var attributes = Ember.get(App.Person, 'attributes')
 5395
 5396        attributes.forEach(function(name, meta) {
 5397          console.log(name, meta);
 5398        });
 5399
 5400        // prints:
 5401        // firstName {type: "string", isAttribute: true, options: Object, parentType: function, name: "firstName"}
 5402        // lastName {type: "string", isAttribute: true, options: Object, parentType: function, name: "lastName"}
 5403        // birthday {type: "date", isAttribute: true, options: Object, parentType: function, name: "birthday"}
 5404        ```
 5405
 5406        @property attributes
 5407        @static
 5408        @type {Ember.Map}
 5409        @readOnly
 5410      */
 5411      attributes: Ember.computed(function() {
 5412        var map = Map.create();
 5413
 5414        this.eachComputedProperty(function(name, meta) {
 5415          if (meta.isAttribute) {
 5416            Ember.assert("You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: DS.attr('<type>')` from " + this.toString(), name !== 'id');
 5417
 5418            meta.name = name;
 5419            map.set(name, meta);
 5420          }
 5421        });
 5422
 5423        return map;
 5424      }).readOnly(),
 5425
 5426      /**
 5427        A map whose keys are the attributes of the model (properties
 5428        described by DS.attr) and whose values are type of transformation
 5429        applied to each attribute. This map does not include any
 5430        attributes that do not have an transformation type.
 5431
 5432        Example
 5433
 5434        ```javascript
 5435        App.Person = DS.Model.extend({
 5436          firstName: attr(),
 5437          lastName: attr('string'),
 5438          birthday: attr('date')
 5439        });
 5440
 5441        var transformedAttributes = Ember.get(App.Person, 'transformedAttributes')
 5442
 5443        transformedAttributes.forEach(function(field, type) {
 5444          console.log(field, type);
 5445        });
 5446
 5447        // prints:
 5448        // lastName string
 5449        // birthday date
 5450        ```
 5451
 5452        @property transformedAttributes
 5453        @static
 5454        @type {Ember.Map}
 5455        @readOnly
 5456      */
 5457      transformedAttributes: Ember.computed(function() {
 5458        var map = Map.create();
 5459
 5460        this.eachAttribute(function(key, meta) {
 5461          if (meta.type) {
 5462            map.set(key, meta.type);
 5463          }
 5464        });
 5465
 5466        return map;
 5467      }).readOnly(),
 5468
 5469      /**
 5470        Iterates through the attributes of the model, calling the passed function on each
 5471        attribute.
 5472
 5473        The callback method you provide should have the following signature (all
 5474        parameters are optional):
 5475
 5476        ```javascript
 5477        function(name, meta);
 5478        ```
 5479
 5480        - `name` the name of the current property in the iteration
 5481        - `meta` the meta object for the attribute property in the iteration
 5482
 5483        Note that in addition to a callback, you can also pass an optional target
 5484        object that will be set as `this` on the context.
 5485
 5486        Example
 5487
 5488        ```javascript
 5489        App.Person = DS.Model.extend({
 5490          firstName: attr('string'),
 5491          lastName: attr('string'),
 5492          birthday: attr('date')
 5493        });
 5494
 5495        App.Person.eachAttribute(function(name, meta) {
 5496          console.log(name, meta);
 5497        });
 5498
 5499        // prints:
 5500        // firstName {type: "string", isAttribute: true, options: Object, parentType: function, name: "firstName"}
 5501        // lastName {type: "string", isAttribute: true, options: Object, parentType: function, name: "lastName"}
 5502        // birthday {type: "date", isAttribute: true, options: Object, parentType: function, name: "birthday"}
 5503       ```
 5504
 5505        @method eachAttribute
 5506        @param {Function} callback The callback to execute
 5507        @param {Object} [target] The target object to use
 5508        @static
 5509      */
 5510      eachAttribute: function(callback, binding) {
 5511        get(this, 'attributes').forEach(function(meta, name) {
 5512          callback.call(binding, name, meta);
 5513        }, binding);
 5514      },
 5515
 5516      /**
 5517        Iterates through the transformedAttributes of the model, calling
 5518        the passed function on each attribute. Note the callback will not be
 5519        called for any attributes that do not have an transformation type.
 5520
 5521        The callback method you provide should have the following signature (all
 5522        parameters are optional):
 5523
 5524        ```javascript
 5525        function(name, type);
 5526        ```
 5527
 5528        - `name` the name of the current property in the iteration
 5529        - `type` a string containing the name of the type of transformed
 5530          applied to the attribute
 5531
 5532        Note that in addition to a callback, you can also pass an optional target
 5533        object that will be set as `this` on the context.
 5534
 5535        Example
 5536
 5537        ```javascript
 5538        App.Person = DS.Model.extend({
 5539          firstName: attr(),
 5540          lastName: attr('string'),
 5541          birthday: attr('date')
 5542        });
 5543
 5544        App.Person.eachTransformedAttribute(function(name, type) {
 5545          console.log(name, type);
 5546        });
 5547
 5548        // prints:
 5549        // lastName string
 5550        // birthday date
 5551       ```
 5552
 5553        @method eachTransformedAttribute
 5554        @param {Function} callback The callback to execute
 5555        @param {Object} [target] The target object to use
 5556        @static
 5557      */
 5558      eachTransformedAttribute: function(callback, binding) {
 5559        get(this, 'transformedAttributes').forEach(function(type, name) {
 5560          callback.call(binding, name, type);
 5561        });
 5562      }
 5563    });
 5564
 5565
 5566    Model.reopen({
 5567      eachAttribute: function(callback, binding) {
 5568        this.constructor.eachAttribute(callback, binding);
 5569      }
 5570    });
 5571
 5572    function getDefaultValue(record, options, key) {
 5573      if (typeof options.defaultValue === "function") {
 5574        return options.defaultValue.apply(null, arguments);
 5575      } else {
 5576        return options.defaultValue;
 5577      }
 5578    }
 5579
 5580    function hasValue(record, key) {
 5581      return record._attributes.hasOwnProperty(key) ||
 5582             record._inFlightAttributes.hasOwnProperty(key) ||
 5583             record._data.hasOwnProperty(key);
 5584    }
 5585
 5586    function getValue(record, key) {
 5587      if (record._attributes.hasOwnProperty(key)) {
 5588        return record._attributes[key];
 5589      } else if (record._inFlightAttributes.hasOwnProperty(key)) {
 5590        return record._inFlightAttributes[key];
 5591      } else {
 5592        return record._data[key];
 5593      }
 5594    }
 5595
 5596    /**
 5597      `DS.attr` defines an attribute on a [DS.Model](/api/data/classes/DS.Model.html).
 5598      By default, attributes are passed through as-is, however you can specify an
 5599      optional type to have the value automatically transformed.
 5600      Ember Data ships with four basic transform types: `string`, `number`,
 5601      `boolean` and `date`. You can define your own transforms by subclassing
 5602      [DS.Transform](/api/data/classes/DS.Transform.html).
 5603
 5604      Note that you cannot use `attr` to define an attribute of `id`.
 5605
 5606      `DS.attr` takes an optional hash as a second parameter, currently
 5607      supported options are:
 5608
 5609      - `defaultValue`: Pass a string or a function to be called to set the attribute
 5610                        to a default value if none is supplied.
 5611
 5612      Example
 5613
 5614      ```javascript
 5615      var attr = DS.attr;
 5616
 5617      App.User = DS.Model.extend({
 5618        username: attr('string'),
 5619        email: attr('string'),
 5620        verified: attr('boolean', {defaultValue: false})
 5621      });
 5622      ```
 5623
 5624      @namespace
 5625      @method attr
 5626      @for DS
 5627      @param {String} type the attribute type
 5628      @param {Object} options a hash of options
 5629      @return {Attribute}
 5630    */
 5631
 5632    __exports__["default"] = function attr(type, options) {
 5633      options = options || {};
 5634
 5635      var meta = {
 5636        type: type,
 5637        isAttribute: true,
 5638        options: options
 5639      };
 5640
 5641      return Ember.computed('data', function(key, value) {
 5642        if (arguments.length > 1) {
 5643          Ember.assert("You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: DS.attr('<type>')` from " + this.constructor.toString(), key !== 'id');
 5644          var oldValue = getValue(this, key);
 5645
 5646          if (value !== oldValue) {
 5647            // Add the new value to the changed attributes hash; it will get deleted by
 5648            // the 'didSetProperty' handler if it is no different from the original value
 5649            this._attributes[key] = value;
 5650
 5651            this.send('didSetProperty', {
 5652              name: key,
 5653              oldValue: oldValue,
 5654              originalValue: this._data[key],
 5655              value: value
 5656            });
 5657          }
 5658
 5659          return value;
 5660        } else if (hasValue(this, key)) {
 5661          return getValue(this, key);
 5662        } else {
 5663          return getDefaultValue(this, options, key);
 5664        }
 5665
 5666      // `data` is never set directly. However, it may be
 5667      // invalidated from the state manager's setData
 5668      // event.
 5669      }).meta(meta);
 5670    };
 5671  });
 5672define("ember-data/system/model/errors",
 5673  ["ember-data/system/map","exports"],
 5674  function(__dependency1__, __exports__) {
 5675    "use strict";
 5676    var get = Ember.get;
 5677    var isEmpty = Ember.isEmpty;
 5678    var map = Ember.EnumerableUtils.map;
 5679
 5680    var MapWithDefault = __dependency1__.MapWithDefault;
 5681
 5682    /**
 5683    @module ember-data
 5684    */
 5685
 5686    /**
 5687      Holds validation errors for a given record organized by attribute names.
 5688
 5689      Every DS.Model has an `errors` property that is an instance of
 5690      `DS.Errors`. This can be used to display validation error
 5691      messages returned from the server when a `record.save()` rejects.
 5692      This works automatically with `DS.ActiveModelAdapter`, but you
 5693      can implement [ajaxError](api/data/classes/DS.RESTAdapter.html#method_ajaxError)
 5694      in other adapters as well.
 5695
 5696      For Example, if you had an `User` model that looked like this:
 5697
 5698      ```javascript
 5699      App.User = DS.Model.extend({
 5700        username: attr('string'),
 5701        email: attr('string')
 5702      });
 5703      ```
 5704      And you attempted to save a record that did not validate on the backend.
 5705
 5706      ```javascript
 5707      var user = store.createRecord('user', {
 5708        username: 'tomster',
 5709        email: 'invalidEmail'
 5710      });
 5711      user.save();
 5712      ```
 5713
 5714      Your backend data store might return a response that looks like
 5715      this. This response will be used to populate the error object.
 5716
 5717      ```javascript
 5718      {
 5719        "errors": {
 5720          "username": ["This username is already taken!"],
 5721          "email": ["Doesn't look like a valid email."]
 5722        }
 5723      }
 5724      ```
 5725
 5726      Errors can be displayed to the user by accessing their property name
 5727      or using the `messages` property to get an array of all errors.
 5728
 5729      ```handlebars
 5730      {{#each errors.messages}}
 5731        <div class="error">
 5732          {{message}}
 5733        </div>
 5734      {{/each}}
 5735
 5736      <label>Username: {{input value=username}} </label>
 5737      {{#each errors.username}}
 5738        <div class="error">
 5739          {{message}}
 5740        </div>
 5741      {{/each}}
 5742
 5743      <label>Email: {{input value=email}} </label>
 5744      {{#each errors.email}}
 5745        <div class="error">
 5746          {{message}}
 5747        </div>
 5748      {{/each}}
 5749      ```
 5750
 5751      @class Errors
 5752      @namespace DS
 5753      @extends Ember.Object
 5754      @uses Ember.Enumerable
 5755      @uses Ember.Evented
 5756     */
 5757    __exports__["default"] = Ember.Object.extend(Ember.Enumerable, Ember.Evented, {
 5758      /**
 5759        Register with target handler
 5760
 5761        @method registerHandlers
 5762        @param {Object} target
 5763        @param {Function} becameInvalid
 5764        @param {Function} becameValid
 5765      */
 5766      registerHandlers: function(target, becameInvalid, becameValid) {
 5767        this.on('becameInvalid', target, becameInvalid);
 5768        this.on('becameValid', target, becameValid);
 5769      },
 5770
 5771      /**
 5772        @property errorsByAttributeName
 5773        @type {Ember.MapWithDefault}
 5774        @private
 5775      */
 5776      errorsByAttributeName: Ember.reduceComputed("content", {
 5777        initialValue: function() {
 5778          return MapWithDefault.create({
 5779            defaultValue: function() {
 5780              return Ember.A();
 5781            }
 5782          });
 5783        },
 5784
 5785        addedItem: function(errors, error) {
 5786          errors.get(error.attribute).pushObject(error);
 5787
 5788          return errors;
 5789        },
 5790
 5791        removedItem: function(errors, error) {
 5792          errors.get(error.attribute).removeObject(error);
 5793
 5794          return errors;
 5795        }
 5796      }),
 5797
 5798      /**
 5799        Returns errors for a given attribute
 5800
 5801        ```javascript
 5802        var user = store.createRecord('user', {
 5803          username: 'tomster',
 5804          email: 'invalidEmail'
 5805        });
 5806        user.save().catch(function(){
 5807          user.get('errors').errorsFor('email'); // ["Doesn't look like a valid email."]
 5808        });
 5809        ```
 5810
 5811        @method errorsFor
 5812        @param {String} attribute
 5813        @return {Array}
 5814      */
 5815      errorsFor: function(attribute) {
 5816        return get(this, 'errorsByAttributeName').get(attribute);
 5817      },
 5818
 5819      /**
 5820        An array containing all of the error messages for this
 5821        record. This is useful for displaying all errors to the user.
 5822
 5823        ```handlebars
 5824        {{#each errors.messages}}
 5825          <div class="error">
 5826            {{message}}
 5827          </div>
 5828        {{/each}}
 5829        ```
 5830
 5831        @property messages
 5832        @type {Array}
 5833      */
 5834      messages: Ember.computed.mapBy('content', 'message'),
 5835
 5836      /**
 5837        @property content
 5838        @type {Array}
 5839        @private
 5840      */
 5841      content: Ember.computed(function() {
 5842        return Ember.A();
 5843      }),
 5844
 5845      /**
 5846        @method unknownProperty
 5847        @private
 5848      */
 5849      unknownProperty: function(attribute) {
 5850        var errors = this.errorsFor(attribute);
 5851        if (isEmpty(errors)) { return null; }
 5852        return errors;
 5853      },
 5854
 5855      /**
 5856        @method nextObject
 5857        @private
 5858      */
 5859      nextObject: function(index, previousObject, context) {
 5860        return get(this, 'content').objectAt(index);
 5861      },
 5862
 5863      /**
 5864        Total number of errors.
 5865
 5866        @property length
 5867        @type {Number}
 5868        @readOnly
 5869      */
 5870      length: Ember.computed.oneWay('content.length').readOnly(),
 5871
 5872      /**
 5873        @property isEmpty
 5874        @type {Boolean}
 5875        @readOnly
 5876      */
 5877      isEmpty: Ember.computed.not('length').readOnly(),
 5878
 5879      /**
 5880        Adds error messages to a given attribute and sends
 5881        `becameInvalid` event to the record.
 5882
 5883        Example:
 5884
 5885        ```javascript
 5886        if (!user.get('username') {
 5887          user.get('errors').add('username', 'This field is required');
 5888        }
 5889        ```
 5890
 5891        @method add
 5892        @param {String} attribute
 5893        @param {Array|String} messages
 5894      */
 5895      add: function(attribute, messages) {
 5896        var wasEmpty = get(this, 'isEmpty');
 5897
 5898        messages = this._findOrCreateMessages(attribute, messages);
 5899        get(this, 'content').addObjects(messages);
 5900
 5901        this.notifyPropertyChange(attribute);
 5902        this.enumerableContentDidChange();
 5903
 5904        if (wasEmpty && !get(this, 'isEmpty')) {
 5905          this.trigger('becameInvalid');
 5906        }
 5907      },
 5908
 5909      /**
 5910        @method _findOrCreateMessages
 5911        @private
 5912      */
 5913      _findOrCreateMessages: function(attribute, messages) {
 5914        var errors = this.errorsFor(attribute);
 5915
 5916        return map(Ember.makeArray(messages), function(message) {
 5917          return errors.findBy('message', message) || {
 5918            attribute: attribute,
 5919            message: message
 5920          };
 5921        });
 5922      },
 5923
 5924      /**
 5925        Removes all error messages from the given attribute and sends
 5926        `becameValid` event to the record if there no more errors left.
 5927
 5928        Example:
 5929
 5930        ```javascript
 5931        App.User = DS.Model.extend({
 5932          email: DS.attr('string'),
 5933          twoFactorAuth: DS.attr('boolean'),
 5934          phone: DS.attr('string')
 5935        });
 5936
 5937        App.UserEditRoute = Ember.Route.extend({
 5938          actions: {
 5939            save: function(user) {
 5940               if (!user.get('twoFactorAuth')) {
 5941                 user.get('errors').remove('phone');
 5942               }
 5943               user.save();
 5944             }
 5945          }
 5946        });
 5947        ```
 5948
 5949        @method remove
 5950        @param {String} attribute
 5951      */
 5952      remove: function(attribute) {
 5953        if (get(this, 'isEmpty')) { return; }
 5954
 5955        var content = get(this, 'content').rejectBy('attribute', attribute);
 5956        get(this, 'content').setObjects(content);
 5957
 5958        this.notifyPropertyChange(attribute);
 5959        this.enumerableContentDidChange();
 5960
 5961        if (get(this, 'isEmpty')) {
 5962          this.trigger('becameValid');
 5963        }
 5964      },
 5965
 5966      /**
 5967        Removes all error messages and sends `becameValid` event
 5968        to the record.
 5969
 5970        Example:
 5971
 5972        ```javascript
 5973        App.UserEditRoute = Ember.Route.extend({
 5974          actions: {
 5975            retrySave: function(user) {
 5976               user.get('errors').clear();
 5977               user.save();
 5978             }
 5979          }
 5980        });
 5981        ```
 5982
 5983        @method clear
 5984      */
 5985      clear: function() {
 5986        if (get(this, 'isEmpty')) { return; }
 5987
 5988        get(this, 'content').clear();
 5989        this.enumerableContentDidChange();
 5990
 5991        this.trigger('becameValid');
 5992      },
 5993
 5994      /**
 5995        Checks if there is error messages for the given attribute.
 5996
 5997        ```javascript
 5998        App.UserEditRoute = Ember.Route.extend({
 5999          actions: {
 6000            save: function(user) {
 6001               if (user.get('errors').has('email')) {
 6002                 return alert('Please update your email before attempting to save.');
 6003               }
 6004               user.save();
 6005             }
 6006          }
 6007        });
 6008        ```
 6009
 6010        @method has
 6011        @param {String} attribute
 6012        @return {Boolean} true if there some errors on given attribute
 6013      */
 6014      has: function(attribute) {
 6015        return !isEmpty(this.errorsFor(attribute));
 6016      }
 6017    });
 6018  });
 6019define("ember-data/system/model/model",
 6020  ["ember-data/system/model/states","ember-data/system/model/errors","ember-data/system/promise_proxies","ember-data/system/relationships/relationship","exports"],
 6021  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
 6022    "use strict";
 6023    var RootState = __dependency1__["default"];
 6024    var Errors = __dependency2__["default"];
 6025    var PromiseObject = __dependency3__.PromiseObject;
 6026    var createRelationshipFor = __dependency4__.createRelationshipFor;
 6027
 6028    /**
 6029      @module ember-data
 6030    */
 6031
 6032    var get = Ember.get;
 6033    var set = Ember.set;
 6034    var merge = Ember.merge;
 6035    var Promise = Ember.RSVP.Promise;
 6036    var forEach = Ember.ArrayPolyfills.forEach;
 6037    var map = Ember.ArrayPolyfills.map;
 6038
 6039    var JSONSerializer;
 6040    var retrieveFromCurrentState = Ember.computed('currentState', function(key, value) {
 6041      return get(get(this, 'currentState'), key);
 6042    }).readOnly();
 6043
 6044    var _extractPivotNameCache = Object.create(null);
 6045    var _splitOnDotCache = Object.create(null);
 6046
 6047    function splitOnDot(name) {
 6048      return _splitOnDotCache[name] || (
 6049        _splitOnDotCache[name] = name.split('.')
 6050      );
 6051    }
 6052
 6053    function extractPivotName(name) {
 6054      return _extractPivotNameCache[name] || (
 6055        _extractPivotNameCache[name] = splitOnDot(name)[0]
 6056      );
 6057    }
 6058
 6059    /**
 6060
 6061      The model class that all Ember Data records descend from.
 6062
 6063      @class Model
 6064      @namespace DS
 6065      @extends Ember.Object
 6066      @uses Ember.Evented
 6067    */
 6068    var Model = Ember.Object.extend(Ember.Evented, {
 6069      _recordArrays: undefined,
 6070      _relationships: undefined,
 6071      _loadingRecordArrays: undefined,
 6072      /**
 6073        If this property is `true` the record is in the `empty`
 6074        state. Empty is the first state all records enter after they have
 6075        been created. Most records created by the store will quickly
 6076        transition to the `loading` state if data needs to be fetched from
 6077        the server or the `created` state if the record is created on the
 6078        client. A record can also enter the empty state if the adapter is
 6079        unable to locate the record.
 6080
 6081        @property isEmpty
 6082        @type {Boolean}
 6083        @readOnly
 6084      */
 6085      isEmpty: retrieveFromCurrentState,
 6086      /**
 6087        If this property is `true` the record is in the `loading` state. A
 6088        record enters this state when the store asks the adapter for its
 6089        data. It remains in this state until the adapter provides the
 6090        requested data.
 6091
 6092        @property isLoading
 6093        @type {Boolean}
 6094        @readOnly
 6095      */
 6096      isLoading: retrieveFromCurrentState,
 6097      /**
 6098        If this property is `true` the record is in the `loaded` state. A
 6099        record enters this state when its data is populated. Most of a
 6100        record's lifecycle is spent inside substates of the `loaded`
 6101        state.
 6102
 6103        Example
 6104
 6105        ```javascript
 6106        var record = store.createRecord('model');
 6107        record.get('isLoaded'); // true
 6108
 6109        store.find('model', 1).then(function(model) {
 6110          model.get('isLoaded'); // true
 6111        });
 6112        ```
 6113
 6114        @property isLoaded
 6115        @type {Boolean}
 6116        @readOnly
 6117      */
 6118      isLoaded: retrieveFromCurrentState,
 6119      /**
 6120        If this property is `true` the record is in the `dirty` state. The
 6121        record has local changes that have not yet been saved by the
 6122        adapter. This includes records that have been created (but not yet
 6123        saved) or deleted.
 6124
 6125        Example
 6126
 6127        ```javascript
 6128        var record = store.createRecord('model');
 6129        record.get('isDirty'); // true
 6130
 6131        store.find('model', 1).then(function(model) {
 6132          model.get('isDirty'); // false
 6133          model.set('foo', 'some value');
 6134          model.get('isDirty'); // true
 6135        });
 6136        ```
 6137
 6138        @property isDirty
 6139        @type {Boolean}
 6140        @readOnly
 6141      */
 6142      isDirty: retrieveFromCurrentState,
 6143      /**
 6144        If this property is `true` the record is in the `saving` state. A
 6145        record enters the saving state when `save` is called, but the
 6146        adapter has not yet acknowledged that the changes have been
 6147        persisted to the backend.
 6148
 6149        Example
 6150
 6151        ```javascript
 6152        var record = store.createRecord('model');
 6153        record.get('isSaving'); // false
 6154        var promise = record.save();
 6155        record.get('isSaving'); // true
 6156        promise.then(function() {
 6157          record.get('isSaving'); // false
 6158        });
 6159        ```
 6160
 6161        @property isSaving
 6162        @type {Boolean}
 6163        @readOnly
 6164      */
 6165      isSaving: retrieveFromCurrentState,
 6166      /**
 6167        If this property is `true` the record is in the `deleted` state
 6168        and has been marked for deletion. When `isDeleted` is true and
 6169        `isDirty` is true, the record is deleted locally but the deletion
 6170        was not yet persisted. When `isSaving` is true, the change is
 6171        in-flight. When both `isDirty` and `isSaving` are false, the
 6172        change has persisted.
 6173
 6174        Example
 6175
 6176        ```javascript
 6177        var record = store.createRecord('model');
 6178        record.get('isDeleted');    // false
 6179        record.deleteRecord();
 6180
 6181        // Locally deleted
 6182        record.get('isDeleted');    // true
 6183        record.get('isDirty');      // true
 6184        record.get('isSaving');     // false
 6185
 6186        // Persisting the deletion
 6187        var promise = record.save();
 6188        record.get('isDeleted');    // true
 6189        record.get('isSaving');     // true
 6190
 6191        // Deletion Persisted
 6192        promise.then(function() {
 6193          record.get('isDeleted');  // true
 6194          record.get('isSaving');   // false
 6195          record.get('isDirty');    // false
 6196        });
 6197        ```
 6198
 6199        @property isDeleted
 6200        @type {Boolean}
 6201        @readOnly
 6202      */
 6203      isDeleted: retrieveFromCurrentState,
 6204      /**
 6205        If this property is `true` the record is in the `new` state. A
 6206        record will be in the `new` state when it has been created on the
 6207        client and the adapter has not yet report that it was successfully
 6208        saved.
 6209
 6210        Example
 6211
 6212        ```javascript
 6213        var record = store.createRecord('model');
 6214        record.get('isNew'); // true
 6215
 6216        record.save().then(function(model) {
 6217          model.get('isNew'); // false
 6218        });
 6219        ```
 6220
 6221        @property isNew
 6222        @type {Boolean}
 6223        @readOnly
 6224      */
 6225      isNew: retrieveFromCurrentState,
 6226      /**
 6227        If this property is `true` the record is in the `valid` state.
 6228
 6229        A record will be in the `valid` state when the adapter did not report any
 6230        server-side validation failures.
 6231
 6232        @property isValid
 6233        @type {Boolean}
 6234        @readOnly
 6235      */
 6236      isValid: retrieveFromCurrentState,
 6237      /**
 6238        If the record is in the dirty state this property will report what
 6239        kind of change has caused it to move into the dirty
 6240        state. Possible values are:
 6241
 6242        - `created` The record has been created by the client and not yet saved to the adapter.
 6243        - `updated` The record has been updated by the client and not yet saved to the adapter.
 6244        - `deleted` The record has been deleted by the client and not yet saved to the adapter.
 6245
 6246        Example
 6247
 6248        ```javascript
 6249        var record = store.createRecord('model');
 6250        record.get('dirtyType'); // 'created'
 6251        ```
 6252
 6253        @property dirtyType
 6254        @type {String}
 6255        @readOnly
 6256      */
 6257      dirtyType: retrieveFromCurrentState,
 6258
 6259      /**
 6260        If `true` the adapter reported that it was unable to save local
 6261        changes to the backend for any reason other than a server-side
 6262        validation error.
 6263
 6264        Example
 6265
 6266        ```javascript
 6267        record.get('isError'); // false
 6268        record.set('foo', 'valid value');
 6269        record.save().then(null, function() {
 6270          record.get('isError'); // true
 6271        });
 6272        ```
 6273
 6274        @property isError
 6275        @type {Boolean}
 6276        @readOnly
 6277      */
 6278      isError: false,
 6279      /**
 6280        If `true` the store is attempting to reload the record form the adapter.
 6281
 6282        Example
 6283
 6284        ```javascript
 6285        record.get('isReloading'); // false
 6286        record.reload();
 6287        record.get('isReloading'); // true
 6288        ```
 6289
 6290        @property isReloading
 6291        @type {Boolean}
 6292        @readOnly
 6293      */
 6294      isReloading: false,
 6295
 6296      /**
 6297        The `clientId` property is a transient numerical identifier
 6298        generated at runtime by the data store. It is important
 6299        primarily because newly created objects may not yet have an
 6300        externally generated id.
 6301
 6302        @property clientId
 6303        @private
 6304        @type {Number|String}
 6305      */
 6306      clientId: null,
 6307      /**
 6308        All ember models have an id property. This is an identifier
 6309        managed by an external source. These are always coerced to be
 6310        strings before being used internally. Note when declaring the
 6311        attributes for a model it is an error to declare an id
 6312        attribute.
 6313
 6314        ```javascript
 6315        var record = store.createRecord('model');
 6316        record.get('id'); // null
 6317
 6318        store.find('model', 1).then(function(model) {
 6319          model.get('id'); // '1'
 6320        });
 6321        ```
 6322
 6323        @property id
 6324        @type {String}
 6325      */
 6326      id: null,
 6327
 6328      /**
 6329        @property currentState
 6330        @private
 6331        @type {Object}
 6332      */
 6333      currentState: RootState.empty,
 6334
 6335      /**
 6336        When the record is in the `invalid` state this object will contain
 6337        any errors returned by the adapter. When present the errors hash
 6338        typically contains keys corresponding to the invalid property names
 6339        and values which are an array of error messages.
 6340
 6341        ```javascript
 6342        record.get('errors.length'); // 0
 6343        record.set('foo', 'invalid value');
 6344        record.save().then(null, function() {
 6345          record.get('errors').get('foo'); // ['foo should be a number.']
 6346        });
 6347        ```
 6348
 6349        @property errors
 6350        @type {DS.Errors}
 6351      */
 6352      errors: Ember.computed(function() {
 6353        var errors = Errors.create();
 6354
 6355        errors.registerHandlers(this, function() {
 6356          this.send('becameInvalid');
 6357        }, function() {
 6358          this.send('becameValid');
 6359        });
 6360
 6361        return errors;
 6362      }).readOnly(),
 6363
 6364      /**
 6365        Create a JSON representation of the record, using the serialization
 6366        strategy of the store's adapter.
 6367
 6368       `serialize` takes an optional hash as a parameter, currently
 6369        supported options are:
 6370
 6371       - `includeId`: `true` if the record's ID should be included in the
 6372          JSON representation.
 6373
 6374        @method serialize
 6375        @param {Object} options
 6376        @return {Object} an object whose values are primitive JSON values only
 6377      */
 6378      serialize: function(options) {
 6379        var store = get(this, 'store');
 6380        return store.serialize(this, options);
 6381      },
 6382
 6383      /**
 6384        Use [DS.JSONSerializer](DS.JSONSerializer.html) to
 6385        get the JSON representation of a record.
 6386
 6387        `toJSON` takes an optional hash as a parameter, currently
 6388        supported options are:
 6389
 6390        - `includeId`: `true` if the record's ID should be included in the
 6391          JSON representation.
 6392
 6393        @method toJSON
 6394        @param {Object} options
 6395        @return {Object} A JSON representation of the object.
 6396      */
 6397      toJSON: function(options) {
 6398        if (!JSONSerializer) { JSONSerializer = requireModule("ember-data/serializers/json_serializer")["default"]; }
 6399        // container is for lazy transform lookups
 6400        var serializer = JSONSerializer.create({ container: this.container });
 6401        return serializer.serialize(this, options);
 6402      },
 6403
 6404      /**
 6405        Fired when the record is loaded from the server.
 6406
 6407        @event didLoad
 6408      */
 6409      didLoad: Ember.K,
 6410
 6411      /**
 6412        Fired when the record is updated.
 6413
 6414        @event didUpdate
 6415      */
 6416      didUpdate: Ember.K,
 6417
 6418      /**
 6419        Fired when the record is created.
 6420
 6421        @event didCreate
 6422      */
 6423      didCreate: Ember.K,
 6424
 6425      /**
 6426        Fired when the record is deleted.
 6427
 6428        @event didDelete
 6429      */
 6430      didDelete: Ember.K,
 6431
 6432      /**
 6433        Fired when the record becomes invalid.
 6434
 6435        @event becameInvalid
 6436      */
 6437      becameInvalid: Ember.K,
 6438
 6439      /**
 6440        Fired when the record enters the error state.
 6441
 6442        @event becameError
 6443      */
 6444      becameError: Ember.K,
 6445
 6446      /**
 6447        @property data
 6448        @private
 6449        @type {Object}
 6450      */
 6451      data: Ember.computed(function() {
 6452        this._data = this._data || {};
 6453        return this._data;
 6454      }).readOnly(),
 6455
 6456      _data: null,
 6457
 6458      init: function() {
 6459        this._super();
 6460        this._setup();
 6461      },
 6462
 6463      _setup: function() {
 6464        this._changesToSync = {};
 6465        this._deferredTriggers = [];
 6466        this._data = {};
 6467        this._attributes = {};
 6468        this._inFlightAttributes = {};
 6469        this._relationships = {};
 6470        /*
 6471          implicit relationships are relationship which have not been declared but the inverse side exists on
 6472          another record somewhere
 6473          For example if there was
 6474          ```
 6475            App.Comment = DS.Model.extend({
 6476              name: DS.attr()
 6477            })
 6478          ```
 6479          but there is also
 6480          ```
 6481            App.Post = DS.Model.extend({
 6482              name: DS.attr(),
 6483              comments: DS.hasMany('comment')
 6484            })
 6485          ```
 6486
 6487          would have a implicit post relationship in order to be do things like remove ourselves from the post
 6488          when we are deleted
 6489        */
 6490        this._implicitRelationships = Object.create(null);
 6491        var model = this;
 6492        //TODO Move into a getter for better perf
 6493        this.constructor.eachRelationship(function(key, descriptor) {
 6494            model._relationships[key] = createRelationshipFor(model, descriptor, model.store);
 6495        });
 6496
 6497      },
 6498
 6499      /**
 6500        @method send
 6501        @private
 6502        @param {String} name
 6503        @param {Object} context
 6504      */
 6505      send: function(name, context) {
 6506        var currentState = get(this, 'currentState');
 6507
 6508        if (!currentState[name]) {
 6509          this._unhandledEvent(currentState, name, context);
 6510        }
 6511
 6512        return currentState[name](this, context);
 6513      },
 6514
 6515      /**
 6516        @method transitionTo
 6517        @private
 6518        @param {String} name
 6519      */
 6520      transitionTo: function(name) {
 6521        // POSSIBLE TODO: Remove this code and replace with
 6522        // always having direct references to state objects
 6523
 6524        var pivotName = extractPivotName(name);
 6525        var currentState = get(this, 'currentState');
 6526        var state = currentState;
 6527
 6528        do {
 6529          if (state.exit) { state.exit(this); }
 6530          state = state.parentState;
 6531        } while (!state.hasOwnProperty(pivotName));
 6532
 6533        var path = splitOnDot(name);
 6534        var setups = [], enters = [], i, l;
 6535
 6536        for (i=0, l=path.length; i<l; i++) {
 6537          state = state[path[i]];
 6538
 6539          if (state.enter) { enters.push(state); }
 6540          if (state.setup) { setups.push(state); }
 6541        }
 6542
 6543        for (i=0, l=enters.length; i<l; i++) {
 6544          enters[i].enter(this);
 6545        }
 6546
 6547        set(this, 'currentState', state);
 6548
 6549        for (i=0, l=setups.length; i<l; i++) {
 6550          setups[i].setup(this);
 6551        }
 6552
 6553        this.updateRecordArraysLater();
 6554      },
 6555
 6556      _unhandledEvent: function(state, name, context) {
 6557        var errorMessage = "Attempted to handle event `" + name + "` ";
 6558        errorMessage    += "on " + String(this) + " while in state ";
 6559        errorMessage    += state.stateName + ". ";
 6560
 6561        if (context !== undefined) {
 6562          errorMessage  += "Called with " + Ember.inspect(context) + ".";
 6563        }
 6564
 6565        throw new Ember.Error(errorMessage);
 6566      },
 6567
 6568      withTransaction: function(fn) {
 6569        var transaction = get(this, 'transaction');
 6570        if (transaction) { fn(transaction); }
 6571      },
 6572
 6573      /**
 6574        @method loadingData
 6575        @private
 6576        @param {Promise} promise
 6577      */
 6578      loadingData: function(promise) {
 6579        this.send('loadingData', promise);
 6580      },
 6581
 6582      /**
 6583        @method loadedData
 6584        @private
 6585      */
 6586      loadedData: function() {
 6587        this.send('loadedData');
 6588      },
 6589
 6590      /**
 6591        @method notFound
 6592        @private
 6593      */
 6594      notFound: function() {
 6595        this.send('notFound');
 6596      },
 6597
 6598      /**
 6599        @method pushedData
 6600        @private
 6601      */
 6602      pushedData: function() {
 6603        this.send('pushedData');
 6604      },
 6605
 6606      /**
 6607        Marks the record as deleted but does not save it. You must call
 6608        `save` afterwards if you want to persist it. You might use this
 6609        method if you want to allow the user to still `rollback()` a
 6610        delete after it was made.
 6611
 6612        Example
 6613
 6614        ```javascript
 6615        App.ModelDeleteRoute = Ember.Route.extend({
 6616          actions: {
 6617            softDelete: function() {
 6618              this.controller.get('model').deleteRecord();
 6619            },
 6620            confirm: function() {
 6621              this.controller.get('model').save();
 6622            },
 6623            undo: function() {
 6624              this.controller.get('model').rollback();
 6625            }
 6626          }
 6627        });
 6628        ```
 6629
 6630        @method deleteRecord
 6631      */
 6632      deleteRecord: function() {
 6633        this.send('deleteRecord');
 6634      },
 6635
 6636      /**
 6637        Same as `deleteRecord`, but saves the record immediately.
 6638
 6639        Example
 6640
 6641        ```javascript
 6642        App.ModelDeleteRoute = Ember.Route.extend({
 6643          actions: {
 6644            delete: function() {
 6645              var controller = this.controller;
 6646              controller.get('model').destroyRecord().then(function() {
 6647                controller.transitionToRoute('model.index');
 6648              });
 6649            }
 6650          }
 6651        });
 6652        ```
 6653
 6654        @method destroyRecord
 6655        @return {Promise} a promise that will be resolved when the adapter returns
 6656        successfully or rejected if the adapter returns with an error.
 6657      */
 6658      destroyRecord: function() {
 6659        this.deleteRecord();
 6660        return this.save();
 6661      },
 6662
 6663      /**
 6664        @method unloadRecord
 6665        @private
 6666      */
 6667      unloadRecord: function() {
 6668        if (this.isDestroyed) { return; }
 6669
 6670        this.send('unloadRecord');
 6671      },
 6672
 6673      /**
 6674        @method clearRelationships
 6675        @private
 6676      */
 6677      clearRelationships: function() {
 6678        this.eachRelationship(function(name, relationship) {
 6679          var rel = this._relationships[name];
 6680          if (rel){
 6681            //TODO(Igor) figure out whether we want to clear or disconnect
 6682            rel.clear();
 6683            rel.destroy();
 6684          }
 6685        }, this);
 6686      },
 6687
 6688      disconnectRelationships: function() {
 6689        this.eachRelationship(function(name, relationship) {
 6690          this._relationships[name].disconnect();
 6691        }, this);
 6692        var model = this;
 6693        forEach.call(Ember.keys(this._implicitRelationships), function(key) {
 6694          model._implicitRelationships[key].disconnect();
 6695        });
 6696      },
 6697
 6698      reconnectRelationships: function() {
 6699        this.eachRelationship(function(name, relationship) {
 6700          this._relationships[name].reconnect();
 6701        }, this);
 6702        var model = this;
 6703        forEach.call(Ember.keys(this._implicitRelationships), function(key) {
 6704          model._implicitRelationships[key].reconnect();
 6705        });
 6706      },
 6707
 6708
 6709      /**
 6710        @method updateRecordArrays
 6711        @private
 6712      */
 6713      updateRecordArrays: function() {
 6714        this._updatingRecordArraysLater = false;
 6715        get(this, 'store').dataWasUpdated(this.constructor, this);
 6716      },
 6717
 6718      /**
 6719        When a find request is triggered on the store, the user can optionally pass in
 6720        attributes and relationships to be preloaded. These are meant to behave as if they
 6721        came back from the server, except the user obtained them out of band and is informing
 6722        the store of their existence. The most common use case is for supporting client side
 6723        nested URLs, such as `/posts/1/comments/2` so the user can do
 6724        `store.find('comment', 2, {post:1})` without having to fetch the post.
 6725
 6726        Preloaded data can be attributes and relationships passed in either as IDs or as actual
 6727        models.
 6728
 6729        @method _preloadData
 6730        @private
 6731        @param {Object} preload
 6732      */
 6733      _preloadData: function(preload) {
 6734        var record = this;
 6735        //TODO(Igor) consider the polymorphic case
 6736        forEach.call(Ember.keys(preload), function(key) {
 6737          var preloadValue = get(preload, key);
 6738          var relationshipMeta = record.constructor.metaForProperty(key);
 6739          if (relationshipMeta.isRelationship) {
 6740            record._preloadRelationship(key, preloadValue);
 6741          } else {
 6742            get(record, '_data')[key] = preloadValue;
 6743          }
 6744        });
 6745      },
 6746
 6747      _preloadRelationship: function(key, preloadValue) {
 6748        var relationshipMeta = this.constructor.metaForProperty(key);
 6749        var type = relationshipMeta.type;
 6750        if (relationshipMeta.kind === 'hasMany'){
 6751          this._preloadHasMany(key, preloadValue, type);
 6752        } else {
 6753          this._preloadBelongsTo(key, preloadValue, type);
 6754        }
 6755      },
 6756
 6757      _preloadHasMany: function(key, preloadValue, type) {
 6758        Ember.assert("You need to pass in an array to set a hasMany property on a record", Ember.isArray(preloadValue));
 6759        var record = this;
 6760
 6761        var recordsToSet = map.call(preloadValue, function(recordToPush) {
 6762          return record._convertStringOrNumberIntoRecord(recordToPush, type);
 6763        });
 6764        //We use the pathway of setting the hasMany as if it came from the adapter
 6765        //because the user told us that they know this relationships exists already
 6766        this._relationships[key].updateRecordsFromAdapter(recordsToSet);
 6767      },
 6768
 6769      _preloadBelongsTo: function(key, preloadValue, type){
 6770        var recordToSet = this._convertStringOrNumberIntoRecord(preloadValue, type);
 6771
 6772        //We use the pathway of setting the hasMany as if it came from the adapter
 6773        //because the user told us that they know this relationships exists already
 6774        this._relationships[key].setRecord(recordToSet);
 6775      },
 6776
 6777      _convertStringOrNumberIntoRecord: function(value, type) {
 6778        if (Ember.typeOf(value) === 'string' || Ember.typeOf(value) === 'number'){
 6779          return this.store.recordForId(type, value);
 6780        }
 6781        return value;
 6782      },
 6783
 6784      /**
 6785        Returns an object, whose keys are changed properties, and value is
 6786        an [oldProp, newProp] array.
 6787
 6788        Example
 6789
 6790        ```javascript
 6791        App.Mascot = DS.Model.extend({
 6792          name: attr('string')
 6793        });
 6794
 6795        var person = store.createRecord('person');
 6796        person.changedAttributes(); // {}
 6797        person.set('name', 'Tomster');
 6798        person.changedAttributes(); // {name: [undefined, 'Tomster']}
 6799        ```
 6800
 6801        @method changedAttributes
 6802        @return {Object} an object, whose keys are changed properties,
 6803          and value is an [oldProp, newProp] array.
 6804      */
 6805      changedAttributes: function() {
 6806        var oldData = get(this, '_data');
 6807        var newData = get(this, '_attributes');
 6808        var diffData = {};
 6809        var prop;
 6810
 6811        for (prop in newData) {
 6812          diffData[prop] = [oldData[prop], newData[prop]];
 6813        }
 6814
 6815        return diffData;
 6816      },
 6817
 6818      /**
 6819        @method adapterWillCommit
 6820        @private
 6821      */
 6822      adapterWillCommit: function() {
 6823        this.send('willCommit');
 6824      },
 6825
 6826      /**
 6827        If the adapter did not return a hash in response to a commit,
 6828        merge the changed attributes and relationships into the existing
 6829        saved data.
 6830
 6831        @method adapterDidCommit
 6832      */
 6833      adapterDidCommit: function(data) {
 6834        set(this, 'isError', false);
 6835
 6836        if (data) {
 6837          this._data = data;
 6838        } else {
 6839          Ember.mixin(this._data, this._inFlightAttributes);
 6840        }
 6841
 6842        this._inFlightAttributes = {};
 6843
 6844        this.send('didCommit');
 6845        this.updateRecordArraysLater();
 6846
 6847        if (!data) { return; }
 6848
 6849        this.notifyPropertyChange('data');
 6850      },
 6851
 6852      /**
 6853        @method adapterDidDirty
 6854        @private
 6855      */
 6856      adapterDidDirty: function() {
 6857        this.send('becomeDirty');
 6858        this.updateRecordArraysLater();
 6859      },
 6860
 6861
 6862      /**
 6863        @method updateRecordArraysLater
 6864        @private
 6865      */
 6866      updateRecordArraysLater: function() {
 6867        // quick hack (something like this could be pushed into run.once
 6868        if (this._updatingRecordArraysLater) { return; }
 6869        this._updatingRecordArraysLater = true;
 6870
 6871        Ember.run.schedule('actions', this, this.updateRecordArrays);
 6872      },
 6873
 6874      /**
 6875        @method setupData
 6876        @private
 6877        @param {Object} data
 6878        @param {Boolean} partial the data should be merged into
 6879          the existing data, not replace it.
 6880      */
 6881      setupData: function(data, partial) {
 6882        if (partial) {
 6883          Ember.merge(this._data, data);
 6884        } else {
 6885          this._data = data;
 6886        }
 6887
 6888        if (data) { this.pushedData(); }
 6889
 6890        this.notifyPropertyChange('data');
 6891      },
 6892
 6893      materializeId: function(id) {
 6894        set(this, 'id', id);
 6895      },
 6896
 6897      materializeAttributes: function(attributes) {
 6898        Ember.assert("Must pass a hash of attributes to materializeAttributes", !!attributes);
 6899        merge(this._data, attributes);
 6900      },
 6901
 6902      materializeAttribute: function(name, value) {
 6903        this._data[name] = value;
 6904      },
 6905
 6906      /**
 6907        If the model `isDirty` this function will discard any unsaved
 6908        changes
 6909
 6910        Example
 6911
 6912        ```javascript
 6913        record.get('name'); // 'Untitled Document'
 6914        record.set('name', 'Doc 1');
 6915        record.get('name'); // 'Doc 1'
 6916        record.rollback();
 6917        record.get('name'); // 'Untitled Document'
 6918        ```
 6919
 6920        @method rollback
 6921      */
 6922      rollback: function() {
 6923        this._attributes = {};
 6924
 6925        if (get(this, 'isError')) {
 6926          this._inFlightAttributes = {};
 6927          set(this, 'isError', false);
 6928        }
 6929
 6930        //Eventually rollback will always work for relationships
 6931        //For now we support it only out of deleted state, because we
 6932        //have an explicit way of knowing when the server acked the relationship change
 6933        if (get(this, 'isDeleted')) {
 6934          this.reconnectRelationships();
 6935        }
 6936
 6937        if (!get(this, 'isValid')) {
 6938          this._inFlightAttributes = {};
 6939        }
 6940
 6941        this.send('rolledBack');
 6942
 6943        this.notifyPropertyChange('data');
 6944      },
 6945
 6946      toStringExtension: function() {
 6947        return get(this, 'id');
 6948      },
 6949
 6950      /**
 6951        Save the record and persist any changes to the record to an
 6952        external source via the adapter.
 6953
 6954        Example
 6955
 6956        ```javascript
 6957        record.set('name', 'Tomster');
 6958        record.save().then(function(){
 6959          // Success callback
 6960        }, function() {
 6961          // Error callback
 6962        });
 6963        ```
 6964        @method save
 6965        @return {Promise} a promise that will be resolved when the adapter returns
 6966        successfully or rejected if the adapter returns with an error.
 6967      */
 6968      save: function() {
 6969        var promiseLabel = "DS: Model#save " + this;
 6970        var resolver = Ember.RSVP.defer(promiseLabel);
 6971
 6972        this.get('store').scheduleSave(this, resolver);
 6973        this._inFlightAttributes = this._attributes;
 6974        this._attributes = {};
 6975
 6976        return PromiseObject.create({
 6977          promise: resolver.promise
 6978        });
 6979      },
 6980
 6981      /**
 6982        Reload the record from the adapter.
 6983
 6984        This will only work if the record has already finished loading
 6985        and has not yet been modified (`isLoaded` but not `isDirty`,
 6986        or `isSaving`).
 6987
 6988        Example
 6989
 6990        ```javascript
 6991        App.ModelViewRoute = Ember.Route.extend({
 6992          actions: {
 6993            reload: function() {
 6994              this.controller.get('model').reload();
 6995            }
 6996          }
 6997        });
 6998        ```
 6999
 7000        @method reload
 7001        @return {Promise} a promise that will be resolved with the record when the
 7002        adapter returns successfully or rejected if the adapter returns
 7003        with an error.
 7004      */
 7005      reload: function() {
 7006        set(this, 'isReloading', true);
 7007
 7008        var record = this;
 7009        var promiseLabel = "DS: Model#reload of " + this;
 7010        var promise = new Promise(function(resolve){
 7011           record.send('reloadRecord', resolve);
 7012        }, promiseLabel).then(function() {
 7013          record.set('isReloading', false);
 7014          record.set('isError', false);
 7015          return record;
 7016        }, function(reason) {
 7017          record.set('isError', true);
 7018          throw reason;
 7019        }, "DS: Model#reload complete, update flags")['finally'](function () {
 7020          record.updateRecordArrays();
 7021        });
 7022
 7023        return PromiseObject.create({
 7024          promise: promise
 7025        });
 7026      },
 7027
 7028      // FOR USE DURING COMMIT PROCESS
 7029
 7030      adapterDidUpdateAttribute: function(attributeName, value) {
 7031
 7032        // If a value is passed in, update the internal attributes and clear
 7033        // the attribute cache so it picks up the new value. Otherwise,
 7034        // collapse the current value into the internal attributes because
 7035        // the adapter has acknowledged it.
 7036        if (value !== undefined) {
 7037          this._data[attributeName] = value;
 7038          this.notifyPropertyChange(attributeName);
 7039        } else {
 7040          this._data[attributeName] = this._inFlightAttributes[attributeName];
 7041        }
 7042
 7043        this.updateRecordArraysLater();
 7044      },
 7045
 7046      /**
 7047        @method adapterDidInvalidate
 7048        @private
 7049      */
 7050      adapterDidInvalidate: function(errors) {
 7051        var recordErrors = get(this, 'errors');
 7052        function addError(name) {
 7053          if (errors[name]) {
 7054            recordErrors.add(name, errors[name]);
 7055          }
 7056        }
 7057
 7058        this.eachAttribute(addError);
 7059        this.eachRelationship(addError);
 7060      },
 7061
 7062      /**
 7063        @method adapterDidError
 7064        @private
 7065      */
 7066      adapterDidError: function() {
 7067        this.send('becameError');
 7068        set(this, 'isError', true);
 7069      },
 7070
 7071      /**
 7072        Override the default event firing from Ember.Evented to
 7073        also call methods with the given name.
 7074
 7075        @method trigger
 7076        @private
 7077        @param {String} name
 7078      */
 7079      trigger: function() {
 7080        var length = arguments.length;
 7081        var args = new Array(length - 1);
 7082        var name = arguments[0];
 7083
 7084        for (var i = 1; i < length; i++ ){
 7085          args[i - 1] = arguments[i];
 7086        }
 7087
 7088        Ember.tryInvoke(this, name, args);
 7089        this._super.apply(this, arguments);
 7090      },
 7091
 7092      triggerLater: function() {
 7093        var length = arguments.length;
 7094        var args = new Array(length);
 7095
 7096        for (var i = 0; i < length; i++ ){
 7097          args[i] = arguments[i];
 7098        }
 7099
 7100        if (this._deferredTriggers.push(args) !== 1) {
 7101          return;
 7102        }
 7103        Ember.run.schedule('actions', this, '_triggerDeferredTriggers');
 7104      },
 7105
 7106      _triggerDeferredTriggers: function() {
 7107        for (var i=0, l= this._deferredTriggers.length; i<l; i++) {
 7108          this.trigger.apply(this, this._deferredTriggers[i]);
 7109        }
 7110
 7111        this._deferredTriggers.length = 0;
 7112      },
 7113
 7114      willDestroy: function() {
 7115        this._super();
 7116        this.clearRelationships();
 7117      },
 7118
 7119      // This is a temporary solution until we refactor DS.Model to not
 7120      // rely on the data property.
 7121      willMergeMixin: function(props) {
 7122        Ember.assert('`data` is a reserved property name on DS.Model objects. Please choose a different property name for ' + this.constructor.toString(), !props.data);
 7123      }
 7124    });
 7125
 7126    Model.reopenClass({
 7127      /**
 7128        Alias DS.Model's `create` method to `_create`. This allows us to create DS.Model
 7129        instances from within the store, but if end users accidentally call `create()`
 7130        (instead of `createRecord()`), we can raise an error.
 7131
 7132        @method _create
 7133        @private
 7134        @static
 7135      */
 7136      _create: Model.create,
 7137
 7138      /**
 7139        Override the class' `create()` method to raise an error. This
 7140        prevents end users from inadvertently calling `create()` instead
 7141        of `createRecord()`. The store is still able to create instances
 7142        by calling the `_create()` method. To create an instance of a
 7143        `DS.Model` use [store.createRecord](DS.Store.html#method_createRecord).
 7144
 7145        @method create
 7146        @private
 7147        @static
 7148      */
 7149      create: function() {
 7150        throw new Ember.Error("You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.");
 7151      }
 7152    });
 7153
 7154    __exports__["default"] = Model;
 7155  });
 7156define("ember-data/system/model/states",
 7157  ["exports"],
 7158  function(__exports__) {
 7159    "use strict";
 7160    /**
 7161      @module ember-data
 7162    */
 7163
 7164    var get = Ember.get;
 7165    var set = Ember.set;
 7166    /*
 7167      This file encapsulates the various states that a record can transition
 7168      through during its lifecycle.
 7169    */
 7170    /**
 7171      ### State
 7172
 7173      Each record has a `currentState` property that explicitly tracks what
 7174      state a record is in at any given time. For instance, if a record is
 7175      newly created and has not yet been sent to the adapter to be saved,
 7176      it would be in the `root.loaded.created.uncommitted` state.  If a
 7177      record has had local modifications made to it that are in the
 7178      process of being saved, the record would be in the
 7179      `root.loaded.updated.inFlight` state. (This state paths will be
 7180      explained in more detail below.)
 7181
 7182      Events are sent by the record or its store to the record's
 7183      `currentState` property. How the state reacts to these events is
 7184      dependent on which state it is in. In some states, certain events
 7185      will be invalid and will cause an exception to be raised.
 7186
 7187      States are hierarchical and every state is a substate of the
 7188      `RootState`. For example, a record can be in the
 7189      `root.deleted.uncommitted` state, then transition into the
 7190      `root.deleted.inFlight` state. If a child state does not implement
 7191      an event handler, the state manager will attempt to invoke the event
 7192      on all parent states until the root state is reached. The state
 7193      hierarchy of a record is described in terms of a path string. You
 7194      can determine a record's current state by getting the state's
 7195      `stateName` property:
 7196
 7197      ```javascript
 7198      record.get('currentState.stateName');
 7199      //=> "root.created.uncommitted"
 7200       ```
 7201
 7202      The hierarchy of valid states that ship with ember data looks like
 7203      this:
 7204
 7205      ```text
 7206      * root
 7207        * deleted
 7208          * saved
 7209          * uncommitted
 7210          * inFlight
 7211        * empty
 7212        * loaded
 7213          * created
 7214            * uncommitted
 7215            * inFlight
 7216          * saved
 7217          * updated
 7218            * uncommitted
 7219            * inFlight
 7220        * loading
 7221      ```
 7222
 7223      The `DS.Model` states are themselves stateless. What that means is
 7224      that, the hierarchical states that each of *those* points to is a
 7225      shared data structure. For performance reasons, instead of each
 7226      record getting its own copy of the hierarchy of states, each record
 7227      points to this global, immutable shared instance. How does a state
 7228      know which record it should be acting on? We pass the record
 7229      instance into the state's event handlers as the first argument.
 7230
 7231      The record passed as the first parameter is where you should stash
 7232      state about the record if needed; you should never store data on the state
 7233      object itself.
 7234
 7235      ### Events and Flags
 7236
 7237      A state may implement zero or more events and flags.
 7238
 7239      #### Events
 7240
 7241      Events are named functions that are invoked when sent to a record. The
 7242      record will first look for a method with the given name on the
 7243      current state. If no method is found, it will search the current
 7244      state's parent, and then its grandparent, and so on until reaching
 7245      the top of the hierarchy. If the root is reached without an event
 7246      handler being found, an exception will be raised. This can be very
 7247      helpful when debugging new features.
 7248
 7249      Here's an example implementation of a state with a `myEvent` event handler:
 7250
 7251      ```javascript
 7252      aState: DS.State.create({
 7253        myEvent: function(manager, param) {
 7254          console.log("Received myEvent with", param);
 7255        }
 7256      })
 7257      ```
 7258
 7259      To trigger this event:
 7260
 7261      ```javascript
 7262      record.send('myEvent', 'foo');
 7263      //=> "Received myEvent with foo"
 7264      ```
 7265
 7266      Note that an optional parameter can be sent to a record's `send()` method,
 7267      which will be passed as the second parameter to the event handler.
 7268
 7269      Events should transition to a different state if appropriate. This can be
 7270      done by calling the record's `transitionTo()` method with a path to the
 7271      desired state. The state manager will attempt to resolve the state path
 7272      relative to the current state. If no state is found at that path, it will
 7273      attempt to resolve it relative to the current state's parent, and then its
 7274      parent, and so on until the root is reached. For example, imagine a hierarchy
 7275      like this:
 7276
 7277          * created
 7278            * uncommitted <-- currentState
 7279            * inFlight
 7280          * updated
 7281            * inFlight
 7282
 7283      If we are currently in the `uncommitted` state, calling
 7284      `transitionTo('inFlight')` would transition to the `created.inFlight` state,
 7285      while calling `transitionTo('updated.inFlight')` would transition to
 7286      the `updated.inFlight` state.
 7287
 7288      Remember that *only events* should ever cause a state transition. You should
 7289      never call `transitionTo()` from outside a state's event handler. If you are
 7290      tempted to do so, create a new event and send that to the state manager.
 7291
 7292      #### Flags
 7293
 7294      Flags are Boolean values that can be used to introspect a record's current
 7295      state in a more user-friendly way than examining its state path. For example,
 7296      instead of doing this:
 7297
 7298      ```javascript
 7299      var statePath = record.get('stateManager.currentPath');
 7300      if (statePath === 'created.inFlight') {
 7301        doSomething();
 7302      }
 7303      ```
 7304
 7305      You can say:
 7306
 7307      ```javascript
 7308      if (record.get('isNew') && record.get('isSaving')) {
 7309        doSomething();
 7310      }
 7311      ```
 7312
 7313      If your state does not set a value for a given flag, the value will
 7314      be inherited from its parent (or the first place in the state hierarchy
 7315      where it is defined).
 7316
 7317      The current set of flags are defined below. If you want to add a new flag,
 7318      in addition to the area below, you will also need to declare it in the
 7319      `DS.Model` class.
 7320
 7321
 7322       * [isEmpty](DS.Model.html#property_isEmpty)
 7323       * [isLoading](DS.Model.html#property_isLoading)
 7324       * [isLoaded](DS.Model.html#property_isLoaded)
 7325       * [isDirty](DS.Model.html#property_isDirty)
 7326       * [isSaving](DS.Model.html#property_isSaving)
 7327       * [isDeleted](DS.Model.html#property_isDeleted)
 7328       * [isNew](DS.Model.html#property_isNew)
 7329       * [isValid](DS.Model.html#property_isValid)
 7330
 7331      @namespace DS
 7332      @class RootState
 7333    */
 7334
 7335    function didSetProperty(record, context) {
 7336      if (context.value === context.originalValue) {
 7337        delete record._attributes[context.name];
 7338        record.send('propertyWasReset', context.name);
 7339      } else if (context.value !== context.oldValue) {
 7340        record.send('becomeDirty');
 7341      }
 7342
 7343      record.updateRecordArraysLater();
 7344    }
 7345
 7346    // Implementation notes:
 7347    //
 7348    // Each state has a boolean value for all of the following flags:
 7349    //
 7350    // * isLoaded: The record has a populated `data` property. When a
 7351    //   record is loaded via `store.find`, `isLoaded` is false
 7352    //   until the adapter sets it. When a record is created locally,
 7353    //   its `isLoaded` property is always true.
 7354    // * isDirty: The record has local changes that have not yet been
 7355    //   saved by the adapter. This includes records that have been
 7356    //   created (but not yet saved) or deleted.
 7357    // * isSaving: The record has been committed, but
 7358    //   the adapter has not yet acknowledged that the changes have
 7359    //   been persisted to the backend.
 7360    // * isDeleted: The record was marked for deletion. When `isDeleted`
 7361    //   is true and `isDirty` is true, the record is deleted locally
 7362    //   but the deletion was not yet persisted. When `isSaving` is
 7363    //   true, the change is in-flight. When both `isDirty` and
 7364    //   `isSaving` are false, the change has persisted.
 7365    // * isError: The adapter reported that it was unable to save
 7366    //   local changes to the backend. This may also result in the
 7367    //   record having its `isValid` property become false if the
 7368    //   adapter reported that server-side validations failed.
 7369    // * isNew: The record was created on the client and the adapter
 7370    //   did not yet report that it was successfully saved.
 7371    // * isValid: The adapter did not report any server-side validation
 7372    //   failures.
 7373
 7374    // The dirty state is a abstract state whose functionality is
 7375    // shared between the `created` and `updated` states.
 7376    //
 7377    // The deleted state shares the `isDirty` flag with the
 7378    // subclasses of `DirtyState`, but with a very different
 7379    // implementation.
 7380    //
 7381    // Dirty states have three child states:
 7382    //
 7383    // `uncommitted`: the store has not yet handed off the record
 7384    //   to be saved.
 7385    // `inFlight`: the store has handed off the record to be saved,
 7386    //   but the adapter has not yet acknowledged success.
 7387    // `invalid`: the record has invalid information and cannot be
 7388    //   send to the adapter yet.
 7389    var DirtyState = {
 7390      initialState: 'uncommitted',
 7391
 7392      // FLAGS
 7393      isDirty: true,
 7394
 7395      // SUBSTATES
 7396
 7397      // When a record first becomes dirty, it is `uncommitted`.
 7398      // This means that there are local pending changes, but they
 7399      // have not yet begun to be saved, and are not invalid.
 7400      uncommitted: {
 7401        // EVENTS
 7402        didSetProperty: didSetProperty,
 7403
 7404        //TODO(Igor) reloading now triggers a
 7405        //loadingData event, though it seems fine?
 7406        loadingData: Ember.K,
 7407
 7408        propertyWasReset: function(record, name) {
 7409          var length = Ember.keys(record._attributes);
 7410          var stillDirty = length > 0;
 7411
 7412          if (!stillDirty) { record.send('rolledBack'); }
 7413        },
 7414
 7415        pushedData: Ember.K,
 7416
 7417        becomeDirty: Ember.K,
 7418
 7419        willCommit: function(record) {
 7420          record.transitionTo('inFlight');
 7421        },
 7422
 7423        reloadRecord: function(record, resolve) {
 7424          resolve(get(record, 'store').reloadRecord(record));
 7425        },
 7426
 7427        rolledBack: function(record) {
 7428          record.transitionTo('loaded.saved');
 7429        },
 7430
 7431        becameInvalid: function(record) {
 7432          record.transitionTo('invalid');
 7433        },
 7434
 7435        rollback: function(record) {
 7436          record.rollback();
 7437        }
 7438      },
 7439
 7440      // Once a record has been handed off to the adapter to be
 7441      // saved, it is in the 'in flight' state. Changes to the
 7442      // record cannot be made during this window.
 7443      inFlight: {
 7444        // FLAGS
 7445        isSaving: true,
 7446
 7447        // EVENTS
 7448        didSetProperty: didSetProperty,
 7449        becomeDirty: Ember.K,
 7450        pushedData: Ember.K,
 7451
 7452        unloadRecord: function(record) {
 7453          Ember.assert("You can only unload a record which is not inFlight. `" + Ember.inspect(record) + " `", false);
 7454        },
 7455
 7456        // TODO: More robust semantics around save-while-in-flight
 7457        willCommit: Ember.K,
 7458
 7459        didCommit: function(record) {
 7460          var dirtyType = get(this, 'dirtyType');
 7461
 7462          record.transitionTo('saved');
 7463          record.send('invokeLifecycleCallbacks', dirtyType);
 7464        },
 7465
 7466        becameInvalid: function(record) {
 7467          record.transitionTo('invalid');
 7468          record.send('invokeLifecycleCallbacks');
 7469        },
 7470
 7471        becameError: function(record) {
 7472          record.transitionTo('uncommitted');
 7473          record.triggerLater('becameError', record);
 7474        }
 7475      },
 7476
 7477      // A record is in the `invalid` if the adapter has indicated
 7478      // the the record failed server-side invalidations.
 7479      invalid: {
 7480        // FLAGS
 7481        isValid: false,
 7482
 7483        // EVENTS
 7484        deleteRecord: function(record) {
 7485          record.transitionTo('deleted.uncommitted');
 7486          record.disconnectRelationships();
 7487        },
 7488
 7489        didSetProperty: function(record, context) {
 7490          get(record, 'errors').remove(context.name);
 7491
 7492          didSetProperty(record, context);
 7493        },
 7494
 7495        becomeDirty: Ember.K,
 7496
 7497        willCommit: function(record) {
 7498          get(record, 'errors').clear();
 7499          record.transitionTo('inFlight');
 7500        },
 7501
 7502        rolledBack: function(record) {
 7503          get(record, 'errors').clear();
 7504        },
 7505
 7506        becameValid: function(record) {
 7507          record.transitionTo('uncommitted');
 7508        },
 7509
 7510        invokeLifecycleCallbacks: function(record) {
 7511          record.triggerLater('becameInvalid', record);
 7512        },
 7513
 7514        exit: function(record) {
 7515          record._inFlightAttributes = {};
 7516        }
 7517      }
 7518    };
 7519
 7520    // The created and updated states are created outside the state
 7521    // chart so we can reopen their substates and add mixins as
 7522    // necessary.
 7523
 7524    function deepClone(object) {
 7525      var clone = {}, value;
 7526
 7527      for (var prop in object) {
 7528        value = object[prop];
 7529        if (value && typeof value === 'object') {
 7530          clone[prop] = deepClone(value);
 7531        } else {
 7532          clone[prop] = value;
 7533        }
 7534      }
 7535
 7536      return clone;
 7537    }
 7538
 7539    function mixin(original, hash) {
 7540      for (var prop in hash) {
 7541        original[prop] = hash[prop];
 7542      }
 7543
 7544      return original;
 7545    }
 7546
 7547    function dirtyState(options) {
 7548      var newState = deepClone(DirtyState);
 7549      return mixin(newState, options);
 7550    }
 7551
 7552    var createdState = dirtyState({
 7553      dirtyType: 'created',
 7554      // FLAGS
 7555      isNew: true
 7556    });
 7557
 7558    createdState.uncommitted.rolledBack = function(record) {
 7559      record.transitionTo('deleted.saved');
 7560    };
 7561
 7562    var updatedState = dirtyState({
 7563      dirtyType: 'updated'
 7564    });
 7565
 7566    createdState.uncommitted.deleteRecord = function(record) {
 7567      record.disconnectRelationships();
 7568      record.transitionTo('deleted.saved');
 7569    };
 7570
 7571    createdState.uncommitted.rollback = function(record) {
 7572      DirtyState.uncommitted.rollback.apply(this, arguments);
 7573      record.transitionTo('deleted.saved');
 7574    };
 7575
 7576    createdState.uncommitted.propertyWasReset = Ember.K;
 7577
 7578    function assertAgainstUnloadRecord(record) {
 7579      Ember.assert("You can only unload a record which is not inFlight. `" + Ember.inspect(record) + "`", false);
 7580    }
 7581
 7582    updatedState.inFlight.unloadRecord = assertAgainstUnloadRecord;
 7583
 7584    updatedState.uncommitted.deleteRecord = function(record) {
 7585      record.transitionTo('deleted.uncommitted');
 7586      record.disconnectRelationships();
 7587    };
 7588
 7589    var RootState = {
 7590      // FLAGS
 7591      isEmpty: false,
 7592      isLoading: false,
 7593      isLoaded: false,
 7594      isDirty: false,
 7595      isSaving: false,
 7596      isDeleted: false,
 7597      isNew: false,
 7598      isValid: true,
 7599
 7600      // DEFAULT EVENTS
 7601
 7602      // Trying to roll back if you're not in the dirty state
 7603      // doesn't change your state. For example, if you're in the
 7604      // in-flight state, rolling back the record doesn't move
 7605      // you out of the in-flight state.
 7606      rolledBack: Ember.K,
 7607      unloadRecord: function(record) {
 7608        // clear relationships before moving to deleted state
 7609        // otherwise it fails
 7610        record.clearRelationships();
 7611        record.transitionTo('deleted.saved');
 7612      },
 7613
 7614
 7615      propertyWasReset: Ember.K,
 7616
 7617      // SUBSTATES
 7618
 7619      // A record begins its lifecycle in the `empty` state.
 7620      // If its data will come from the adapter, it will
 7621      // transition into the `loading` state. Otherwise, if
 7622      // the record is being created on the client, it will
 7623      // transition into the `created` state.
 7624      empty: {
 7625        isEmpty: true,
 7626
 7627        // EVENTS
 7628        loadingData: function(record, promise) {
 7629          record._loadingPromise = promise;
 7630          record.transitionTo('loading');
 7631        },
 7632
 7633        loadedData: function(record) {
 7634          record.transitionTo('loaded.created.uncommitted');
 7635          record.notifyPropertyChange('data');
 7636        },
 7637
 7638        pushedData: function(record) {
 7639          record.transitionTo('loaded.saved');
 7640          record.triggerLater('didLoad');
 7641        }
 7642      },
 7643
 7644      // A record enters this state when the store asks
 7645      // the adapter for its data. It remains in this state
 7646      // until the adapter provides the requested data.
 7647      //
 7648      // Usually, this process is asynchronous, using an
 7649      // XHR to retrieve the data.
 7650      loading: {
 7651        // FLAGS
 7652        isLoading: true,
 7653
 7654        exit: function(record) {
 7655          record._loadingPromise = null;
 7656        },
 7657
 7658        // EVENTS
 7659        pushedData: function(record) {
 7660          record.transitionTo('loaded.saved');
 7661          record.triggerLater('didLoad');
 7662          set(record, 'isError', false);
 7663        },
 7664
 7665        becameError: function(record) {
 7666          record.triggerLater('becameError', record);
 7667        },
 7668
 7669        notFound: function(record) {
 7670          record.transitionTo('empty');
 7671        }
 7672      },
 7673
 7674      // A record enters this state when its data is populated.
 7675      // Most of a record's lifecycle is spent inside substates
 7676      // of the `loaded` state.
 7677      loaded: {
 7678        initialState: 'saved',
 7679
 7680        // FLAGS
 7681        isLoaded: true,
 7682
 7683        //TODO(Igor) Reloading now triggers a loadingData event,
 7684        //but it should be ok?
 7685        loadingData: Ember.K,
 7686
 7687        // SUBSTATES
 7688
 7689        // If there are no local changes to a record, it remains
 7690        // in the `saved` state.
 7691        saved: {
 7692          setup: function(record) {
 7693            var attrs = record._attributes;
 7694            var isDirty = false;
 7695
 7696            for (var prop in attrs) {
 7697              if (attrs.hasOwnProperty(prop)) {
 7698                isDirty = true;
 7699                break;
 7700              }
 7701            }
 7702
 7703            if (isDirty) {
 7704              record.adapterDidDirty();
 7705            }
 7706          },
 7707
 7708          // EVENTS
 7709          didSetProperty: didSetProperty,
 7710
 7711          pushedData: Ember.K,
 7712
 7713          becomeDirty: function(record) {
 7714            record.transitionTo('updated.uncommitted');
 7715          },
 7716
 7717          willCommit: function(record) {
 7718            record.transitionTo('updated.inFlight');
 7719          },
 7720
 7721          reloadRecord: function(record, resolve) {
 7722            resolve(get(record, 'store').reloadRecord(record));
 7723          },
 7724
 7725          deleteRecord: function(record) {
 7726            record.transitionTo('deleted.uncommitted');
 7727            record.disconnectRelationships();
 7728          },
 7729
 7730          unloadRecord: function(record) {
 7731            // clear relationships before moving to deleted state
 7732            // otherwise it fails
 7733            record.clearRelationships();
 7734            record.transitionTo('deleted.saved');
 7735          },
 7736
 7737          didCommit: function(record) {
 7738            record.send('invokeLifecycleCallbacks', get(record, 'lastDirtyType'));
 7739          },
 7740
 7741          // loaded.saved.notFound would be triggered by a failed
 7742          // `reload()` on an unchanged record
 7743          notFound: Ember.K
 7744
 7745        },
 7746
 7747        // A record is in this state after it has been locally
 7748        // created but before the adapter has indicated that
 7749        // it has been saved.
 7750        created: createdState,
 7751
 7752        // A record is in this state if it has already been
 7753        // saved to the server, but there are new local changes
 7754        // that have not yet been saved.
 7755        updated: updatedState
 7756      },
 7757
 7758      // A record is in this state if it was deleted from the store.
 7759      deleted: {
 7760        initialState: 'uncommitted',
 7761        dirtyType: 'deleted',
 7762
 7763        // FLAGS
 7764        isDeleted: true,
 7765        isLoaded: true,
 7766        isDirty: true,
 7767
 7768        // TRANSITIONS
 7769        setup: function(record) {
 7770          record.updateRecordArrays();
 7771        },
 7772
 7773        // SUBSTATES
 7774
 7775        // When a record is deleted, it enters the `start`
 7776        // state. It will exit this state when the record
 7777        // starts to commit.
 7778        uncommitted: {
 7779
 7780          // EVENTS
 7781
 7782          willCommit: function(record) {
 7783            record.transitionTo('inFlight');
 7784          },
 7785
 7786          rollback: function(record) {
 7787            record.rollback();
 7788          },
 7789
 7790          becomeDirty: Ember.K,
 7791          deleteRecord: Ember.K,
 7792
 7793          rolledBack: function(record) {
 7794            record.transitionTo('loaded.saved');
 7795          }
 7796        },
 7797
 7798        // After a record starts committing, but
 7799        // before the adapter indicates that the deletion
 7800        // has saved to the server, a record is in the
 7801        // `inFlight` substate of `deleted`.
 7802        inFlight: {
 7803          // FLAGS
 7804          isSaving: true,
 7805
 7806          // EVENTS
 7807
 7808          unloadRecord: assertAgainstUnloadRecord,
 7809
 7810          // TODO: More robust semantics around save-while-in-flight
 7811          willCommit: Ember.K,
 7812          didCommit: function(record) {
 7813            record.transitionTo('saved');
 7814
 7815            record.send('invokeLifecycleCallbacks');
 7816          },
 7817
 7818          becameError: function(record) {
 7819            record.transitionTo('uncommitted');
 7820            record.triggerLater('becameError', record);
 7821          }
 7822        },
 7823
 7824        // Once the adapter indicates that the deletion has
 7825        // been saved, the record enters the `saved` substate
 7826        // of `deleted`.
 7827        saved: {
 7828          // FLAGS
 7829          isDirty: false,
 7830
 7831          setup: function(record) {
 7832            var store = get(record, 'store');
 7833            store.dematerializeRecord(record);
 7834          },
 7835
 7836          invokeLifecycleCallbacks: function(record) {
 7837            record.triggerLater('didDelete', record);
 7838            record.triggerLater('didCommit', record);
 7839          },
 7840
 7841          willCommit: Ember.K,
 7842
 7843          didCommit: Ember.K
 7844        }
 7845      },
 7846
 7847      invokeLifecycleCallbacks: function(record, dirtyType) {
 7848        if (dirtyType === 'created') {
 7849          record.triggerLater('didCreate', record);
 7850        } else {
 7851          record.triggerLater('didUpdate', record);
 7852        }
 7853
 7854        record.triggerLater('didCommit', record);
 7855      }
 7856    };
 7857
 7858    function wireState(object, parent, name) {
 7859      /*jshint proto:true*/
 7860      // TODO: Use Object.create and copy instead
 7861      object = mixin(parent ? Ember.create(parent) : {}, object);
 7862      object.parentState = parent;
 7863      object.stateName = name;
 7864
 7865      for (var prop in object) {
 7866        if (!object.hasOwnProperty(prop) || prop === 'parentState' || prop === 'stateName') { continue; }
 7867        if (typeof object[prop] === 'object') {
 7868          object[prop] = wireState(object[prop], object, name + "." + prop);
 7869        }
 7870      }
 7871
 7872      return object;
 7873    }
 7874
 7875    RootState = wireState(RootState, null, "root");
 7876
 7877    __exports__["default"] = RootState;
 7878  });
 7879define("ember-data/system/promise_proxies",
 7880  ["exports"],
 7881  function(__exports__) {
 7882    "use strict";
 7883    var Promise = Ember.RSVP.Promise;
 7884    var get = Ember.get;
 7885
 7886    /**
 7887      A `PromiseArray` is an object that acts like both an `Ember.Array`
 7888      and a promise. When the promise is resolved the resulting value
 7889      will be set to the `PromiseArray`'s `content` property. This makes
 7890      it easy to create data bindings with the `PromiseArray` that will be
 7891      updated when the promise resolves.
 7892
 7893      For more information see the [Ember.PromiseProxyMixin
 7894      documentation](/api/classes/Ember.PromiseProxyMixin.html).
 7895
 7896      Example
 7897
 7898      ```javascript
 7899      var promiseArray = DS.PromiseArray.create({
 7900        promise: $.getJSON('/some/remote/data.json')
 7901      });
 7902
 7903      promiseArray.get('length'); // 0
 7904
 7905      promiseArray.then(function() {
 7906        promiseArray.get('length'); // 100
 7907      });
 7908      ```
 7909
 7910      @class PromiseArray
 7911      @namespace DS
 7912      @extends Ember.ArrayProxy
 7913      @uses Ember.PromiseProxyMixin
 7914    */
 7915    var PromiseArray = Ember.ArrayProxy.extend(Ember.PromiseProxyMixin);
 7916
 7917    /**
 7918      A `PromiseObject` is an object that acts like both an `Ember.Object`
 7919      and a promise. When the promise is resolved, then the resulting value
 7920      will be set to the `PromiseObject`'s `content` property. This makes
 7921      it easy to create data bindings with the `PromiseObject` that will
 7922      be updated when the promise resolves.
 7923
 7924      For more information see the [Ember.PromiseProxyMixin
 7925      documentation](/api/classes/Ember.PromiseProxyMixin.html).
 7926
 7927      Example
 7928
 7929      ```javascript
 7930      var promiseObject = DS.PromiseObject.create({
 7931        promise: $.getJSON('/some/remote/data.json')
 7932      });
 7933
 7934      promiseObject.get('name'); // null
 7935
 7936      promiseObject.then(function() {
 7937        promiseObject.get('name'); // 'Tomster'
 7938      });
 7939      ```
 7940
 7941      @class PromiseObject
 7942      @namespace DS
 7943      @extends Ember.ObjectProxy
 7944      @uses Ember.PromiseProxyMixin
 7945    */
 7946    var PromiseObject = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin);
 7947
 7948    var promiseObject = function(promise, label) {
 7949      return PromiseObject.create({
 7950        promise: Promise.resolve(promise, label)
 7951      });
 7952    };
 7953
 7954    var promiseArray = function(promise, label) {
 7955      return PromiseArray.create({
 7956        promise: Promise.resolve(promise, label)
 7957      });
 7958    };
 7959
 7960    /**
 7961      A PromiseManyArray is a PromiseArray that also proxies certain method calls
 7962      to the underlying manyArray.
 7963      Right now we proxy:
 7964        `reload()`
 7965    */
 7966
 7967    var PromiseManyArray = PromiseArray.extend({
 7968      reload: function() {
 7969        //I don't think this should ever happen right now, but worth guarding if we refactor the async relationships
 7970        Ember.assert('You are trying to reload an async manyArray before it has been created', get(this, 'content'));
 7971        return get(this, 'content').reload();
 7972      }
 7973    });
 7974
 7975    var promiseManyArray = function(promise, label) {
 7976      return PromiseManyArray.create({
 7977        promise: Promise.resolve(promise, label)
 7978      });
 7979    };
 7980
 7981
 7982    __exports__.PromiseArray = PromiseArray;
 7983    __exports__.PromiseObject = PromiseObject;
 7984    __exports__.PromiseManyArray = PromiseManyArray;
 7985    __exports__.promiseArray = promiseArray;
 7986    __exports__.promiseObject = promiseObject;
 7987    __exports__.promiseManyArray = promiseManyArray;
 7988  });
 7989define("ember-data/system/record_array_manager",
 7990  ["ember-data/system/record_arrays","ember-data/system/map","exports"],
 7991  function(__dependency1__, __dependency2__, __exports__) {
 7992    "use strict";
 7993    /**
 7994      @module ember-data
 7995    */
 7996
 7997    var RecordArray = __dependency1__.RecordArray;
 7998    var FilteredRecordArray = __dependency1__.FilteredRecordArray;
 7999    var AdapterPopulatedRecordArray = __dependency1__.AdapterPopulatedRecordArray;
 8000    var ManyArray = __dependency1__.ManyArray;
 8001    var MapWithDefault = __dependency2__.MapWithDefault;
 8002    var OrderedSet = __dependency2__.OrderedSet;
 8003    var get = Ember.get;
 8004    var forEach = Ember.EnumerableUtils.forEach;
 8005
 8006    /**
 8007      @class RecordArrayManager
 8008      @namespace DS
 8009      @private
 8010      @extends Ember.Object
 8011    */
 8012    __exports__["default"] = Ember.Object.extend({
 8013      init: function() {
 8014        this.filteredRecordArrays = MapWithDefault.create({
 8015          defaultValue: function() { return []; }
 8016        });
 8017
 8018        this.changedRecords = [];
 8019        this._adapterPopulatedRecordArrays = [];
 8020      },
 8021
 8022      recordDidChange: function(record) {
 8023        if (this.changedRecords.push(record) !== 1) { return; }
 8024
 8025        Ember.run.schedule('actions', this, this.updateRecordArrays);
 8026      },
 8027
 8028      recordArraysForRecord: function(record) {
 8029        record._recordArrays = record._recordArrays || OrderedSet.create();
 8030        return record._recordArrays;
 8031      },
 8032
 8033      /**
 8034        This method is invoked whenever data is loaded into the store by the
 8035        adapter or updated by the adapter, or when a record has changed.
 8036
 8037        It updates all record arrays that a record belongs to.
 8038
 8039        To avoid thrashing, it only runs at most once per run loop.
 8040
 8041        @method updateRecordArrays
 8042        @param {Class} type
 8043        @param {Number|String} clientId
 8044      */
 8045      updateRecordArrays: function() {
 8046        forEach(this.changedRecords, function(record) {
 8047          if (get(record, 'isDeleted')) {
 8048            this._recordWasDeleted(record);
 8049          } else {
 8050            this._recordWasChanged(record);
 8051          }
 8052        }, this);
 8053
 8054        this.changedRecords.length = 0;
 8055      },
 8056
 8057      _recordWasDeleted: function (record) {
 8058        var recordArrays = record._recordArrays;
 8059
 8060        if (!recordArrays) { return; }
 8061
 8062        recordArrays.forEach(function(array){
 8063          array.removeRecord(record);
 8064        });
 8065
 8066        record._recordArrays = null;
 8067      },
 8068
 8069      _recordWasChanged: function (record) {
 8070        var type = record.constructor;
 8071        var recordArrays = this.filteredRecordArrays.get(type);
 8072        var filter;
 8073
 8074        forEach(recordArrays, function(array) {
 8075          filter = get(array, 'filterFunction');
 8076          this.updateRecordArray(array, filter, type, record);
 8077        }, this);
 8078
 8079        // loop through all manyArrays containing an unloaded copy of this
 8080        // clientId and notify them that the record was loaded.
 8081        var manyArrays = record._loadingRecordArrays;
 8082
 8083        if (manyArrays) {
 8084          for (var i=0, l=manyArrays.length; i<l; i++) {
 8085            manyArrays[i].loadedRecord();
 8086          }
 8087
 8088          record._loadingRecordArrays = [];
 8089        }
 8090      },
 8091
 8092      /**
 8093        Update an individual filter.
 8094
 8095        @method updateRecordArray
 8096        @param {DS.FilteredRecordArray} array
 8097        @param {Function} filter
 8098        @param {Class} type
 8099        @param {Number|String} clientId
 8100      */
 8101      updateRecordArray: function(array, filter, type, record) {
 8102        var shouldBeInArray;
 8103
 8104        if (!filter) {
 8105          shouldBeInArray = true;
 8106        } else {
 8107          shouldBeInArray = filter(record);
 8108        }
 8109
 8110        var recordArrays = this.recordArraysForRecord(record);
 8111
 8112        if (shouldBeInArray) {
 8113          if (!recordArrays.has(array)) {
 8114            array.pushRecord(record);
 8115            recordArrays.add(array);
 8116          }
 8117        } else if (!shouldBeInArray) {
 8118          recordArrays["delete"](array);
 8119          array.removeRecord(record);
 8120        }
 8121      },
 8122
 8123      /**
 8124        This method is invoked if the `filterFunction` property is
 8125        changed on a `DS.FilteredRecordArray`.
 8126
 8127        It essentially re-runs the filter from scratch. This same
 8128        method is invoked when the filter is created in th first place.
 8129
 8130        @method updateFilter
 8131        @param {Array} array
 8132        @param {String} type
 8133        @param {Function} filter
 8134      */
 8135      updateFilter: function(array, type, filter) {
 8136        var typeMap = this.store.typeMapFor(type);
 8137        var records = typeMap.records, record;
 8138
 8139        for (var i=0, l=records.length; i<l; i++) {
 8140          record = records[i];
 8141
 8142          if (!get(record, 'isDeleted') && !get(record, 'isEmpty')) {
 8143            this.updateRecordArray(array, filter, type, record);
 8144          }
 8145        }
 8146      },
 8147
 8148      /**
 8149        Create a `DS.ManyArray` for a type and list of record references, and index
 8150        the `ManyArray` under each reference. This allows us to efficiently remove
 8151        records from `ManyArray`s when they are deleted.
 8152
 8153        @method createManyArray
 8154        @param {Class} type
 8155        @param {Array} references
 8156        @return {DS.ManyArray}
 8157      */
 8158      createManyArray: function(type, records) {
 8159        var manyArray = ManyArray.create({
 8160          type: type,
 8161          content: records,
 8162          store: this.store
 8163        });
 8164
 8165        forEach(records, function(record) {
 8166          var arrays = this.recordArraysForRecord(record);
 8167          arrays.add(manyArray);
 8168        }, this);
 8169
 8170        return manyArray;
 8171      },
 8172
 8173      /**
 8174        Create a `DS.RecordArray` for a type and register it for updates.
 8175
 8176        @method createRecordArray
 8177        @param {Class} type
 8178        @return {DS.RecordArray}
 8179      */
 8180      createRecordArray: function(type) {
 8181        var array = RecordArray.create({
 8182          type: type,
 8183          content: Ember.A(),
 8184          store: this.store,
 8185          isLoaded: true
 8186        });
 8187
 8188        this.registerFilteredRecordArray(array, type);
 8189
 8190        return array;
 8191      },
 8192
 8193      /**
 8194        Create a `DS.FilteredRecordArray` for a type and register it for updates.
 8195
 8196        @method createFilteredRecordArray
 8197        @param {Class} type
 8198        @param {Function} filter
 8199        @param {Object} query (optional
 8200        @return {DS.FilteredRecordArray}
 8201      */
 8202      createFilteredRecordArray: function(type, filter, query) {
 8203        var array = FilteredRecordArray.create({
 8204          query: query,
 8205          type: type,
 8206          content: Ember.A(),
 8207          store: this.store,
 8208          manager: this,
 8209          filterFunction: filter
 8210        });
 8211
 8212        this.registerFilteredRecordArray(array, type, filter);
 8213
 8214        return array;
 8215      },
 8216
 8217      /**
 8218        Create a `DS.AdapterPopulatedRecordArray` for a type with given query.
 8219
 8220        @method createAdapterPopulatedRecordArray
 8221        @param {Class} type
 8222        @param {Object} query
 8223        @return {DS.AdapterPopulatedRecordArray}
 8224      */
 8225      createAdapterPopulatedRecordArray: function(type, query) {
 8226        var array = AdapterPopulatedRecordArray.create({
 8227          type: type,
 8228          query: query,
 8229          content: Ember.A(),
 8230          store: this.store,
 8231          manager: this
 8232        });
 8233
 8234        this._adapterPopulatedRecordArrays.push(array);
 8235
 8236        return array;
 8237      },
 8238
 8239      /**
 8240        Register a RecordArray for a given type to be backed by
 8241        a filter function. This will cause the array to update
 8242        automatically when records of that type change attribute
 8243        values or states.
 8244
 8245        @method registerFilteredRecordArray
 8246        @param {DS.RecordArray} array
 8247        @param {Class} type
 8248        @param {Function} filter
 8249      */
 8250      registerFilteredRecordArray: function(array, type, filter) {
 8251        var recordArrays = this.filteredRecordArrays.get(type);
 8252        recordArrays.push(array);
 8253
 8254        this.updateFilter(array, type, filter);
 8255      },
 8256
 8257      // Internally, we maintain a map of all unloaded IDs requested by
 8258      // a ManyArray. As the adapter loads data into the store, the
 8259      // store notifies any interested ManyArrays. When the ManyArray's
 8260      // total number of loading records drops to zero, it becomes
 8261      // `isLoaded` and fires a `didLoad` event.
 8262      registerWaitingRecordArray: function(record, array) {
 8263        var loadingRecordArrays = record._loadingRecordArrays || [];
 8264        loadingRecordArrays.push(array);
 8265        record._loadingRecordArrays = loadingRecordArrays;
 8266      },
 8267
 8268      willDestroy: function(){
 8269        this._super();
 8270
 8271        forEach(flatten(values(this.filteredRecordArrays.values)), destroy);
 8272        forEach(this._adapterPopulatedRecordArrays, destroy);
 8273      }
 8274    });
 8275
 8276    function values(obj) {
 8277      var result = [];
 8278      var keys = Ember.keys(obj);
 8279
 8280      for (var i = 0; i < keys.length; i++) {
 8281        result.push(obj[keys[i]]);
 8282      }
 8283
 8284      return result;
 8285    }
 8286
 8287    function destroy(entry) {
 8288      entry.destroy();
 8289    }
 8290
 8291    function flatten(list) {
 8292      var length = list.length;
 8293      var result = Ember.A();
 8294
 8295      for (var i = 0; i < length; i++) {
 8296        result = result.concat(list[i]);
 8297      }
 8298
 8299      return result;
 8300    }
 8301  });
 8302define("ember-data/system/record_arrays",
 8303  ["ember-data/system/record_arrays/record_array","ember-data/system/record_arrays/filtered_record_array","ember-data/system/record_arrays/adapter_populated_record_array","ember-data/system/record_arrays/many_array","exports"],
 8304  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
 8305    "use strict";
 8306    /**
 8307      @module ember-data
 8308    */
 8309
 8310    var RecordArray = __dependency1__["default"];
 8311    var FilteredRecordArray = __dependency2__["default"];
 8312    var AdapterPopulatedRecordArray = __dependency3__["default"];
 8313    var ManyArray = __dependency4__["default"];
 8314
 8315    __exports__.RecordArray = RecordArray;
 8316    __exports__.FilteredRecordArray = FilteredRecordArray;
 8317    __exports__.AdapterPopulatedRecordArray = AdapterPopulatedRecordArray;
 8318    __exports__.ManyArray = ManyArray;
 8319  });
 8320define("ember-data/system/record_arrays/adapter_populated_record_array",
 8321  ["ember-data/system/record_arrays/record_array","exports"],
 8322  function(__dependency1__, __exports__) {
 8323    "use strict";
 8324    var RecordArray = __dependency1__["default"];
 8325    /**
 8326      @module ember-data
 8327    */
 8328
 8329    var get = Ember.get;
 8330
 8331    function cloneNull(source) {
 8332      var clone = Object.create(null);
 8333      for (var key in source) {
 8334        clone[key] = source[key];
 8335      }
 8336      return clone;
 8337    }
 8338
 8339    /**
 8340      Represents an ordered list of records whose order and membership is
 8341      determined by the adapter. For example, a query sent to the adapter
 8342      may trigger a search on the server, whose results would be loaded
 8343      into an instance of the `AdapterPopulatedRecordArray`.
 8344
 8345      @class AdapterPopulatedRecordArray
 8346      @namespace DS
 8347      @extends DS.RecordArray
 8348    */
 8349    __exports__["default"] = RecordArray.extend({
 8350      query: null,
 8351
 8352      replace: function() {
 8353        var type = get(this, 'type').toString();
 8354        throw new Error("The result of a server query (on " + type + ") is immutable.");
 8355      },
 8356
 8357      /**
 8358        @method load
 8359        @private
 8360        @param {Array} data
 8361      */
 8362      load: function(data) {
 8363        var store = get(this, 'store');
 8364        var type = get(this, 'type');
 8365        var records = store.pushMany(type, data);
 8366        var meta = store.metadataFor(type);
 8367
 8368        this.setProperties({
 8369          content: Ember.A(records),
 8370          isLoaded: true,
 8371          meta: cloneNull(meta)
 8372        });
 8373
 8374        records.forEach(function(record) {
 8375          this.manager.recordArraysForRecord(record).add(this);
 8376        }, this);
 8377
 8378        // TODO: should triggering didLoad event be the last action of the runLoop?
 8379        Ember.run.once(this, 'trigger', 'didLoad');
 8380      }
 8381    });
 8382  });
 8383define("ember-data/system/record_arrays/filtered_record_array",
 8384  ["ember-data/system/record_arrays/record_array","exports"],
 8385  function(__dependency1__, __exports__) {
 8386    "use strict";
 8387    var RecordArray = __dependency1__["default"];
 8388
 8389    /**
 8390      @module ember-data
 8391    */
 8392
 8393    var get = Ember.get;
 8394
 8395    /**
 8396      Represents a list of records whose membership is determined by the
 8397      store. As records are created, loaded, or modified, the store
 8398      evaluates them to determine if they should be part of the record
 8399      array.
 8400
 8401      @class FilteredRecordArray
 8402      @namespace DS
 8403      @extends DS.RecordArray
 8404    */
 8405    __exports__["default"] = RecordArray.extend({
 8406      /**
 8407        The filterFunction is a function used to test records from the store to
 8408        determine if they should be part of the record array.
 8409
 8410        Example
 8411
 8412        ```javascript
 8413        var allPeople = store.all('person');
 8414        allPeople.mapBy('name'); // ["Tom Dale", "Yehuda Katz", "Trek Glowacki"]
 8415
 8416        var people = store.filter('person', function(person) {
 8417          if (person.get('name').match(/Katz$/)) { return true; }
 8418        });
 8419        people.mapBy('name'); // ["Yehuda Katz"]
 8420
 8421        var notKatzFilter = function(person) {
 8422          return !person.get('name').match(/Katz$/);
 8423        };
 8424        people.set('filterFunction', notKatzFilter);
 8425        people.mapBy('name'); // ["Tom Dale", "Trek Glowacki"]
 8426        ```
 8427
 8428        @method filterFunction
 8429        @param {DS.Model} record
 8430        @return {Boolean} `true` if the record should be in the array
 8431      */
 8432      filterFunction: null,
 8433      isLoaded: true,
 8434
 8435      replace: function() {
 8436        var type = get(this, 'type').toString();
 8437        throw new Error("The result of a client-side filter (on " + type + ") is immutable.");
 8438      },
 8439
 8440      /**
 8441        @method updateFilter
 8442        @private
 8443      */
 8444      _updateFilter: function() {
 8445        var manager = get(this, 'manager');
 8446        manager.updateFilter(this, get(this, 'type'), get(this, 'filterFunction'));
 8447      },
 8448
 8449      updateFilter: Ember.observer(function() {
 8450        Ember.run.once(this, this._updateFilter);
 8451      }, 'filterFunction')
 8452    });
 8453  });
 8454define("ember-data/system/record_arrays/many_array",
 8455  ["ember-data/system/record_arrays/record_array","exports"],
 8456  function(__dependency1__, __exports__) {
 8457    "use strict";
 8458    var RecordArray = __dependency1__["default"];
 8459
 8460    /**
 8461      @module ember-data
 8462    */
 8463
 8464    var get = Ember.get, set = Ember.set;
 8465
 8466    /**
 8467      A `ManyArray` is a `RecordArray` that represents the contents of a has-many
 8468      relationship.
 8469
 8470      The `ManyArray` is instantiated lazily the first time the relationship is
 8471      requested.
 8472
 8473      ### Inverses
 8474
 8475      Often, the relationships in Ember Data applications will have
 8476      an inverse. For example, imagine the following models are
 8477      defined:
 8478
 8479      ```javascript
 8480      App.Post = DS.Model.extend({
 8481        comments: DS.hasMany('comment')
 8482      });
 8483
 8484      App.Comment = DS.Model.extend({
 8485        post: DS.belongsTo('post')
 8486      });
 8487      ```
 8488
 8489      If you created a new instance of `App.Post` and added
 8490      a `App.Comment` record to its `comments` has-many
 8491      relationship, you would expect the comment's `post`
 8492      property to be set to the post that contained
 8493      the has-many.
 8494
 8495      We call the record to which a relationship belongs the
 8496      relationship's _owner_.
 8497
 8498      @class ManyArray
 8499      @namespace DS
 8500      @extends DS.RecordArray
 8501    */
 8502    __exports__["default"] = RecordArray.extend({
 8503      init: function() {
 8504        this._super.apply(this, arguments);
 8505      },
 8506
 8507      /**
 8508        `true` if the relationship is polymorphic, `false` otherwise.
 8509
 8510        @property {Boolean} isPolymorphic
 8511        @private
 8512      */
 8513      isPolymorphic: false,
 8514
 8515      // LOADING STATE
 8516
 8517      isLoaded: false,
 8518
 8519       /**
 8520         The relationship which manages this array.
 8521
 8522         @property {DS.Model} owner
 8523         @private
 8524       */
 8525
 8526      relationship: null,
 8527
 8528
 8529      /**
 8530        Used for async `hasMany` arrays
 8531        to keep track of when they will resolve.
 8532
 8533        @property {Ember.RSVP.Promise} promise
 8534        @private
 8535      */
 8536      promise: null,
 8537
 8538      /**
 8539        @method loadingRecordsCount
 8540        @param {Number} count
 8541        @private
 8542      */
 8543      loadingRecordsCount: function(count) {
 8544        this.loadingRecordsCount = count;
 8545      },
 8546
 8547      /**
 8548        @method loadedRecord
 8549        @private
 8550      */
 8551      loadedRecord: function() {
 8552        this.loadingRecordsCount--;
 8553        if (this.loadingRecordsCount === 0) {
 8554          set(this, 'isLoaded', true);
 8555          this.trigger('didLoad');
 8556        }
 8557      },
 8558
 8559      replaceContent: function(idx, amt, objects){
 8560        var records;
 8561        if (amt > 0){
 8562          records = get(this, 'content').slice(idx, idx+amt);
 8563          this.get('relationship').removeRecords(records);
 8564        }
 8565        if (objects){
 8566          this.get('relationship').addRecords(objects, idx);
 8567        }
 8568      },
 8569      /**
 8570        @method reload
 8571        @public
 8572      */
 8573      reload: function() {
 8574        return this.relationship.reload();
 8575      },
 8576
 8577      /**
 8578        Create a child record within the owner
 8579
 8580        @method createRecord
 8581        @private
 8582        @param {Object} hash
 8583        @return {DS.Model} record
 8584      */
 8585      createRecord: function(hash) {
 8586        var store = get(this, 'store');
 8587        var type = get(this, 'type');
 8588        var record;
 8589
 8590        Ember.assert("You cannot add '" + type.typeKey + "' records to this polymorphic relationship.", !get(this, 'isPolymorphic'));
 8591
 8592        record = store.createRecord.call(store, type, hash);
 8593        this.pushObject(record);
 8594
 8595        return record;
 8596      }
 8597    });
 8598  });
 8599define("ember-data/system/record_arrays/record_array",
 8600  ["ember-data/system/promise_proxies","exports"],
 8601  function(__dependency1__, __exports__) {
 8602    "use strict";
 8603    /**
 8604      @module ember-data
 8605    */
 8606
 8607    var PromiseArray = __dependency1__.PromiseArray;
 8608    var get = Ember.get;
 8609
 8610    /**
 8611      A record array is an array that contains records of a certain type. The record
 8612      array materializes records as needed when they are retrieved for the first
 8613      time. You should not create record arrays yourself. Instead, an instance of
 8614      `DS.RecordArray` or its subclasses will be returned by your application's store
 8615      in response to queries.
 8616
 8617      @class RecordArray
 8618      @namespace DS
 8619      @extends Ember.ArrayProxy
 8620      @uses Ember.Evented
 8621    */
 8622
 8623    __exports__["default"] = Ember.ArrayProxy.extend(Ember.Evented, {
 8624      /**
 8625        The model type contained by this record array.
 8626
 8627        @property type
 8628        @type DS.Model
 8629      */
 8630      type: null,
 8631
 8632      /**
 8633        The array of client ids backing the record array. When a
 8634        record is requested from the record array, the record
 8635        for the client id at the same index is materialized, if
 8636        necessary, by the store.
 8637
 8638        @property content
 8639        @private
 8640        @type Ember.Array
 8641      */
 8642      content: null,
 8643
 8644      /**
 8645        The flag to signal a `RecordArray` is currently loading data.
 8646
 8647        Example
 8648
 8649        ```javascript
 8650        var people = store.all('person');
 8651        people.get('isLoaded'); // true
 8652        ```
 8653
 8654        @property isLoaded
 8655        @type Boolean
 8656      */
 8657      isLoaded: false,
 8658      /**
 8659        The flag to signal a `RecordArray` is currently loading data.
 8660
 8661        Example
 8662
 8663        ```javascript
 8664        var people = store.all('person');
 8665        people.get('isUpdating'); // false
 8666        people.update();
 8667        people.get('isUpdating'); // true
 8668        ```
 8669
 8670        @property isUpdating
 8671        @type Boolean
 8672      */
 8673      isUpdating: false,
 8674
 8675      /**
 8676        The store that created this record array.
 8677
 8678        @property store
 8679        @private
 8680        @type DS.Store
 8681      */
 8682      store: null,
 8683
 8684      /**
 8685        Retrieves an object from the content by index.
 8686
 8687        @method objectAtContent
 8688        @private
 8689        @param {Number} index
 8690        @return {DS.Model} record
 8691      */
 8692      objectAtContent: function(index) {
 8693        var content = get(this, 'content');
 8694
 8695        return content.objectAt(index);
 8696      },
 8697
 8698      /**
 8699        Used to get the latest version of all of the records in this array
 8700        from the adapter.
 8701
 8702        Example
 8703
 8704        ```javascript
 8705        var people = store.all('person');
 8706        people.get('isUpdating'); // false
 8707        people.update();
 8708        people.get('isUpdating'); // true
 8709        ```
 8710
 8711        @method update
 8712      */
 8713      update: function() {
 8714        if (get(this, 'isUpdating')) { return; }
 8715
 8716        var store = get(this, 'store');
 8717        var type = get(this, 'type');
 8718
 8719        return store.fetchAll(type, this);
 8720      },
 8721
 8722      /**
 8723        Adds a record to the `RecordArray` without duplicates
 8724
 8725        @method addRecord
 8726        @private
 8727        @param {DS.Model} record
 8728        @param {DS.Model} an optional index to insert at
 8729      */
 8730      addRecord: function(record, idx) {
 8731        var content = get(this, 'content');
 8732        if (idx === undefined) {
 8733          content.addObject(record);
 8734        } else {
 8735          if (!content.contains(record)) {
 8736           content.insertAt(idx, record);
 8737          }
 8738        }
 8739      },
 8740
 8741      /**
 8742        Adds a record to the `RecordArray`, but allows duplicates
 8743
 8744        @method pushRecord
 8745        @private
 8746        @param {DS.Model} record
 8747      */
 8748      pushRecord: function(record) {
 8749        get(this, 'content').pushObject(record);
 8750      },
 8751
 8752
 8753      /**
 8754        Removes a record to the `RecordArray`.
 8755
 8756        @method removeRecord
 8757        @private
 8758        @param {DS.Model} record
 8759      */
 8760      removeRecord: function(record) {
 8761        get(this, 'content').removeObject(record);
 8762      },
 8763
 8764      /**
 8765        Saves all of the records in the `RecordArray`.
 8766
 8767        Example
 8768
 8769        ```javascript
 8770        var messages = store.all('message');
 8771        messages.forEach(function(message) {
 8772          message.set('hasBeenSeen', true);
 8773        });
 8774        messages.save();
 8775        ```
 8776
 8777        @method save
 8778        @return {DS.PromiseArray} promise
 8779      */
 8780      save: function() {
 8781        var promiseLabel = "DS: RecordArray#save " + get(this, 'type');
 8782        var promise = Ember.RSVP.all(this.invoke("save"), promiseLabel).then(function(array) {
 8783          return Ember.A(array);
 8784        }, null, "DS: RecordArray#save apply Ember.NativeArray");
 8785
 8786        return PromiseArray.create({ promise: promise });
 8787      },
 8788
 8789      _dissociateFromOwnRecords: function() {
 8790        var array = this;
 8791
 8792        this.forEach(function(record){
 8793          var recordArrays = record._recordArrays;
 8794
 8795          if (recordArrays) {
 8796            recordArrays["delete"](array);
 8797          }
 8798        });
 8799      },
 8800
 8801      willDestroy: function(){
 8802        this._dissociateFromOwnRecords();
 8803        this._super();
 8804      }
 8805    });
 8806  });
 8807define("ember-data/system/relationship-meta",
 8808  ["ember-inflector/system","exports"],
 8809  function(__dependency1__, __exports__) {
 8810    "use strict";
 8811    var singularize = __dependency1__.singularize;
 8812
 8813    function typeForRelationshipMeta(store, meta) {
 8814      var typeKey, type;
 8815
 8816      typeKey = meta.type || meta.key;
 8817      if (typeof typeKey === 'string') {
 8818        if (meta.kind === 'hasMany') {
 8819          typeKey = singularize(typeKey);
 8820        }
 8821        type = store.modelFor(typeKey);
 8822      } else {
 8823        type = meta.type;
 8824      }
 8825
 8826      return type;
 8827    }
 8828
 8829    __exports__.typeForRelationshipMeta = typeForRelationshipMeta;function relationshipFromMeta(store, meta) {
 8830      return {
 8831        key:  meta.key,
 8832        kind: meta.kind,
 8833        type: typeForRelationshipMeta(store, meta),
 8834        options:    meta.options,
 8835        parentType: meta.parentType,
 8836        isRelationship: true
 8837      };
 8838    }
 8839
 8840    __exports__.relationshipFromMeta = relationshipFromMeta;
 8841  });
 8842define("ember-data/system/relationships",
 8843  ["./relationships/belongs_to","./relationships/has_many","ember-data/system/relationships/ext","exports"],
 8844  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
 8845    "use strict";
 8846    /**
 8847      @module ember-data
 8848    */
 8849
 8850    var belongsTo = __dependency1__["default"];
 8851    var hasMany = __dependency2__["default"];
 8852
 8853
 8854    __exports__.belongsTo = belongsTo;
 8855    __exports__.hasMany = hasMany;
 8856  });
 8857define("ember-data/system/relationships/belongs_to",
 8858  ["ember-data/system/model","exports"],
 8859  function(__dependency1__, __exports__) {
 8860    "use strict";
 8861    var Model = __dependency1__.Model;
 8862
 8863
 8864    /**
 8865      `DS.belongsTo` is used to define One-To-One and One-To-Many
 8866      relationships on a [DS.Model](/api/data/classes/DS.Model.html).
 8867
 8868
 8869      `DS.belongsTo` takes an optional hash as a second parameter, currently
 8870      supported options are:
 8871
 8872      - `async`: A boolean value used to explicitly declare this to be an async relationship.
 8873      - `inverse`: A string used to identify the inverse property on a
 8874        related model in a One-To-Many relationship. See [Explicit Inverses](#toc_explicit-inverses)
 8875
 8876      #### One-To-One
 8877      To declare a one-to-one relationship between two models, use
 8878      `DS.belongsTo`:
 8879
 8880      ```javascript
 8881      App.User = DS.Model.extend({
 8882        profile: DS.belongsTo('profile')
 8883      });
 8884
 8885      App.Profile = DS.Model.extend({
 8886        user: DS.belongsTo('user')
 8887      });
 8888      ```
 8889
 8890      #### One-To-Many
 8891      To declare a one-to-many relationship between two models, use
 8892      `DS.belongsTo` in combination with `DS.hasMany`, like this:
 8893
 8894      ```javascript
 8895      App.Post = DS.Model.extend({
 8896        comments: DS.hasMany('comment')
 8897      });
 8898
 8899      App.Comment = DS.Model.extend({
 8900        post: DS.belongsTo('post')
 8901      });
 8902      ```
 8903
 8904      @namespace
 8905      @method belongsTo
 8906      @for DS
 8907      @param {String or DS.Model} type the model type of the relationship
 8908      @param {Object} options a hash of options
 8909      @return {Ember.computed} relationship
 8910    */
 8911    function belongsTo(type, options) {
 8912      if (typeof type === 'object') {
 8913        options = type;
 8914        type = undefined;
 8915      } else {
 8916        Ember.assert("The first argument to DS.belongsTo must be a string representing a model type key, e.g. use DS.belongsTo('person') to define a relation to the App.Person model", !!type && (typeof type === 'string' || Model.detect(type)));
 8917      }
 8918
 8919      options = options || {};
 8920
 8921      var meta = {
 8922        type: type,
 8923        isRelationship: true,
 8924        options: options,
 8925        kind: 'belongsTo',
 8926        key: null
 8927      };
 8928
 8929      return Ember.computed(function(key, value) {
 8930        if (arguments.length>1) {
 8931          if ( value === undefined ) {
 8932            value = null;
 8933          }
 8934          if (value && value.then) {
 8935            this._relationships[key].setRecordPromise(value);
 8936          } else {
 8937            this._relationships[key].setRecord(value);
 8938          }
 8939        }
 8940
 8941        return this._relationships[key].getRecord();
 8942      }).meta(meta);
 8943    }
 8944
 8945    /**
 8946      These observers observe all `belongsTo` relationships on the record. See
 8947      `relationships/ext` to see how these observers get their dependencies.
 8948
 8949      @class Model
 8950      @namespace DS
 8951    */
 8952    Model.reopen({
 8953      notifyBelongsToAdded: function(key, relationship) {
 8954        this.notifyPropertyChange(key);
 8955      },
 8956
 8957      notifyBelongsToRemoved: function(key) {
 8958        this.notifyPropertyChange(key);
 8959      }
 8960    });
 8961
 8962    __exports__["default"] = belongsTo;
 8963  });
 8964define("ember-data/system/relationships/ext",
 8965  ["ember-data/system/relationship-meta","ember-data/system/model","ember-data/system/map"],
 8966  function(__dependency1__, __dependency2__, __dependency3__) {
 8967    "use strict";
 8968    var typeForRelationshipMeta = __dependency1__.typeForRelationshipMeta;
 8969    var relationshipFromMeta = __dependency1__.relationshipFromMeta;
 8970    var Model = __dependency2__.Model;
 8971    var Map = __dependency3__.Map;
 8972    var MapWithDefault = __dependency3__.MapWithDefault;
 8973
 8974    var get = Ember.get;
 8975    var filter = Ember.ArrayPolyfills.filter;
 8976
 8977    /**
 8978      @module ember-data
 8979    */
 8980
 8981    /*
 8982      This file defines several extensions to the base `DS.Model` class that
 8983      add support for one-to-many relationships.
 8984    */
 8985
 8986    /**
 8987      @class Model
 8988      @namespace DS
 8989    */
 8990    Model.reopen({
 8991
 8992      /**
 8993        This Ember.js hook allows an object to be notified when a property
 8994        is defined.
 8995
 8996        In this case, we use it to be notified when an Ember Data user defines a
 8997        belongs-to relationship. In that case, we need to set up observers for
 8998        each one, allowing us to track relationship changes and automatically
 8999        reflect changes in the inverse has-many array.
 9000
 9001        This hook passes the class being set up, as well as the key and value
 9002        being defined. So, for example, when the user does this:
 9003
 9004        ```javascript
 9005        DS.Model.extend({
 9006          parent: DS.belongsTo('user')
 9007        });
 9008        ```
 9009
 9010        This hook would be called with "parent" as the key and the computed
 9011        property returned by `DS.belongsTo` as the value.
 9012
 9013        @method didDefineProperty
 9014        @param {Object} proto
 9015        @param {String} key
 9016        @param {Ember.ComputedProperty} value
 9017      */
 9018      didDefineProperty: function(proto, key, value) {
 9019        // Check if the value being set is a computed property.
 9020        if (value instanceof Ember.ComputedProperty) {
 9021
 9022          // If it is, get the metadata for the relationship. This is
 9023          // populated by the `DS.belongsTo` helper when it is creating
 9024          // the computed property.
 9025          var meta = value.meta();
 9026
 9027          meta.parentType = proto.constructor;
 9028        }
 9029      }
 9030    });
 9031
 9032    /*
 9033      These DS.Model extensions add class methods that provide relationship
 9034      introspection abilities about relationships.
 9035
 9036      A note about the computed properties contained here:
 9037
 9038      **These properties are effectively sealed once called for the first time.**
 9039      To avoid repeatedly doing expensive iteration over a model's fields, these
 9040      values are computed once and then cached for the remainder of the runtime of
 9041      your application.
 9042
 9043      If your application needs to modify a class after its initial definition
 9044      (for example, using `reopen()` to add additional attributes), make sure you
 9045      do it before using your model with the store, which uses these properties
 9046      extensively.
 9047    */
 9048
 9049    Model.reopenClass({
 9050
 9051      /**
 9052        For a given relationship name, returns the model type of the relationship.
 9053
 9054        For example, if you define a model like this:
 9055
 9056       ```javascript
 9057        App.Post = DS.Model.extend({
 9058          comments: DS.hasMany('comment')
 9059        });
 9060       ```
 9061
 9062        Calling `App.Post.typeForRelationship('comments')` will return `App.Comment`.
 9063
 9064        @method typeForRelationship
 9065        @static
 9066        @param {String} name the name of the relationship
 9067        @return {subclass of DS.Model} the type of the relationship, or undefined
 9068      */
 9069      typeForRelationship: function(name) {
 9070        var relationship = get(this, 'relationshipsByName').get(name);
 9071        return relationship && relationship.type;
 9072      },
 9073
 9074      inverseMap: Ember.computed(function() {
 9075        return Object.create(null);
 9076      }),
 9077
 9078      /*
 9079        Find the relationship which is the inverse of the one asked for.
 9080
 9081        For example, if you define models like this:
 9082
 9083       ```javascript
 9084          App.Post = DS.Model.extend({
 9085            comments: DS.hasMany('message')
 9086          });
 9087
 9088          App.Message = DS.Model.extend({
 9089            owner: DS.belongsTo('post')
 9090          });
 9091        ```
 9092
 9093        App.Post.inverseFor('comments') -> {type: App.Message, name:'owner', kind:'belongsTo'}
 9094        App.Message.inverseFor('owner') -> {type: App.Post, name:'comments', kind:'hasMany'}
 9095
 9096        @method inverseFor
 9097        @static
 9098        @param {String} name the name of the relationship
 9099        @return {Object} the inverse relationship, or null
 9100      */
 9101      inverseFor: function(name) {
 9102        var inverseMap = get(this, 'inverseMap');
 9103        if (inverseMap[name]) {
 9104          return inverseMap[name];
 9105        } else {
 9106          var inverse = this._findInverseFor(name);
 9107          inverseMap[name] = inverse;
 9108          return inverse;
 9109        }
 9110      },
 9111
 9112      //Calculate the inverse, ignoring the cache
 9113      _findInverseFor: function(name) {
 9114
 9115        var inverseType = this.typeForRelationship(name);
 9116        if (!inverseType) {
 9117          return null;
 9118        }
 9119
 9120        //If inverse is manually specified to be null, like  `comments: DS.hasMany('message', {inverse: null})`
 9121        var options = this.metaForProperty(name).options;
 9122        if (options.inverse === null) { return null; }
 9123
 9124        var inverseName, inverseKind, inverse;
 9125
 9126        //If inverse is specified manually, return the inverse
 9127        if (options.inverse) {
 9128          inverseName = options.inverse;
 9129          inverse = Ember.get(inverseType, 'relationshipsByName').get(inverseName);
 9130
 9131          Ember.assert("We found no inverse relationships by the name of '" + inverseName + "' on the '" + inverseType.typeKey +
 9132            "' model. This is most likely due to a missing attribute on your model definition.", !Ember.isNone(inverse));
 9133
 9134          inverseKind = inverse.kind;
 9135        } else {
 9136          //No inverse was specified manually, we need to use a heuristic to guess one
 9137          var possibleRelationships = findPossibleInverses(this, inverseType);
 9138
 9139          if (possibleRelationships.length === 0) { return null; }
 9140
 9141          var filteredRelationships = filter.call(possibleRelationships, function(possibleRelationship) {
 9142            var optionsForRelationship = inverseType.metaForProperty(possibleRelationship.name).options;
 9143            return name === optionsForRelationship.inverse;
 9144          });
 9145
 9146          Ember.assert("You defined the '" + name + "' relationship on " + this + ", but you defined the inverse relationships of type " +
 9147            inverseType.toString() + " multiple times. Look at http://emberjs.com/guides/models/defining-models/#toc_explicit-inverses for how to explicitly specify inverses",
 9148            filteredRelationships.length < 2);
 9149
 9150          if (filteredRelationships.length === 1 ) {
 9151            possibleRelationships = filteredRelationships;
 9152          }
 9153
 9154          Ember.assert("You defined the '" + name + "' relationship on " + this + ", but multiple possible inverse relationships of type " +
 9155            this + " were found on " + inverseType + ". Look at http://emberjs.com/guides/models/defining-models/#toc_explicit-inverses for how to explicitly specify inverses",
 9156            possibleRelationships.length === 1);
 9157
 9158          inverseName = possibleRelationships[0].name;
 9159          inverseKind = possibleRelationships[0].kind;
 9160        }
 9161
 9162        function findPossibleInverses(type, inverseType, relationshipsSoFar) {
 9163          var possibleRelationships = relationshipsSoFar || [];
 9164
 9165          var relationshipMap = get(inverseType, 'relationships');
 9166          if (!relationshipMap) { return; }
 9167
 9168          var relationships = relationshipMap.get(type);
 9169
 9170          relationships = filter.call(relationships, function(relationship) {
 9171            var optionsForRelationship = inverseType.metaForProperty(relationship.name).options;
 9172
 9173            if (!optionsForRelationship.inverse){
 9174              return true;
 9175            }
 9176
 9177            return name === optionsForRelationship.inverse;
 9178          });
 9179
 9180          if (relationships) {
 9181            possibleRelationships.push.apply(possibleRelationships, relationships);
 9182          }
 9183
 9184          //Recurse to support polymorphism
 9185          if (type.superclass) {
 9186            findPossibleInverses(type.superclass, inverseType, possibleRelationships);
 9187          }
 9188
 9189          return possibleRelationships;
 9190        }
 9191
 9192        return {
 9193          type: inverseType,
 9194          name: inverseName,
 9195          kind: inverseKind
 9196        };
 9197      },
 9198
 9199      /**
 9200        The model's relationships as a map, keyed on the type of the
 9201        relationship. The value of each entry is an array containing a descriptor
 9202        for each relationship with that type, describing the name of the relationship
 9203        as well as the type.
 9204
 9205        For example, given the following model definition:
 9206
 9207        ```javascript
 9208        App.Blog = DS.Model.extend({
 9209          users: DS.hasMany('user'),
 9210          owner: DS.belongsTo('user'),
 9211          posts: DS.hasMany('post')
 9212        });
 9213        ```
 9214
 9215        This computed property would return a map describing these
 9216        relationships, like this:
 9217
 9218        ```javascript
 9219        var relationships = Ember.get(App.Blog, 'relationships');
 9220        relationships.get(App.User);
 9221        //=> [ { name: 'users', kind: 'hasMany' },
 9222        //     { name: 'owner', kind: 'belongsTo' } ]
 9223        relationships.get(App.Post);
 9224        //=> [ { name: 'posts', kind: 'hasMany' } ]
 9225        ```
 9226
 9227        @property relationships
 9228        @static
 9229        @type Ember.Map
 9230        @readOnly
 9231      */
 9232      relationships: Ember.computed(function() {
 9233        var map = new MapWithDefault({
 9234          defaultValue: function() { return []; }
 9235        });
 9236
 9237        // Loop through each computed property on the class
 9238        this.eachComputedProperty(function(name, meta) {
 9239          // If the computed property is a relationship, add
 9240          // it to the map.
 9241          if (meta.isRelationship) {
 9242            meta.key = name;
 9243            var relationshipsForType = map.get(typeForRelationshipMeta(this.store, meta));
 9244
 9245            relationshipsForType.push({
 9246              name: name,
 9247              kind: meta.kind
 9248            });
 9249          }
 9250        });
 9251
 9252        return map;
 9253      }).cacheable(false).readOnly(),
 9254
 9255      /**
 9256        A hash containing lists of the model's relationships, grouped
 9257        by the relationship kind. For example, given a model with this
 9258        definition:
 9259
 9260        ```javascript
 9261        App.Blog = DS.Model.extend({
 9262          users: DS.hasMany('user'),
 9263          owner: DS.belongsTo('user'),
 9264
 9265          posts: DS.hasMany('post')
 9266        });
 9267        ```
 9268
 9269        This property would contain the following:
 9270
 9271        ```javascript
 9272        var relationshipNames = Ember.get(App.Blog, 'relationshipNames');
 9273        relationshipNames.hasMany;
 9274        //=> ['users', 'posts']
 9275        relationshipNames.belongsTo;
 9276        //=> ['owner']
 9277        ```
 9278
 9279        @property relationshipNames
 9280        @static
 9281        @type Object
 9282        @readOnly
 9283      */
 9284      relationshipNames: Ember.computed(function() {
 9285        var names = {
 9286          hasMany: [],
 9287          belongsTo: []
 9288        };
 9289
 9290        this.eachComputedProperty(function(name, meta) {
 9291          if (meta.isRelationship) {
 9292            names[meta.kind].push(name);
 9293          }
 9294        });
 9295
 9296        return names;
 9297      }),
 9298
 9299      /**
 9300        An array of types directly related to a model. Each type will be
 9301        included once, regardless of the number of relationships it has with
 9302        the model.
 9303
 9304        For example, given a model with this definition:
 9305
 9306        ```javascript
 9307        App.Blog = DS.Model.extend({
 9308          users: DS.hasMany('user'),
 9309          owner: DS.belongsTo('user'),
 9310
 9311          posts: DS.hasMany('post')
 9312        });
 9313        ```
 9314
 9315        This property would contain the following:
 9316
 9317        ```javascript
 9318        var relatedTypes = Ember.get(App.Blog, 'relatedTypes');
 9319        //=> [ App.User, App.Post ]
 9320        ```
 9321
 9322        @property relatedTypes
 9323        @static
 9324        @type Ember.Array
 9325        @readOnly
 9326      */
 9327      relatedTypes: Ember.computed(function() {
 9328        var type;
 9329        var types = Ember.A();
 9330
 9331        // Loop through each computed property on the class,
 9332        // and create an array of the unique types involved
 9333        // in relationships
 9334        this.eachComputedProperty(function(name, meta) {
 9335          if (meta.isRelationship) {
 9336            meta.key = name;
 9337            type = typeForRelationshipMeta(this.store, meta);
 9338
 9339            Ember.assert("You specified a hasMany (" + meta.type + ") on " + meta.parentType + " but " + meta.type + " was not found.",  type);
 9340
 9341            if (!types.contains(type)) {
 9342              Ember.assert("Trying to sideload " + name + " on " + this.toString() + " but the type doesn't exist.", !!type);
 9343              types.push(type);
 9344            }
 9345          }
 9346        });
 9347
 9348        return types;
 9349      }).cacheable(false).readOnly(),
 9350
 9351      /**
 9352        A map whose keys are the relationships of a model and whose values are
 9353        relationship descriptors.
 9354
 9355        For example, given a model with this
 9356        definition:
 9357
 9358        ```javascript
 9359        App.Blog = DS.Model.extend({
 9360          users: DS.hasMany('user'),
 9361          owner: DS.belongsTo('user'),
 9362
 9363          posts: DS.hasMany('post')
 9364        });
 9365        ```
 9366
 9367        This property would contain the following:
 9368
 9369        ```javascript
 9370        var relationshipsByName = Ember.get(App.Blog, 'relationshipsByName');
 9371        relationshipsByName.get('users');
 9372        //=> { key: 'users', kind: 'hasMany', type: App.User }
 9373        relationshipsByName.get('owner');
 9374        //=> { key: 'owner', kind: 'belongsTo', type: App.User }
 9375        ```
 9376
 9377        @property relationshipsByName
 9378        @static
 9379        @type Ember.Map
 9380        @readOnly
 9381      */
 9382      relationshipsByName: Ember.computed(function() {
 9383        var map = Map.create();
 9384
 9385        this.eachComputedProperty(function(name, meta) {
 9386          if (meta.isRelationship) {
 9387            meta.key = name;
 9388            var relationship = relationshipFromMeta(this.store, meta);
 9389            relationship.type = typeForRelationshipMeta(this.store, meta);
 9390            map.set(name, relationship);
 9391          }
 9392        });
 9393
 9394        return map;
 9395      }).cacheable(false).readOnly(),
 9396
 9397      /**
 9398        A map whose keys are the fields of the model and whose values are strings
 9399        describing the kind of the field. A model's fields are the union of all of its
 9400        attributes and relationships.
 9401
 9402        For example:
 9403
 9404        ```javascript
 9405
 9406        App.Blog = DS.Model.extend({
 9407          users: DS.hasMany('user'),
 9408          owner: DS.belongsTo('user'),
 9409
 9410          posts: DS.hasMany('post'),
 9411
 9412          title: DS.attr('string')
 9413        });
 9414
 9415        var fields = Ember.get(App.Blog, 'fields');
 9416        fields.forEach(function(field, kind) {
 9417          console.log(field, kind);
 9418        });
 9419
 9420        // prints:
 9421        // users, hasMany
 9422        // owner, belongsTo
 9423        // posts, hasMany
 9424        // title, attribute
 9425        ```
 9426
 9427        @property fields
 9428        @static
 9429        @type Ember.Map
 9430        @readOnly
 9431      */
 9432      fields: Ember.computed(function() {
 9433        var map = Map.create();
 9434
 9435        this.eachComputedProperty(function(name, meta) {
 9436          if (meta.isRelationship) {
 9437            map.set(name, meta.kind);
 9438          } else if (meta.isAttribute) {
 9439            map.set(name, 'attribute');
 9440          }
 9441        });
 9442
 9443        return map;
 9444      }).readOnly(),
 9445
 9446      /**
 9447        Given a callback, iterates over each of the relationships in the model,
 9448        invoking the callback with the name of each relationship and its relationship
 9449        descriptor.
 9450
 9451        @method eachRelationship
 9452        @static
 9453        @param {Function} callback the callback to invoke
 9454        @param {any} binding the value to which the callback's `this` should be bound
 9455      */
 9456      eachRelationship: function(callback, binding) {
 9457        get(this, 'relationshipsByName').forEach(function(relationship, name) {
 9458          callback.call(binding, name, relationship);
 9459        });
 9460      },
 9461
 9462      /**
 9463        Given a callback, iterates over each of the types related to a model,
 9464        invoking the callback with the related type's class. Each type will be
 9465        returned just once, regardless of how many different relationships it has
 9466        with a model.
 9467
 9468        @method eachRelatedType
 9469        @static
 9470        @param {Function} callback the callback to invoke
 9471        @param {any} binding the value to which the callback's `this` should be bound
 9472      */
 9473      eachRelatedType: function(callback, binding) {
 9474        get(this, 'relatedTypes').forEach(function(type) {
 9475          callback.call(binding, type);
 9476        });
 9477      },
 9478
 9479      determineRelationshipType: function(knownSide) {
 9480        var knownKey = knownSide.key;
 9481        var knownKind = knownSide.kind;
 9482        var inverse = this.inverseFor(knownKey);
 9483        var key, otherKind;
 9484
 9485        if (!inverse) {
 9486          return knownKind === 'belongsTo' ? 'oneToNone' : 'manyToNone';
 9487        }
 9488
 9489        key = inverse.name;
 9490        otherKind = inverse.kind;
 9491
 9492        if (otherKind === 'belongsTo') {
 9493          return knownKind === 'belongsTo' ? 'oneToOne' : 'manyToOne';
 9494        } else {
 9495          return knownKind === 'belongsTo' ? 'oneToMany' : 'manyToMany';
 9496        }
 9497      }
 9498
 9499    });
 9500
 9501    Model.reopen({
 9502      /**
 9503        Given a callback, iterates over each of the relationships in the model,
 9504        invoking the callback with the name of each relationship and its relationship
 9505        descriptor.
 9506
 9507        @method eachRelationship
 9508        @param {Function} callback the callback to invoke
 9509        @param {any} binding the value to which the callback's `this` should be bound
 9510      */
 9511      eachRelationship: function(callback, binding) {
 9512        this.constructor.eachRelationship(callback, binding);
 9513      },
 9514
 9515      relationshipFor: function(name) {
 9516        return get(this.constructor, 'relationshipsByName').get(name);
 9517      },
 9518
 9519      inverseFor: function(key) {
 9520        return this.constructor.inverseFor(key);
 9521      }
 9522
 9523    });
 9524  });
 9525define("ember-data/system/relationships/has_many",
 9526  ["ember-data/system/model","exports"],
 9527  function(__dependency1__, __exports__) {
 9528    "use strict";
 9529    /**
 9530      @module ember-data
 9531    */
 9532
 9533    var Model = __dependency1__.Model;
 9534
 9535    /**
 9536      `DS.hasMany` is used to define One-To-Many and Many-To-Many
 9537      relationships on a [DS.Model](/api/data/classes/DS.Model.html).
 9538
 9539      `DS.hasMany` takes an optional hash as a second parameter, currently
 9540      supported options are:
 9541
 9542      - `async`: A boolean value used to explicitly declare this to be an async relationship.
 9543      - `inverse`: A string used to identify the inverse property on a related model.
 9544
 9545      #### One-To-Many
 9546      To declare a one-to-many relationship between two models, use
 9547      `DS.belongsTo` in combination with `DS.hasMany`, like this:
 9548
 9549      ```javascript
 9550      App.Post = DS.Model.extend({
 9551        comments: DS.hasMany('comment')
 9552      });
 9553
 9554      App.Comment = DS.Model.extend({
 9555        post: DS.belongsTo('post')
 9556      });
 9557      ```
 9558
 9559      #### Many-To-Many
 9560      To declare a many-to-many relationship between two models, use
 9561      `DS.hasMany`:
 9562
 9563      ```javascript
 9564      App.Post = DS.Model.extend({
 9565        tags: DS.hasMany('tag')
 9566      });
 9567
 9568      App.Tag = DS.Model.extend({
 9569        posts: DS.hasMany('post')
 9570      });
 9571      ```
 9572
 9573      #### Explicit Inverses
 9574
 9575      Ember Data will do its best to discover which relationships map to
 9576      one another. In the one-to-many code above, for example, Ember Data
 9577      can figure out that changing the `comments` relationship should update
 9578      the `post` relationship on the inverse because post is the only
 9579      relationship to that model.
 9580
 9581      However, sometimes you may have multiple `belongsTo`/`hasManys` for the
 9582      same type. You can specify which property on the related model is
 9583      the inverse using `DS.hasMany`'s `inverse` option:
 9584
 9585      ```javascript
 9586      var belongsTo = DS.belongsTo,
 9587          hasMany = DS.hasMany;
 9588
 9589      App.Comment = DS.Model.extend({
 9590        onePost: belongsTo('post'),
 9591        twoPost: belongsTo('post'),
 9592        redPost: belongsTo('post'),
 9593        bluePost: belongsTo('post')
 9594      });
 9595
 9596      App.Post = DS.Model.extend({
 9597        comments: hasMany('comment', {
 9598          inverse: 'redPost'
 9599        })
 9600      });
 9601      ```
 9602
 9603      You can also specify an inverse on a `belongsTo`, which works how
 9604      you'd expect.
 9605
 9606      @namespace
 9607      @method hasMany
 9608      @for DS
 9609      @param {String or DS.Model} type the model type of the relationship
 9610      @param {Object} options a hash of options
 9611      @return {Ember.computed} relationship
 9612    */
 9613    function hasMany(type, options) {
 9614      if (typeof type === 'object') {
 9615        options = type;
 9616        type = undefined;
 9617      }
 9618
 9619      options = options || {};
 9620
 9621      // Metadata about relationships is stored on the meta of
 9622      // the relationship. This is used for introspection and
 9623      // serialization. Note that `key` is populated lazily
 9624      // the first time the CP is called.
 9625      var meta = {
 9626        type: type,
 9627        isRelationship: true,
 9628        options: options,
 9629        kind: 'hasMany',
 9630        key: null
 9631      };
 9632
 9633      return Ember.computed(function(key) {
 9634        var relationship = this._relationships[key];
 9635        return relationship.getRecords();
 9636      }).meta(meta).readOnly();
 9637    }
 9638
 9639    Model.reopen({
 9640      notifyHasManyAdded: function(key, record, idx) {
 9641        var relationship = this._relationships[key];
 9642        var manyArray = relationship.manyArray;
 9643        manyArray.addRecord(record, idx);
 9644        //We need to notifyPropertyChange in the adding case because we need to make sure
 9645        //we fetch the newly added record in case it is unloaded
 9646        //TODO(Igor): Consider whether we could do this only if the record state is unloaded
 9647        this.notifyPropertyChange(key);
 9648      },
 9649
 9650      notifyHasManyRemoved: function(key, record) {
 9651        var relationship = this._relationships[key];
 9652        var manyArray = relationship.manyArray;
 9653        manyArray.removeRecord(record);
 9654      }
 9655    });
 9656
 9657
 9658    __exports__["default"] = hasMany;
 9659  });
 9660define("ember-data/system/relationships/relationship",
 9661  ["ember-data/system/promise_proxies","ember-data/system/map","exports"],
 9662  function(__dependency1__, __dependency2__, __exports__) {
 9663    "use strict";
 9664    var PromiseManyArray = __dependency1__.PromiseManyArray;
 9665    var PromiseObject = __dependency1__.PromiseObject;
 9666    var OrderedSet = __dependency2__.OrderedSet;
 9667
 9668    var Relationship = function(store, record, inverseKey, relationshipMeta) {
 9669      this.members = new OrderedSet();
 9670      this.store = store;
 9671      this.key = relationshipMeta.key;
 9672      this.inverseKey = inverseKey;
 9673      this.record = record;
 9674      this.key = relationshipMeta.key;
 9675      this.isAsync = relationshipMeta.options.async;
 9676      this.relationshipMeta = relationshipMeta;
 9677      //This probably breaks for polymorphic relationship in complex scenarios, due to
 9678      //multiple possible typeKeys
 9679      this.inverseKeyForImplicit = this.store.modelFor(this.record.constructor).typeKey + this.key;
 9680      //Cached promise when fetching the relationship from a link
 9681      this.linkPromise = null;
 9682    };
 9683
 9684    Relationship.prototype = {
 9685      constructor: Relationship,
 9686
 9687      destroy: Ember.K,
 9688
 9689      clear: function() {
 9690        this.members.forEach(function(member) {
 9691          this.removeRecord(member);
 9692        }, this);
 9693      },
 9694
 9695      disconnect: function(){
 9696        this.members.forEach(function(member) {
 9697          this.removeRecordFromInverse(member);
 9698        }, this);
 9699      },
 9700
 9701      reconnect: function(){
 9702        this.members.forEach(function(member) {
 9703          this.addRecordToInverse(member);
 9704        }, this);
 9705      },
 9706
 9707      removeRecords: function(records){
 9708        var that = this;
 9709        records.forEach(function(record){
 9710          that.removeRecord(record);
 9711        });
 9712      },
 9713
 9714      addRecords: function(records, idx){
 9715        var that = this;
 9716        records.forEach(function(record){
 9717          that.addRecord(record, idx);
 9718          if (idx !== undefined) {
 9719            idx++;
 9720          }
 9721        });
 9722      },
 9723
 9724      addRecord: function(record, idx) {
 9725        if (!this.members.has(record)) {
 9726          this.members.add(record);
 9727          this.notifyRecordRelationshipAdded(record, idx);
 9728          if (this.inverseKey) {
 9729            record._relationships[this.inverseKey].addRecord(this.record);
 9730          } else {
 9731            if (!record._implicitRelationships[this.inverseKeyForImplicit]) {
 9732              record._implicitRelationships[this.inverseKeyForImplicit] = new Relationship(this.store, record, this.key,  {options:{}});
 9733            }
 9734            record._implicitRelationships[this.inverseKeyForImplicit].addRecord(this.record);
 9735          }
 9736          this.record.updateRecordArrays();
 9737        }
 9738      },
 9739
 9740      removeRecord: function(record) {
 9741        if (this.members.has(record)) {
 9742          this.removeRecordFromOwn(record);
 9743          if (this.inverseKey) {
 9744            this.removeRecordFromInverse(record);
 9745          } else {
 9746            if (record._implicitRelationships[this.inverseKeyForImplicit]) {
 9747              record._implicitRelationships[this.inverseKeyForImplicit].removeRecord(this.record);
 9748            }
 9749          }
 9750        }
 9751      },
 9752
 9753      addRecordToInverse: function(record) {
 9754        if (this.inverseKey) {
 9755          record._relationships[this.inverseKey].addRecord(this.record);
 9756        }
 9757      },
 9758
 9759      removeRecordFromInverse: function(record) {
 9760        var inverseRelationship = record._relationships[this.inverseKey];
 9761        //Need to check for existence, as the record might unloading at the moment
 9762        if (inverseRelationship) {
 9763          inverseRelationship.removeRecordFromOwn(this.record);
 9764        }
 9765      },
 9766
 9767      removeRecordFromOwn: function(record) {
 9768        this.members["delete"](record);
 9769        this.notifyRecordRelationshipRemoved(record);
 9770        this.record.updateRecordArrays();
 9771      },
 9772
 9773      updateLink: function(link) {
 9774        if (link !== this.link) {
 9775          this.link = link;
 9776          this.linkPromise = null;
 9777          this.record.notifyPropertyChange(this.key);
 9778        }
 9779      },
 9780
 9781      findLink: function() {
 9782        if (this.linkPromise) {
 9783          return this.linkPromise;
 9784        } else {
 9785          var promise = this.fetchLink();
 9786          this.linkPromise = promise;
 9787          return promise.then(function(result) {
 9788            return result;
 9789          });
 9790        }
 9791      },
 9792
 9793      updateRecordsFromAdapter: function(records) {
 9794        //TODO Once we have adapter support, we need to handle updated and canonical changes
 9795        this.computeChanges(records);
 9796      },
 9797
 9798      notifyRecordRelationshipAdded: Ember.K,
 9799      notifyRecordRelationshipRemoved: Ember.K
 9800    };
 9801
 9802    var ManyRelationship = function(store, record, inverseKey, relationshipMeta) {
 9803      this._super$constructor(store, record, inverseKey, relationshipMeta);
 9804      this.belongsToType = relationshipMeta.type;
 9805      this.manyArray = store.recordArrayManager.createManyArray(this.belongsToType, Ember.A());
 9806      this.manyArray.relationship = this;
 9807      this.isPolymorphic = relationshipMeta.options.polymorphic;
 9808      this.manyArray.isPolymorphic = this.isPolymorphic;
 9809    };
 9810
 9811    ManyRelationship.prototype = Object.create(Relationship.prototype);
 9812    ManyRelationship.prototype.constructor = ManyRelationship;
 9813    ManyRelationship.prototype._super$constructor = Relationship;
 9814
 9815    ManyRelationship.prototype.destroy = function() {
 9816      this.manyArray.destroy();
 9817    };
 9818
 9819    ManyRelationship.prototype.notifyRecordRelationshipAdded = function(record, idx) {
 9820      Ember.assert("You cannot add '" + record.constructor.typeKey + "' records to this relationship (only '" + this.belongsToType.typeKey + "' allowed)", !this.belongsToType || record instanceof this.belongsToType);
 9821      this.record.notifyHasManyAdded(this.key, record, idx);
 9822    };
 9823
 9824    ManyRelationship.prototype.notifyRecordRelationshipRemoved = function(record) {
 9825      this.record.notifyHasManyRemoved(this.key, record);
 9826    };
 9827
 9828    ManyRelationship.prototype.reload = function() {
 9829      var self = this;
 9830      if (this.link) {
 9831        return this.fetchLink();
 9832      } else {
 9833        return this.store.scheduleFetchMany(this.manyArray.toArray()).then(function() {
 9834          //Goes away after the manyArray refactor
 9835          self.manyArray.set('isLoaded', true);
 9836          return self.manyArray;
 9837        });
 9838      }
 9839    };
 9840
 9841    ManyRelationship.prototype.computeChanges = function(records) {
 9842      var members = this.members;
 9843      var recordsToRemove = [];
 9844      var length;
 9845      var record;
 9846      var i;
 9847
 9848      records = setForArray(records);
 9849
 9850      members.forEach(function(member) {
 9851        if (records.has(member)) return;
 9852
 9853        recordsToRemove.push(member);
 9854      });
 9855      this.removeRecords(recordsToRemove);
 9856
 9857      var hasManyArray = this.manyArray;
 9858
 9859      // Using records.toArray() since currently using
 9860      // removeRecord can modify length, messing stuff up
 9861      // forEach since it directly looks at "length" each
 9862      // iteration
 9863      records = records.toArray();
 9864      length = records.length;
 9865      for (i = 0; i < length; i++){
 9866        record = records[i];
 9867        //Need to preserve the order of incoming records
 9868        if (hasManyArray.objectAt(i) === record ) {
 9869          continue;
 9870        }
 9871        this.removeRecord(record);
 9872        this.addRecord(record, i);
 9873      }
 9874    };
 9875
 9876    ManyRelationship.prototype.fetchLink = function() {
 9877      var self = this;
 9878      return this.store.findHasMany(this.record, this.link, this.relationshipMeta).then(function(records){
 9879        self.updateRecordsFromAdapter(records);
 9880        return self.manyArray;
 9881      });
 9882    };
 9883
 9884    ManyRelationship.prototype.findRecords = function() {
 9885      var manyArray = this.manyArray;
 9886      return this.store.findMany(manyArray.toArray()).then(function(){
 9887        //Goes away after the manyArray refactor
 9888        manyArray.set('isLoaded', true);
 9889        return manyArray;
 9890      });
 9891    };
 9892
 9893    ManyRelationship.prototype.getRecords = function() {
 9894      if (this.isAsync) {
 9895        var self = this;
 9896        var promise;
 9897        if (this.link) {
 9898          promise = this.findLink().then(function() {
 9899            return self.findRecords();
 9900          });
 9901        } else {
 9902          promise = this.findRecords();
 9903        }
 9904        return PromiseManyArray.create({
 9905          content: this.manyArray,
 9906          promise: promise
 9907        });
 9908      } else {
 9909          Ember.assert("You looked up the '" + this.key + "' relationship on a '" + this.record.constructor.typeKey + "' with id " + this.record.get('id') +  " but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.hasMany({ async: true })`)", this.manyArray.isEvery('isEmpty', false));
 9910
 9911        this.manyArray.set('isLoaded', true);
 9912        return this.manyArray;
 9913     }
 9914    };
 9915
 9916    var BelongsToRelationship = function(store, record, inverseKey, relationshipMeta) {
 9917      this._super$constructor(store, record, inverseKey, relationshipMeta);
 9918      this.record = record;
 9919      this.key = relationshipMeta.key;
 9920      this.inverseRecord = null;
 9921    };
 9922
 9923    BelongsToRelationship.prototype = Object.create(Relationship.prototype);
 9924    BelongsToRelationship.prototype.constructor = BelongsToRelationship;
 9925    BelongsToRelationship.prototype._super$constructor = Relationship;
 9926
 9927    BelongsToRelationship.prototype.setRecord = function(newRecord) {
 9928      if (newRecord) {
 9929        this.addRecord(newRecord);
 9930      } else if (this.inverseRecord) {
 9931        this.removeRecord(this.inverseRecord);
 9932      }
 9933    };
 9934
 9935    BelongsToRelationship.prototype._super$addRecord = Relationship.prototype.addRecord;
 9936    BelongsToRelationship.prototype.addRecord = function(newRecord) {
 9937      if (this.members.has(newRecord)){ return;}
 9938      var type = this.relationshipMeta.type;
 9939      Ember.assert("You can only add a '" + type.typeKey + "' record to this relationship", newRecord instanceof type);
 9940
 9941      if (this.inverseRecord) {
 9942        this.removeRecord(this.inverseRecord);
 9943      }
 9944
 9945      this.inverseRecord = newRecord;
 9946      this._super$addRecord(newRecord);
 9947    };
 9948
 9949    BelongsToRelationship.prototype.setRecordPromise = function(newPromise) {
 9950      var content = newPromise.get && newPromise.get('content');
 9951      Ember.assert("You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo or hasMany relationship to the get call.", content !== undefined);
 9952      this.setRecord(content);
 9953    };
 9954
 9955    BelongsToRelationship.prototype.notifyRecordRelationshipAdded = function(newRecord) {
 9956      this.record.notifyBelongsToAdded(this.key, this);
 9957    };
 9958
 9959    BelongsToRelationship.prototype.notifyRecordRelationshipRemoved = function(record) {
 9960      this.record.notifyBelongsToRemoved(this.key, this);
 9961    };
 9962
 9963    BelongsToRelationship.prototype._super$removeRecordFromOwn = Relationship.prototype.removeRecordFromOwn;
 9964    BelongsToRelationship.prototype.removeRecordFromOwn = function(record) {
 9965      if (!this.members.has(record)){ return;}
 9966      this._super$removeRecordFromOwn(record);
 9967      this.inverseRecord = null;
 9968    };
 9969
 9970    BelongsToRelationship.prototype.findRecord = function() {
 9971      if (this.inverseRecord) {
 9972        return this.store._findByRecord(this.inverseRecord);
 9973      } else {
 9974        return Ember.RSVP.Promise.resolve(null);
 9975      }
 9976    };
 9977
 9978    BelongsToRelationship.prototype.fetchLink = function() {
 9979      var self = this;
 9980      return this.store.findBelongsTo(this.record, this.link, this.relationshipMeta).then(function(record){
 9981        self.addRecord(record);
 9982        return record;
 9983      });
 9984    };
 9985
 9986    BelongsToRelationship.prototype.getRecord = function() {
 9987      if (this.isAsync) {
 9988        var promise;
 9989        if (this.link){
 9990          var self = this;
 9991          promise = this.findLink().then(function() {
 9992            return self.findRecord();
 9993          });
 9994        } else {
 9995          promise = this.findRecord();
 9996        }
 9997
 9998        return PromiseObject.create({
 9999          promise: promise,
10000          content: this.inverseRecord
10001        });
10002      } else {
10003        Ember.assert("You looked up the '" + this.key + "' relationship on a '" + this.record.constructor.typeKey + "' with id " + this.record.get('id') +  " but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.belongsTo({ async: true })`)", this.inverseRecord === null || !this.inverseRecord.get('isEmpty'));
10004        return this.inverseRecord;
10005      }
10006    };
10007
10008    function setForArray(array) {
10009      var set = new OrderedSet();
10010
10011      if (array) {
10012        for (var i=0, l=array.length; i<l; i++) {
10013          set.add(array[i]);
10014        }
10015      }
10016
10017      return set;
10018    }
10019
10020    var createRelationshipFor = function(record, relationshipMeta, store){
10021      var inverseKey;
10022      var inverse = record.constructor.inverseFor(relationshipMeta.key);
10023
10024      if (inverse) {
10025        inverseKey = inverse.name;
10026      }
10027
10028      if (relationshipMeta.kind === 'hasMany'){
10029        return new ManyRelationship(store, record, inverseKey, relationshipMeta);
10030      }
10031      else {
10032        return new BelongsToRelationship(store, record, inverseKey, relationshipMeta);
10033      }
10034    };
10035
10036
10037    __exports__.Relationship = Relationship;
10038    __exports__.ManyRelationship = ManyRelationship;
10039    __exports__.BelongsToRelationship = BelongsToRelationship;
10040    __exports__.createRelationshipFor = createRelationshipFor;
10041  });
10042define("ember-data/system/store",
10043  ["ember-data/system/adapter","ember-inflector/system/string","ember-data/system/map","ember-data/system/promise_proxies","exports"],
10044  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
10045    "use strict";
10046    /*globals Ember*/
10047    /*jshint eqnull:true*/
10048
10049    /**
10050      @module ember-data
10051    */
10052
10053    var InvalidError = __dependency1__.InvalidError;
10054    var Adapter = __dependency1__.Adapter;
10055    var singularize = __dependency2__.singularize;
10056    var Map = __dependency3__.Map;
10057
10058    var promiseArray = __dependency4__.promiseArray;
10059    var promiseObject = __dependency4__.promiseObject;
10060
10061
10062    var get = Ember.get;
10063    var set = Ember.set;
10064    var once = Ember.run.once;
10065    var isNone = Ember.isNone;
10066    var forEach = Ember.EnumerableUtils.forEach;
10067    var indexOf = Ember.EnumerableUtils.indexOf;
10068    var map = Ember.EnumerableUtils.map;
10069    var Promise = Ember.RSVP.Promise;
10070    var copy = Ember.copy;
10071    var Store, RecordArrayManager, Model;
10072
10073    var camelize = Ember.String.camelize;
10074
10075    // Implementors Note:
10076    //
10077    //   The variables in this file are consistently named according to the following
10078    //   scheme:
10079    //
10080    //   * +id+ means an identifier managed by an external source, provided inside
10081    //     the data provided by that source. These are always coerced to be strings
10082    //     before being used internally.
10083    //   * +clientId+ means a transient numerical identifier generated at runtime by
10084    //     the data store. It is important primarily because newly created objects may
10085    //     not yet have an externally generated id.
10086    //   * +reference+ means a record reference object, which holds metadata about a
10087    //     record, even if it has not yet been fully materialized.
10088    //   * +type+ means a subclass of DS.Model.
10089
10090    // Used by the store to normalize IDs entering the store.  Despite the fact
10091    // that developers may provide IDs as numbers (e.g., `store.find(Person, 1)`),
10092    // it is important that internally we use strings, since IDs may be serialized
10093    // and lose type information.  For example, Ember's router may put a record's
10094    // ID into the URL, and if we later try to deserialize that URL and find the
10095    // corresponding record, we will not know if it is a string or a number.
10096    function coerceId(id) {
10097      return id == null ? null : id+'';
10098    }
10099
10100    /**
10101      The store contains all of the data for records loaded from the server.
10102      It is also responsible for creating instances of `DS.Model` that wrap
10103      the individual data for a record, so that they can be bound to in your
10104      Handlebars templates.
10105
10106      Define your application's store like this:
10107
10108      ```javascript
10109      MyApp.Store = DS.Store.extend();
10110      ```
10111
10112      Most Ember.js applications will only have a single `DS.Store` that is
10113      automatically created by their `Ember.Application`.
10114
10115      You can retrieve models from the store in several ways. To retrieve a record
10116      for a specific id, use `DS.Store`'s `find()` method:
10117
10118      ```javascript
10119      store.find('person', 123).then(function (person) {
10120      });
10121      ```
10122
10123      If your application has multiple `DS.Store` instances (an unusual case), you can
10124      specify which store should be used:
10125
10126      ```javascript
10127      store.find('person', 123).then(function (person) {
10128      });
10129      ```
10130
10131      By default, the store will talk to your backend using a standard
10132      REST mechanism. You can customize how the store talks to your
10133      backend by specifying a custom adapter:
10134
10135      ```javascript
10136      MyApp.ApplicationAdapter = MyApp.CustomAdapter
10137      ```
10138
10139      You can learn more about writing a custom adapter by reading the `DS.Adapter`
10140      documentation.
10141
10142      ### Store createRecord() vs. push() vs. pushPayload() vs. update()
10143
10144      The store provides multiple ways to create new record objects. They have
10145      some subtle differences in their use which are detailed below:
10146
10147      [createRecord](#method_createRecord) is used for creating new
10148      records on the client side. This will return a new record in the
10149      `created.uncommitted` state. In order to persist this record to the
10150      backend you will need to call `record.save()`.
10151
10152      [push](#method_push) is used to notify Ember Data's store of new or
10153      updated records that exist in the backend. This will return a record
10154      in the `loaded.saved` state. The primary use-case for `store#push` is
10155      to notify Ember Data about record updates that happen
10156      outside of the normal adapter methods (for example
10157      [SSE](http://dev.w3.org/html5/eventsource/) or [Web
10158      Sockets](http://www.w3.org/TR/2009/WD-websockets-20091222/)).
10159
10160      [pushPayload](#method_pushPayload) is a convenience wrapper for
10161      `store#push` that will deserialize payloads if the
10162      Serializer implements a `pushPayload` method.
10163
10164      [update](#method_update) works like `push`, except it can handle
10165      partial attributes without overwriting the existing record
10166      properties.
10167
10168      Note: When creating a new record using any of the above methods
10169      Ember Data will update `DS.RecordArray`s such as those returned by
10170      `store#all()`, `store#findAll()` or `store#filter()`. This means any
10171      data bindings or computed properties that depend on the RecordArray
10172      will automatically be synced to include the new or updated record
10173      values.
10174
10175      @class Store
10176      @namespace DS
10177      @extends Ember.Object
10178    */
10179    Store = Ember.Object.extend({
10180
10181      /**
10182        @method init
10183        @private
10184      */
10185      init: function() {
10186        // internal bookkeeping; not observable
10187        if (!RecordArrayManager) { RecordArrayManager = requireModule("ember-data/system/record_array_manager")["default"]; }
10188        this.typeMaps = {};
10189        this.recordArrayManager = RecordArrayManager.create({
10190          store: this
10191        });
10192        this._pendingSave = [];
10193        //Used to keep track of all the find requests that need to be coalesced
10194        this._pendingFetch = Map.create();
10195      },
10196
10197      /**
10198        The adapter to use to communicate to a backend server or other persistence layer.
10199
10200        This can be specified as an instance, class, or string.
10201
10202        If you want to specify `App.CustomAdapter` as a string, do:
10203
10204        ```js
10205        adapter: 'custom'
10206        ```
10207
10208        @property adapter
10209        @default DS.RESTAdapter
10210        @type {DS.Adapter|String}
10211      */
10212      adapter: '-rest',
10213
10214      /**
10215        Returns a JSON representation of the record using a custom
10216        type-specific serializer, if one exists.
10217
10218        The available options are:
10219
10220        * `includeId`: `true` if the record's ID should be included in
10221          the JSON representation
10222
10223        @method serialize
10224        @private
10225        @param {DS.Model} record the record to serialize
10226        @param {Object} options an options hash
10227      */
10228      serialize: function(record, options) {
10229        return this.serializerFor(record.constructor.typeKey).serialize(record, options);
10230      },
10231
10232      /**
10233        This property returns the adapter, after resolving a possible
10234        string key.
10235
10236        If the supplied `adapter` was a class, or a String property
10237        path resolved to a class, this property will instantiate the
10238        class.
10239
10240        This property is cacheable, so the same instance of a specified
10241        adapter class should be used for the lifetime of the store.
10242
10243        @property defaultAdapter
10244        @private
10245        @return DS.Adapter
10246      */
10247      defaultAdapter: Ember.computed('adapter', function() {
10248        var adapter = get(this, 'adapter');
10249
10250        Ember.assert('You tried to set `adapter` property to an instance of `DS.Adapter`, where it should be a name or a factory', !(adapter instanceof Adapter));
10251
10252        if (typeof adapter === 'string') {
10253          adapter = this.container.lookup('adapter:' + adapter) || this.container.lookup('adapter:application') || this.container.lookup('adapter:-rest');
10254        }
10255
10256        if (DS.Adapter.detect(adapter)) {
10257          adapter = adapter.create({
10258            container: this.container
10259          });
10260        }
10261
10262        return adapter;
10263      }),
10264
10265      // .....................
10266      // . CREATE NEW RECORD .
10267      // .....................
10268
10269      /**
10270        Create a new record in the current store. The properties passed
10271        to this method are set on the newly created record.
10272
10273        To create a new instance of `App.Post`:
10274
10275        ```js
10276        store.createRecord('post', {
10277          title: "Rails is omakase"
10278        });
10279        ```
10280
10281        @method createRecord
10282        @param {String} type
10283        @param {Object} properties a hash of properties to set on the
10284          newly created record.
10285        @return {DS.Model} record
10286      */
10287      createRecord: function(typeName, inputProperties) {
10288        var type = this.modelFor(typeName);
10289        var properties = copy(inputProperties) || {};
10290
10291        // If the passed properties do not include a primary key,
10292        // give the adapter an opportunity to generate one. Typically,
10293        // client-side ID generators will use something like uuid.js
10294        // to avoid conflicts.
10295
10296        if (isNone(properties.id)) {
10297          properties.id = this._generateId(type);
10298        }
10299
10300        // Coerce ID to a string
10301        properties.id = coerceId(properties.id);
10302
10303        var record = this.buildRecord(type, properties.id);
10304
10305        // Move the record out of its initial `empty` state into
10306        // the `loaded` state.
10307        record.loadedData();
10308
10309        // Set the properties specified on the record.
10310        record.setProperties(properties);
10311
10312        return record;
10313      },
10314
10315      /**
10316        If possible, this method asks the adapter to generate an ID for
10317        a newly created record.
10318
10319        @method _generateId
10320        @private
10321        @param {String} type
10322        @return {String} if the adapter can generate one, an ID
10323      */
10324      _generateId: function(type) {
10325        var adapter = this.adapterFor(type);
10326
10327        if (adapter && adapter.generateIdForRecord) {
10328          return adapter.generateIdForRecord(this);
10329        }
10330
10331        return null;
10332      },
10333
10334      // .................
10335      // . DELETE RECORD .
10336      // .................
10337
10338      /**
10339        For symmetry, a record can be deleted via the store.
10340
10341        Example
10342
10343        ```javascript
10344        var post = store.createRecord('post', {
10345          title: "Rails is omakase"
10346        });
10347
10348        store.deleteRecord(post);
10349        ```
10350
10351        @method deleteRecord
10352        @param {DS.Model} record
10353      */
10354      deleteRecord: function(record) {
10355        record.deleteRecord();
10356      },
10357
10358      /**
10359        For symmetry, a record can be unloaded via the store. Only
10360        non-dirty records can be unloaded.
10361
10362        Example
10363
10364        ```javascript
10365        store.find('post', 1).then(function(post) {
10366          store.unloadRecord(post);
10367        });
10368        ```
10369
10370        @method unloadRecord
10371        @param {DS.Model} record
10372      */
10373      unloadRecord: function(record) {
10374        record.unloadRecord();
10375      },
10376
10377      // ................
10378      // . FIND RECORDS .
10379      // ................
10380
10381      /**
10382        This is the main entry point into finding records. The first parameter to
10383        this method is the model's name as a string.
10384
10385        ---
10386
10387        To find a record by ID, pass the `id` as the second parameter:
10388
10389        ```javascript
10390        store.find('person', 1);
10391        ```
10392
10393        The `find` method will always return a **promise** that will be resolved
10394        with the record. If the record was already in the store, the promise will
10395        be resolved immediately. Otherwise, the store will ask the adapter's `find`
10396        method to find the necessary data.
10397
10398        The `find` method will always resolve its promise with the same object for
10399        a given type and `id`.
10400
10401        ---
10402
10403        You can optionally `preload` specific attributes and relationships that you know of
10404        by passing them as the third argument to find.
10405
10406        For example, if your Ember route looks like `/posts/1/comments/2` and your API route
10407        for the comment also looks like `/posts/1/comments/2` if you want to fetch the comment
10408        without fetching the post you can pass in the post to the `find` call:
10409
10410        ```javascript
10411        store.find('comment', 2, {post: 1});
10412        ```
10413
10414        If you have access to the post model you can also pass the model itself:
10415
10416        ```javascript
10417        store.find('post', 1).then(function (myPostModel) {
10418          store.find('comment', 2, {post: myPostModel});
10419        });
10420        ```
10421
10422        This way, your adapter's `find` or `buildURL` method will be able to look up the
10423        relationship on the record and construct the nested URL without having to first
10424        fetch the post.
10425
10426        ---
10427
10428        To find all records for a type, call `find` with no additional parameters:
10429
10430        ```javascript
10431        store.find('person');
10432        ```
10433
10434        This will ask the adapter's `findAll` method to find the records for the
10435        given type, and return a promise that will be resolved once the server
10436        returns the values.
10437
10438        ---
10439
10440        To find a record by a query, call `find` with a hash as the second
10441        parameter:
10442
10443        ```javascript
10444        store.find('person', { page: 1 });
10445        ```
10446
10447        This will ask the adapter's `findQuery` method to find the records for
10448        the query, and return a promise that will be resolved once the server
10449        responds.
10450
10451        @method find
10452        @param {String or subclass of DS.Model} type
10453        @param {Object|String|Integer|null} id
10454        @param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
10455        @return {Promise} promise
10456      */
10457      find: function(type, id, preload) {
10458        Ember.assert("You need to pass a type to the store's find method", arguments.length >= 1);
10459        Ember.assert("You may not pass `" + id + "` as id to the store's find method", arguments.length === 1 || !Ember.isNone(id));
10460
10461        if (arguments.length === 1) {
10462          return this.findAll(type);
10463        }
10464
10465        // We are passed a query instead of an id.
10466        if (Ember.typeOf(id) === 'object') {
10467          return this.findQuery(type, id);
10468        }
10469
10470        return this.findById(type, coerceId(id), preload);
10471      },
10472
10473      /**
10474        This method returns a record for a given type and id combination.
10475
10476        @method findById
10477        @private
10478        @param {String or subclass of DS.Model} type
10479        @param {String|Integer} id
10480        @param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
10481        @return {Promise} promise
10482      */
10483      findById: function(typeName, id, preload) {
10484
10485        var type = this.modelFor(typeName);
10486        var record = this.recordForId(type, id);
10487
10488        return this._findByRecord(record, preload);
10489      },
10490
10491      _findByRecord: function(record, preload) {
10492        var fetchedRecord;
10493
10494        if (preload) {
10495          record._preloadData(preload);
10496        }
10497
10498        if (get(record, 'isEmpty')) {
10499          fetchedRecord = this.scheduleFetch(record);
10500          //TODO double check about reloading
10501        } else if (get(record, 'isLoading')){
10502          fetchedRecord = record._loadingPromise;
10503        }
10504
10505        return promiseObject(fetchedRecord || record, "DS: Store#findByRecord " + record.typeKey + " with id: " + get(record, 'id'));
10506      },
10507
10508      /**
10509        This method makes a series of requests to the adapter's `find` method
10510        and returns a promise that resolves once they are all loaded.
10511
10512        @private
10513        @method findByIds
10514        @param {String} type
10515        @param {Array} ids
10516        @return {Promise} promise
10517      */
10518      findByIds: function(type, ids) {
10519        var store = this;
10520
10521        return promiseArray(Ember.RSVP.all(map(ids, function(id) {
10522          return store.findById(type, id);
10523        })).then(Ember.A, null, "DS: Store#findByIds of " + type + " complete"));
10524      },
10525
10526      /**
10527        This method is called by `findById` if it discovers that a particular
10528        type/id pair hasn't been loaded yet to kick off a request to the
10529        adapter.
10530
10531        @method fetchRecord
10532        @private
10533        @param {DS.Model} record
10534        @return {Promise} promise
10535      */
10536      fetchRecord: function(record) {
10537        var type = record.constructor;
10538        var id = get(record, 'id');
10539        var adapter = this.adapterFor(type);
10540
10541        Ember.assert("You tried to find a record but you have no adapter (for " + type + ")", adapter);
10542        Ember.assert("You tried to find a record but your adapter (for " + type + ") does not implement 'find'", adapter.find);
10543
10544        var promise = _find(adapter, this, type, id, record);
10545        return promise;
10546      },
10547
10548      scheduleFetchMany: function(records) {
10549        return Ember.RSVP.all(map(records, this.scheduleFetch, this));
10550      },
10551
10552      scheduleFetch: function(record) {
10553        var type = record.constructor;
10554        if (isNone(record)) { return null; }
10555        if (record._loadingPromise) { return record._loadingPromise; }
10556
10557        var resolver = Ember.RSVP.defer('Fetching ' + type + 'with id: ' + record.get('id'));
10558        var recordResolverPair = {
10559          record: record,
10560          resolver: resolver
10561        };
10562        var promise = resolver.promise;
10563
10564        record.loadingData(promise);
10565
10566        if (!this._pendingFetch.get(type)){
10567          this._pendingFetch.set(type, [recordResolverPair]);
10568        } else {
10569          this._pendingFetch.get(type).push(recordResolverPair);
10570        }
10571        Ember.run.scheduleOnce('afterRender', this, this.flushAllPendingFetches);
10572
10573        return promise;
10574      },
10575
10576      flushAllPendingFetches: function(){
10577        if (this.isDestroyed || this.isDestroying) {
10578          return;
10579        }
10580
10581        this._pendingFetch.forEach(this._flushPendingFetchForType, this);
10582        this._pendingFetch = Map.create();
10583      },
10584
10585      _flushPendingFetchForType: function (recordResolverPairs, type) {
10586        var store = this;
10587        var adapter = store.adapterFor(type);
10588        var shouldCoalesce = !!adapter.findMany && adapter.coalesceFindRequests;
10589        var records = Ember.A(recordResolverPairs).mapBy('record');
10590
10591        function _fetchRecord(recordResolverPair) {
10592          recordResolverPair.resolver.resolve(store.fetchRecord(recordResolverPair.record));
10593        }
10594
10595        function resolveFoundRecords(records) {
10596          forEach(records, function(record){
10597            var pair = Ember.A(recordResolverPairs).findBy('record', record);
10598            if (pair){
10599              var resolver = pair.resolver;
10600              resolver.resolve(record);
10601            }
10602          });
10603        }
10604
10605        function makeMissingRecordsRejector(requestedRecords) {
10606          return function rejectMissingRecords(resolvedRecords) {
10607            var missingRecords = requestedRecords.without(resolvedRecords);
10608            rejectRecords(missingRecords);
10609          };
10610        }
10611
10612        function makeRecordsRejector(records) {
10613          return function (error) {
10614            rejectRecords(records, error);
10615          };
10616        }
10617
10618        function rejectRecords(records, error) {
10619          forEach(records, function(record){
10620            var pair = Ember.A(recordResolverPairs).findBy('record', record);
10621            if (pair){
10622              var resolver = pair.resolver;
10623              resolver.reject(error);
10624            }
10625          });
10626        }
10627
10628        if (recordResolverPairs.length === 1) {
10629          _fetchRecord(recordResolverPairs[0]);
10630        } else if (shouldCoalesce) {
10631          var groups = adapter.groupRecordsForFindMany(this, records);
10632          forEach(groups, function (groupOfRecords) {
10633            var requestedRecords = Ember.A(groupOfRecords);
10634            var ids = requestedRecords.mapBy('id');
10635            if (ids.length > 1) {
10636              _findMany(adapter, store, type, ids, requestedRecords).
10637                then(resolveFoundRecords).
10638                then(makeMissingRecordsRejector(requestedRecords)).
10639                then(null, makeRecordsRejector(requestedRecords));
10640            } else if (ids.length === 1) {
10641              var pair = Ember.A(recordResolverPairs).findBy('record', groupOfRecords[0]);
10642              _fetchRecord(pair);
10643            } else {
10644              Ember.assert("You cannot return an empty array from adapter's method groupRecordsForFindMany", false);
10645            }
10646          });
10647        } else {
10648          forEach(recordResolverPairs, _fetchRecord);
10649        }
10650      },
10651
10652      /**
10653        Get a record by a given type and ID without triggering a fetch.
10654
10655        This method will synchronously return the record if it is available in the store,
10656        otherwise it will return `null`. A record is available if it has been fetched earlier, or
10657        pushed manually into the store.
10658
10659        _Note: This is an synchronous method and does not return a promise._
10660
10661        ```js
10662        var post = store.getById('post', 1);
10663
10664        post.get('id'); // 1
10665        ```
10666
10667        @method getById
10668        @param {String or subclass of DS.Model} type
10669        @param {String|Integer} id
10670        @return {DS.Model|null} record
10671      */
10672      getById: function(type, id) {
10673        if (this.hasRecordForId(type, id)) {
10674          return this.recordForId(type, id);
10675        } else {
10676          return null;
10677        }
10678      },
10679
10680      /**
10681        This method is called by the record's `reload` method.
10682
10683        This method calls the adapter's `find` method, which returns a promise. When
10684        **that** promise resolves, `reloadRecord` will resolve the promise returned
10685        by the record's `reload`.
10686
10687        @method reloadRecord
10688        @private
10689        @param {DS.Model} record
10690        @return {Promise} promise
10691      */
10692      reloadRecord: function(record) {
10693        var type = record.constructor;
10694        var adapter = this.adapterFor(type);
10695        var id = get(record, 'id');
10696
10697        Ember.assert("You cannot reload a record without an ID", id);
10698        Ember.assert("You tried to reload a record but you have no adapter (for " + type + ")", adapter);
10699        Ember.assert("You tried to reload a record but your adapter does not implement `find`", adapter.find);
10700
10701        return this.scheduleFetch(record);
10702      },
10703
10704      /**
10705        Returns true if a record for a given type and ID is already loaded.
10706
10707        @method hasRecordForId
10708        @param {String or subclass of DS.Model} type
10709        @param {String|Integer} id
10710        @return {Boolean}
10711      */
10712      hasRecordForId: function(typeName, inputId) {
10713        var type = this.modelFor(typeName);
10714        var id = coerceId(inputId);
10715        return !!this.typeMapFor(type).idToRecord[id];
10716      },
10717
10718      /**
10719        Returns id record for a given type and ID. If one isn't already loaded,
10720        it builds a new record and leaves it in the `empty` state.
10721
10722        @method recordForId
10723        @private
10724        @param {String or subclass of DS.Model} type
10725        @param {String|Integer} id
10726        @return {DS.Model} record
10727      */
10728      recordForId: function(typeName, inputId) {
10729        var type = this.modelFor(typeName);
10730        var id = coerceId(inputId);
10731        var idToRecord = this.typeMapFor(type).idToRecord;
10732        var record = idToRecord[id];
10733
10734        if (!record || !idToRecord[id]) {
10735          record = this.buildRecord(type, id);
10736        }
10737
10738        return record;
10739      },
10740
10741      /**
10742        @method findMany
10743        @private
10744        @param {DS.Model} owner
10745        @param {Array} records
10746        @param {String or subclass of DS.Model} type
10747        @param {Resolver} resolver
10748        @return {DS.ManyArray} records
10749      */
10750      findMany: function(records) {
10751        var store = this;
10752        return Promise.all( map(records, function(record) {
10753          return store._findByRecord(record);
10754        }));
10755      },
10756
10757
10758      /**
10759        If a relationship was originally populated by the adapter as a link
10760        (as opposed to a list of IDs), this method is called when the
10761        relationship is fetched.
10762
10763        The link (which is usually a URL) is passed through unchanged, so the
10764        adapter can make whatever request it wants.
10765
10766        The usual use-case is for the server to register a URL as a link, and
10767        then use that URL in the future to make a request for the relationship.
10768
10769        @method findHasMany
10770        @private
10771        @param {DS.Model} owner
10772        @param {any} link
10773        @param {String or subclass of DS.Model} type
10774        @return {Promise} promise
10775      */
10776      findHasMany: function(owner, link, type) {
10777        var adapter = this.adapterFor(owner.constructor);
10778
10779        Ember.assert("You tried to load a hasMany relationship but you have no adapter (for " + owner.constructor + ")", adapter);
10780        Ember.assert("You tried to load a hasMany relationship from a specified `link` in the original payload but your adapter does not implement `findHasMany`", adapter.findHasMany);
10781
10782        return _findHasMany(adapter, this, owner, link, type);
10783      },
10784
10785      /**
10786        @method findBelongsTo
10787        @private
10788        @param {DS.Model} owner
10789        @param {any} link
10790        @param {Relationship} relationship
10791        @return {Promise} promise
10792      */
10793      findBelongsTo: function(owner, link, relationship) {
10794        var adapter = this.adapterFor(owner.constructor);
10795
10796        Ember.assert("You tried to load a belongsTo relationship but you have no adapter (for " + owner.constructor + ")", adapter);
10797        Ember.assert("You tried to load a belongsTo relationship from a specified `link` in the original payload but your adapter does not implement `findBelongsTo`", adapter.findBelongsTo);
10798
10799        return _findBelongsTo(adapter, this, owner, link, relationship);
10800      },
10801
10802      /**
10803        This method delegates a query to the adapter. This is the one place where
10804        adapter-level semantics are exposed to the application.
10805
10806        Exposing queries this way seems preferable to creating an abstract query
10807        language for all server-side queries, and then require all adapters to
10808        implement them.
10809
10810        This method returns a promise, which is resolved with a `RecordArray`
10811        once the server returns.
10812
10813        @method findQuery
10814        @private
10815        @param {String or subclass of DS.Model} type
10816        @param {any} query an opaque query to be used by the adapter
10817        @return {Promise} promise
10818      */
10819      findQuery: function(typeName, query) {
10820        var type = this.modelFor(typeName);
10821        var array = this.recordArrayManager
10822          .createAdapterPopulatedRecordArray(type, query);
10823
10824        var adapter = this.adapterFor(type);
10825
10826        Ember.assert("You tried to load a query but you have no adapter (for " + type + ")", adapter);
10827        Ember.assert("You tried to load a query but your adapter does not implement `findQuery`", adapter.findQuery);
10828
10829        return promiseArray(_findQuery(adapter, this, type, query, array));
10830      },
10831
10832      /**
10833        This method returns an array of all records adapter can find.
10834        It triggers the adapter's `findAll` method to give it an opportunity to populate
10835        the array with records of that type.
10836
10837        @method findAll
10838        @private
10839        @param {String or subclass of DS.Model} type
10840        @return {DS.AdapterPopulatedRecordArray}
10841      */
10842      findAll: function(typeName) {
10843        var type = this.modelFor(typeName);
10844
10845        return this.fetchAll(type, this.all(type));
10846      },
10847
10848      /**
10849        @method fetchAll
10850        @private
10851        @param {DS.Model} type
10852        @param {DS.RecordArray} array
10853        @return {Promise} promise
10854      */
10855      fetchAll: function(type, array) {
10856        var adapter = this.adapterFor(type);
10857        var sinceToken = this.typeMapFor(type).metadata.since;
10858
10859        set(array, 'isUpdating', true);
10860
10861        Ember.assert("You tried to load all records but you have no adapter (for " + type + ")", adapter);
10862        Ember.assert("You tried to load all records but your adapter does not implement `findAll`", adapter.findAll);
10863
10864        return promiseArray(_findAll(adapter, this, type, sinceToken));
10865      },
10866
10867      /**
10868        @method didUpdateAll
10869        @param {DS.Model} type
10870      */
10871      didUpdateAll: function(type) {
10872        var findAllCache = this.typeMapFor(type).findAllCache;
10873        set(findAllCache, 'isUpdating', false);
10874      },
10875
10876      /**
10877        This method returns a filtered array that contains all of the known records
10878        for a given type.
10879
10880        Note that because it's just a filter, it will have any locally
10881        created records of the type.
10882
10883        Also note that multiple calls to `all` for a given type will always
10884        return the same RecordArray.
10885
10886        Example
10887
10888        ```javascript
10889        var localPosts = store.all('post');
10890        ```
10891
10892        @method all
10893        @param {String or subclass of DS.Model} type
10894        @return {DS.RecordArray}
10895      */
10896      all: function(typeName) {
10897        var type = this.modelFor(typeName);
10898        var typeMap = this.typeMapFor(type);
10899        var findAllCache = typeMap.findAllCache;
10900
10901        if (findAllCache) { return findAllCache; }
10902
10903        var array = this.recordArrayManager.createRecordArray(type);
10904
10905        typeMap.findAllCache = array;
10906        return array;
10907      },
10908
10909
10910      /**
10911        This method unloads all of the known records for a given type.
10912
10913        ```javascript
10914        store.unloadAll('post');
10915        ```
10916
10917        @method unloadAll
10918        @param {String or subclass of DS.Model} type
10919      */
10920      unloadAll: function(type) {
10921        var modelType = this.modelFor(type);
10922        var typeMap = this.typeMapFor(modelType);
10923        var records = typeMap.records.slice();
10924        var record;
10925
10926        for (var i = 0; i < records.length; i++) {
10927          record = records[i];
10928          record.unloadRecord();
10929          record.destroy(); // maybe within unloadRecord
10930        }
10931
10932        typeMap.findAllCache = null;
10933      },
10934
10935      /**
10936        Takes a type and filter function, and returns a live RecordArray that
10937        remains up to date as new records are loaded into the store or created
10938        locally.
10939
10940        The callback function takes a materialized record, and returns true
10941        if the record should be included in the filter and false if it should
10942        not.
10943
10944        The filter function is called once on all records for the type when
10945        it is created, and then once on each newly loaded or created record.
10946
10947        If any of a record's properties change, or if it changes state, the
10948        filter function will be invoked again to determine whether it should
10949        still be in the array.
10950
10951        Optionally you can pass a query which will be triggered at first. The
10952        results returned by the server could then appear in the filter if they
10953        match the filter function.
10954
10955        Example
10956
10957        ```javascript
10958        store.filter('post', {unread: true}, function(post) {
10959          return post.get('unread');
10960        }).then(function(unreadPosts) {
10961          unreadPosts.get('length'); // 5
10962          var unreadPost = unreadPosts.objectAt(0);
10963          unreadPost.set('unread', false);
10964          unreadPosts.get('length'); // 4
10965        });
10966        ```
10967
10968        @method filter
10969        @param {String or subclass of DS.Model} type
10970        @param {Object} query optional query
10971        @param {Function} filter
10972        @return {DS.PromiseArray}
10973      */
10974      filter: function(type, query, filter) {
10975        var promise;
10976        var length = arguments.length;
10977        var array;
10978        var hasQuery = length === 3;
10979
10980        // allow an optional server query
10981        if (hasQuery) {
10982          promise = this.findQuery(type, query);
10983        } else if (arguments.length === 2) {
10984          filter = query;
10985        }
10986
10987        type = this.modelFor(type);
10988
10989        if (hasQuery) {
10990          array = this.recordArrayManager.createFilteredRecordArray(type, filter, query);
10991        } else {
10992          array = this.recordArrayManager.createFilteredRecordArray(type, filter);
10993        }
10994
10995        promise = promise || Promise.cast(array);
10996
10997
10998        return promiseArray(promise.then(function() {
10999          return array;
11000        }, null, "DS: Store#filter of " + type));
11001      },
11002
11003      /**
11004        This method returns if a certain record is already loaded
11005        in the store. Use this function to know beforehand if a find()
11006        will result in a request or that it will be a cache hit.
11007
11008         Example
11009
11010        ```javascript
11011        store.recordIsLoaded('post', 1); // false
11012        store.find('post', 1).then(function() {
11013          store.recordIsLoaded('post', 1); // true
11014        });
11015        ```
11016
11017        @method recordIsLoaded
11018        @param {String or subclass of DS.Model} type
11019        @param {string} id
11020        @return {boolean}
11021      */
11022      recordIsLoaded: function(type, id) {
11023        if (!this.hasRecordForId(type, id)) { return false; }
11024        return !get(this.recordForId(type, id), 'isEmpty');
11025      },
11026
11027      /**
11028        This method returns the metadata for a specific type.
11029
11030        @method metadataFor
11031        @param {String or subclass of DS.Model} type
11032        @return {object}
11033      */
11034      metadataFor: function(type) {
11035        type = this.modelFor(type);
11036        return this.typeMapFor(type).metadata;
11037      },
11038
11039      // ............
11040      // . UPDATING .
11041      // ............
11042
11043      /**
11044        If the adapter updates attributes or acknowledges creation
11045        or deletion, the record will notify the store to update its
11046        membership in any filters.
11047        To avoid thrashing, this method is invoked only once per
11048
11049        run loop per record.
11050
11051        @method dataWasUpdated
11052        @private
11053        @param {Class} type
11054        @param {DS.Model} record
11055      */
11056      dataWasUpdated: function(type, record) {
11057        this.recordArrayManager.recordDidChange(record);
11058      },
11059
11060      // ..............
11061      // . PERSISTING .
11062      // ..............
11063
11064      /**
11065        This method is called by `record.save`, and gets passed a
11066        resolver for the promise that `record.save` returns.
11067
11068        It schedules saving to happen at the end of the run loop.
11069
11070        @method scheduleSave
11071        @private
11072        @param {DS.Model} record
11073        @param {Resolver} resolver
11074      */
11075      scheduleSave: function(record, resolver) {
11076        record.adapterWillCommit();
11077        this._pendingSave.push([record, resolver]);
11078        once(this, 'flushPendingSave');
11079      },
11080
11081      /**
11082        This method is called at the end of the run loop, and
11083        flushes any records passed into `scheduleSave`
11084
11085        @method flushPendingSave
11086        @private
11087      */
11088      flushPendingSave: function() {
11089        var pending = this._pendingSave.slice();
11090        this._pendingSave = [];
11091
11092        forEach(pending, function(tuple) {
11093          var record = tuple[0], resolver = tuple[1];
11094          var adapter = this.adapterFor(record.constructor);
11095          var operation;
11096
11097          if (get(record, 'currentState.stateName') === 'root.deleted.saved') {
11098            return resolver.resolve(record);
11099          } else if (get(record, 'isNew')) {
11100            operation = 'createRecord';
11101          } else if (get(record, 'isDeleted')) {
11102            operation = 'deleteRecord';
11103          } else {
11104            operation = 'updateRecord';
11105          }
11106
11107          resolver.resolve(_commit(adapter, this, operation, record));
11108        }, this);
11109      },
11110
11111      /**
11112        This method is called once the promise returned by an
11113        adapter's `createRecord`, `updateRecord` or `deleteRecord`
11114        is resolved.
11115
11116        If the data provides a server-generated ID, it will
11117        update the record and the store's indexes.
11118
11119        @method didSaveRecord
11120        @private
11121        @param {DS.Model} record the in-flight record
11122        @param {Object} data optional data (see above)
11123      */
11124      didSaveRecord: function(record, data) {
11125        if (data) {
11126          // normalize relationship IDs into records
11127          data = normalizeRelationships(this, record.constructor, data, record);
11128          setupRelationships(this, record, data);
11129
11130          this.updateId(record, data);
11131        }
11132
11133        record.adapterDidCommit(data);
11134      },
11135
11136      /**
11137        This method is called once the promise returned by an
11138        adapter's `createRecord`, `updateRecord` or `deleteRecord`
11139        is rejected with a `DS.InvalidError`.
11140
11141        @method recordWasInvalid
11142        @private
11143        @param {DS.Model} record
11144        @param {Object} errors
11145      */
11146      recordWasInvalid: function(record, errors) {
11147        record.adapterDidInvalidate(errors);
11148      },
11149
11150      /**
11151        This method is called once the promise returned by an
11152        adapter's `createRecord`, `updateRecord` or `deleteRecord`
11153        is rejected (with anything other than a `DS.InvalidError`).
11154
11155        @method recordWasError
11156        @private
11157        @param {DS.Model} record
11158      */
11159      recordWasError: function(record) {
11160        record.adapterDidError();
11161      },
11162
11163      /**
11164        When an adapter's `createRecord`, `updateRecord` or `deleteRecord`
11165        resolves with data, this method extracts the ID from the supplied
11166        data.
11167
11168        @method updateId
11169        @private
11170        @param {DS.Model} record
11171        @param {Object} data
11172      */
11173      updateId: function(record, data) {
11174        var oldId = get(record, 'id');
11175        var id = coerceId(data.id);
11176
11177        Ember.assert("An adapter cannot assign a new id to a record that already has an id. " + record + " had id: " + oldId + " and you tried to update it with " + id + ". This likely happened because your server returned data in response to a find or update that had a different id than the one you sent.", oldId === null || id === oldId);
11178
11179        this.typeMapFor(record.constructor).idToRecord[id] = record;
11180
11181        set(record, 'id', id);
11182      },
11183
11184      /**
11185        Returns a map of IDs to client IDs for a given type.
11186
11187        @method typeMapFor
11188        @private
11189        @param {subclass of DS.Model} type
11190        @return {Object} typeMap
11191      */
11192      typeMapFor: function(type) {
11193        var typeMaps = get(this, 'typeMaps');
11194        var guid = Ember.guidFor(type);
11195        var typeMap;
11196
11197        typeMap = typeMaps[guid];
11198
11199        if (typeMap) { return typeMap; }
11200
11201        typeMap = {
11202          idToRecord: Object.create(null),
11203          records: [],
11204          metadata: Object.create(null),
11205          type: type
11206        };
11207
11208        typeMaps[guid] = typeMap;
11209
11210        return typeMap;
11211      },
11212
11213      // ................
11214      // . LOADING DATA .
11215      // ................
11216
11217      /**
11218        This internal method is used by `push`.
11219
11220        @method _load
11221        @private
11222        @param {String or subclass of DS.Model} type
11223        @param {Object} data
11224        @param {Boolean} partial the data should be merged into
11225          the existing data, not replace it.
11226      */
11227      _load: function(type, data, partial) {
11228        var id = coerceId(data.id);
11229        var record = this.recordForId(type, id);
11230
11231        record.setupData(data, partial);
11232        this.recordArrayManager.recordDidChange(record);
11233
11234        return record;
11235      },
11236
11237      /**
11238        Returns a model class for a particular key. Used by
11239        methods that take a type key (like `find`, `createRecord`,
11240        etc.)
11241
11242        @method modelFor
11243        @param {String or subclass of DS.Model} key
11244        @return {subclass of DS.Model}
11245      */
11246      modelFor: function(key) {
11247        var factory;
11248
11249        if (typeof key === 'string') {
11250          factory = this.modelFactoryFor(key);
11251          if (!factory) {
11252            throw new Ember.Error("No model was found for '" + key + "'");
11253          }
11254          factory.typeKey = factory.typeKey || this._normalizeTypeKey(key);
11255        } else {
11256          // A factory already supplied. Ensure it has a normalized key.
11257          factory = key;
11258          if (factory.typeKey) {
11259            factory.typeKey = this._normalizeTypeKey(factory.typeKey);
11260          }
11261        }
11262
11263        factory.store = this;
11264        return factory;
11265      },
11266
11267      modelFactoryFor: function(key){
11268        return this.container.lookupFactory('model:' + key);
11269      },
11270
11271      /**
11272        Push some data for a given type into the store.
11273
11274        This method expects normalized data:
11275
11276        * The ID is a key named `id` (an ID is mandatory)
11277        * The names of attributes are the ones you used in
11278          your model's `DS.attr`s.
11279        * Your relationships must be:
11280          * represented as IDs or Arrays of IDs
11281          * represented as model instances
11282          * represented as URLs, under the `links` key
11283
11284        For this model:
11285
11286        ```js
11287        App.Person = DS.Model.extend({
11288          firstName: DS.attr(),
11289          lastName: DS.attr(),
11290
11291          children: DS.hasMany('person')
11292        });
11293        ```
11294
11295        To represent the children as IDs:
11296
11297        ```js
11298        {
11299          id: 1,
11300          firstName: "Tom",
11301          lastName: "Dale",
11302          children: [1, 2, 3]
11303        }
11304        ```
11305
11306        To represent the children relationship as a URL:
11307
11308        ```js
11309        {
11310          id: 1,
11311          firstName: "Tom",
11312          lastName: "Dale",
11313          links: {
11314            children: "/people/1/children"
11315          }
11316        }
11317        ```
11318
11319        If you're streaming data or implementing an adapter,
11320        make sure that you have converted the incoming data
11321        into this form.
11322
11323        This method can be used both to push in brand new
11324        records, as well as to update existing records.
11325
11326        @method push
11327        @param {String or subclass of DS.Model} type
11328        @param {Object} data
11329        @return {DS.Model} the record that was created or
11330          updated.
11331      */
11332      push: function(typeName, data, _partial) {
11333        // _partial is an internal param used by `update`.
11334        // If passed, it means that the data should be
11335        // merged into the existing data, not replace it.
11336        Ember.assert("Expected an object as `data` in a call to push for " + typeName + " , but was " + data, Ember.typeOf(data) === 'object');
11337        Ember.assert("You must include an `id` for " + typeName + " in an object passed to `push`", data.id != null);
11338
11339        var type = this.modelFor(typeName);
11340
11341        // If the payload contains relationships that are specified as
11342        // IDs, normalizeRelationships will convert them into DS.Model instances
11343        // (possibly unloaded) before we push the payload into the
11344        // store.
11345
11346        data = normalizeRelationships(this, type, data);
11347
11348        // Actually load the record into the store.
11349
11350        this._load(type, data, _partial);
11351
11352        var record = this.recordForId(type, data.id);
11353
11354        // Now that the pushed record as well as any related records
11355        // are in the store, create the data structures used to track
11356        // relationships.
11357        setupRelationships(this, record, data);
11358
11359        return record;
11360      },
11361
11362      /**
11363        Push some raw data into the store.
11364
11365        This method can be used both to push in brand new
11366        records, as well as to update existing records. You
11367        can push in more than one type of object at once.
11368        All objects should be in the format expected by the
11369        serializer.
11370
11371        ```js
11372        App.ApplicationSerializer = DS.ActiveModelSerializer;
11373
11374        var pushData = {
11375          posts: [
11376            {id: 1, post_title: "Great post", comment_ids: [2]}
11377          ],
11378          comments: [
11379            {id: 2, comment_body: "Insightful comment"}
11380          ]
11381        }
11382
11383        store.pushPayload(pushData);
11384        ```
11385
11386        By default, the data will be deserialized using a default
11387        serializer (the application serializer if it exists).
11388
11389        Alternatively, `pushPayload` will accept a model type which
11390        will determine which serializer will process the payload.
11391        However, the serializer itself (processing this data via
11392        `normalizePayload`) will not know which model it is
11393        deserializing.
11394
11395        ```js
11396        App.ApplicationSerializer = DS.ActiveModelSerializer;
11397        App.PostSerializer = DS.JSONSerializer;
11398        store.pushPayload('comment', pushData); // Will use the ApplicationSerializer
11399        store.pushPayload('post', pushData); // Will use the PostSerializer
11400        ```
11401
11402        @method pushPayload
11403        @param {String} type Optionally, a model used to determine which serializer will be used
11404        @param {Object} payload
11405      */
11406      pushPayload: function (type, inputPayload) {
11407        var serializer;
11408        var payload;
11409        if (!inputPayload) {
11410          payload = type;
11411          serializer = defaultSerializer(this.container);
11412          Ember.assert("You cannot use `store#pushPayload` without a type unless your default serializer defines `pushPayload`", serializer.pushPayload);
11413        } else {
11414          payload = inputPayload;
11415          serializer = this.serializerFor(type);
11416        }
11417        serializer.pushPayload(this, payload);
11418      },
11419
11420      /**
11421        `normalize` converts a json payload into the normalized form that
11422        [push](#method_push) expects.
11423
11424        Example
11425
11426        ```js
11427        socket.on('message', function(message) {
11428          var modelName = message.model;
11429          var data = message.data;
11430          store.push(modelName, store.normalize(modelName, data));
11431        });
11432        ```
11433
11434        @method normalize
11435        @param {String} type The name of the model type for this payload
11436        @param {Object} payload
11437        @return {Object} The normalized payload
11438      */
11439      normalize: function (type, payload) {
11440        var serializer = this.serializerFor(type);
11441        var model = this.modelFor(type);
11442        return serializer.normalize(model, payload);
11443      },
11444
11445      /**
11446        Update existing records in the store. Unlike [push](#method_push),
11447        update will merge the new data properties with the existing
11448        properties. This makes it safe to use with a subset of record
11449        attributes. This method expects normalized data.
11450
11451        `update` is useful if your app broadcasts partial updates to
11452        records.
11453
11454        ```js
11455        App.Person = DS.Model.extend({
11456          firstName: DS.attr('string'),
11457          lastName: DS.attr('string')
11458        });
11459
11460        store.get('person', 1).then(function(tom) {
11461          tom.get('firstName'); // Tom
11462          tom.get('lastName'); // Dale
11463
11464          var updateEvent = {id: 1, firstName: "TomHuda"};
11465          store.update('person', updateEvent);
11466
11467          tom.get('firstName'); // TomHuda
11468          tom.get('lastName'); // Dale
11469        });
11470        ```
11471
11472        @method update
11473        @param {String} type
11474        @param {Object} data
11475        @return {DS.Model} the record that was updated.
11476      */
11477      update: function(type, data) {
11478        Ember.assert("You must include an `id` for " + type + " in a hash passed to `update`", data.id != null);
11479
11480        return this.push(type, data, true);
11481      },
11482
11483      /**
11484        If you have an Array of normalized data to push,
11485        you can call `pushMany` with the Array, and it will
11486        call `push` repeatedly for you.
11487
11488        @method pushMany
11489        @param {String or subclass of DS.Model} type
11490        @param {Array} datas
11491        @return {Array}
11492      */
11493      pushMany: function(type, datas) {
11494        var length = datas.length;
11495        var result = new Array(length);
11496
11497        for (var i = 0; i < length; i++) {
11498          result[i] = this.push(type, datas[i]);
11499        }
11500
11501        return result;
11502      },
11503
11504      /**
11505        If you have some metadata to set for a type
11506        you can call `metaForType`.
11507
11508        @method metaForType
11509        @param {String or subclass of DS.Model} type
11510        @param {Object} metadata
11511      */
11512      metaForType: function(typeName, metadata) {
11513        var type = this.modelFor(typeName);
11514
11515        Ember.merge(this.typeMapFor(type).metadata, metadata);
11516      },
11517
11518      /**
11519        Build a brand new record for a given type, ID, and
11520        initial data.
11521
11522        @method buildRecord
11523        @private
11524        @param {subclass of DS.Model} type
11525        @param {String} id
11526        @param {Object} data
11527        @return {DS.Model} record
11528      */
11529      buildRecord: function(type, id, data) {
11530        var typeMap = this.typeMapFor(type);
11531        var idToRecord = typeMap.idToRecord;
11532
11533        Ember.assert('The id ' + id + ' has already been used with another record of type ' + type.toString() + '.', !id || !idToRecord[id]);
11534        Ember.assert("`" + Ember.inspect(type)+ "` does not appear to be an ember-data model", (typeof type._create === 'function') );
11535
11536        // lookupFactory should really return an object that creates
11537        // instances with the injections applied
11538        var record = type._create({
11539          id: id,
11540          store: this,
11541          container: this.container
11542        });
11543
11544        if (data) {
11545          record.setupData(data);
11546        }
11547
11548        // if we're creating an item, this process will be done
11549        // later, once the object has been persisted.
11550        if (id) {
11551          idToRecord[id] = record;
11552        }
11553
11554        typeMap.records.push(record);
11555
11556        return record;
11557      },
11558
11559      // ...............
11560      // . DESTRUCTION .
11561      // ...............
11562
11563      /**
11564        When a record is destroyed, this un-indexes it and
11565        removes it from any record arrays so it can be GCed.
11566
11567        @method dematerializeRecord
11568        @private
11569        @param {DS.Model} record
11570      */
11571      dematerializeRecord: function(record) {
11572        var type = record.constructor;
11573        var typeMap = this.typeMapFor(type);
11574        var id = get(record, 'id');
11575
11576        record.updateRecordArrays();
11577
11578        if (id) {
11579          delete typeMap.idToRecord[id];
11580        }
11581
11582        var loc = indexOf(typeMap.records, record);
11583        typeMap.records.splice(loc, 1);
11584      },
11585
11586      // ......................
11587      // . PER-TYPE ADAPTERS
11588      // ......................
11589
11590      /**
11591        Returns the adapter for a given type.
11592
11593        @method adapterFor
11594        @private
11595        @param {subclass of DS.Model} type
11596        @return DS.Adapter
11597      */
11598      adapterFor: function(type) {
11599        var container = this.container, adapter;
11600
11601        if (container) {
11602          adapter = container.lookup('adapter:' + type.typeKey) || container.lookup('adapter:application');
11603        }
11604
11605        return adapter || get(this, 'defaultAdapter');
11606      },
11607
11608      // ..............................
11609      // . RECORD CHANGE NOTIFICATION .
11610      // ..............................
11611
11612      /**
11613        Returns an instance of the serializer for a given type. For
11614        example, `serializerFor('person')` will return an instance of
11615        `App.PersonSerializer`.
11616
11617        If no `App.PersonSerializer` is found, this method will look
11618        for an `App.ApplicationSerializer` (the default serializer for
11619        your entire application).
11620
11621        If no `App.ApplicationSerializer` is found, it will fall back
11622        to an instance of `DS.JSONSerializer`.
11623
11624        @method serializerFor
11625        @private
11626        @param {String} type the record to serialize
11627        @return {DS.Serializer}
11628      */
11629      serializerFor: function(type) {
11630        type = this.modelFor(type);
11631        var adapter = this.adapterFor(type);
11632
11633        return serializerFor(this.container, type.typeKey, adapter && adapter.defaultSerializer);
11634      },
11635
11636      willDestroy: function() {
11637        var typeMaps = this.typeMaps;
11638        var keys = Ember.keys(typeMaps);
11639
11640        var types = map(keys, byType);
11641
11642        this.recordArrayManager.destroy();
11643
11644        forEach(types, this.unloadAll, this);
11645
11646        function byType(entry) {
11647          return typeMaps[entry]['type'];
11648        }
11649
11650      },
11651
11652      /**
11653        All typeKeys are camelCase internally. Changing this function may
11654        require changes to other normalization hooks (such as typeForRoot).
11655
11656        @method _normalizeTypeKey
11657        @private
11658        @param {String} type
11659        @return {String} if the adapter can generate one, an ID
11660      */
11661      _normalizeTypeKey: function(key) {
11662        return camelize(singularize(key));
11663      }
11664    });
11665
11666
11667    function normalizeRelationships(store, type, data, record) {
11668      type.eachRelationship(function(key, relationship) {
11669        var kind = relationship.kind;
11670        var value = data[key];
11671        if (kind === 'belongsTo') {
11672          deserializeRecordId(store, data, key, relationship, value);
11673        } else if (kind === 'hasMany') {
11674          deserializeRecordIds(store, data, key, relationship, value);
11675        }
11676      });
11677
11678      return data;
11679    }
11680
11681    function deserializeRecordId(store, data, key, relationship, id) {
11682      if (!Model) { Model = requireModule("ember-data/system/model")["Model"]; }
11683      if (isNone(id) || id instanceof Model) {
11684        return;
11685      }
11686
11687      var type;
11688
11689      if (typeof id === 'number' || typeof id === 'string') {
11690        type = typeFor(relationship, key, data);
11691        data[key] = store.recordForId(type, id);
11692      } else if (typeof id === 'object') {
11693        // polymorphic
11694        data[key] = store.recordForId(id.type, id.id);
11695      }
11696    }
11697
11698    function typeFor(relationship, key, data) {
11699      if (relationship.options.polymorphic) {
11700        return data[key + "Type"];
11701      } else {
11702        return relationship.type;
11703      }
11704    }
11705
11706    function deserializeRecordIds(store, data, key, relationship, ids) {
11707      if (!Ember.isArray(ids)) {
11708        return;
11709      }
11710      for (var i=0, l=ids.length; i<l; i++) {
11711        deserializeRecordId(store, ids, i, relationship, ids[i]);
11712      }
11713    }
11714
11715    // Delegation to the adapter and promise management
11716
11717
11718    function serializerFor(container, type, defaultSerializer) {
11719      return container.lookup('serializer:'+type) ||
11720                     container.lookup('serializer:application') ||
11721                     container.lookup('serializer:' + defaultSerializer) ||
11722                     container.lookup('serializer:-default');
11723    }
11724
11725    function defaultSerializer(container) {
11726      return container.lookup('serializer:application') ||
11727             container.lookup('serializer:-default');
11728    }
11729
11730    function serializerForAdapter(adapter, type) {
11731      var serializer = adapter.serializer;
11732      var defaultSerializer = adapter.defaultSerializer;
11733      var container = adapter.container;
11734
11735      if (container && serializer === undefined) {
11736        serializer = serializerFor(container, type.typeKey, defaultSerializer);
11737      }
11738
11739      if (serializer === null || serializer === undefined) {
11740        serializer = {
11741          extract: function(store, type, payload) { return payload; }
11742        };
11743      }
11744
11745      return serializer;
11746    }
11747
11748    function _objectIsAlive(object) {
11749      return !(get(object, "isDestroyed") || get(object, "isDestroying"));
11750    }
11751
11752    function _guard(promise, test) {
11753      var guarded = promise['finally'](function() {
11754        if (!test()) {
11755          guarded._subscribers.length = 0;
11756        }
11757      });
11758
11759      return guarded;
11760    }
11761
11762    function _bind(fn) {
11763      var args = Array.prototype.slice.call(arguments, 1);
11764
11765      return function() {
11766        return fn.apply(undefined, args);
11767      };
11768    }
11769
11770    function _find(adapter, store, type, id, record) {
11771      var promise = adapter.find(store, type, id, record);
11772      var serializer = serializerForAdapter(adapter, type);
11773      var label = "DS: Handle Adapter#find of " + type + " with id: " + id;
11774
11775      promise = Promise.cast(promise, label);
11776      promise = _guard(promise, _bind(_objectIsAlive, store));
11777
11778      return promise.then(function(adapterPayload) {
11779        Ember.assert("You made a request for a " + type.typeKey + " with id " + id + ", but the adapter's response did not have any data", adapterPayload);
11780        var payload = serializer.extract(store, type, adapterPayload, id, 'find');
11781
11782        return store.push(type, payload);
11783      }, function(error) {
11784        var record = store.getById(type, id);
11785        if (record) {
11786          record.notFound();
11787        }
11788        throw error;
11789      }, "DS: Extract payload of '" + type + "'");
11790    }
11791
11792
11793    function _findMany(adapter, store, type, ids, records) {
11794      var promise = adapter.findMany(store, type, ids, records);
11795      var serializer = serializerForAdapter(adapter, type);
11796      var label = "DS: Handle Adapter#findMany of " + type;
11797
11798      if (promise === undefined) {
11799        throw new Error('adapter.findMany returned undefined, this was very likely a mistake');
11800      }
11801
11802      promise = Promise.cast(promise, label);
11803      promise = _guard(promise, _bind(_objectIsAlive, store));
11804
11805      return promise.then(function(adapterPayload) {
11806        var payload = serializer.extract(store, type, adapterPayload, null, 'findMany');
11807
11808        Ember.assert("The response from a findMany must be an Array, not " + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
11809
11810        return store.pushMany(type, payload);
11811      }, null, "DS: Extract payload of " + type);
11812    }
11813
11814    function _findHasMany(adapter, store, record, link, relationship) {
11815      var promise = adapter.findHasMany(store, record, link, relationship);
11816      var serializer = serializerForAdapter(adapter, relationship.type);
11817      var label = "DS: Handle Adapter#findHasMany of " + record + " : " + relationship.type;
11818
11819      promise = Promise.cast(promise, label);
11820      promise = _guard(promise, _bind(_objectIsAlive, store));
11821      promise = _guard(promise, _bind(_objectIsAlive, record));
11822
11823      return promise.then(function(adapterPayload) {
11824        var payload = serializer.extract(store, relationship.type, adapterPayload, null, 'findHasMany');
11825
11826        Ember.assert("The response from a findHasMany must be an Array, not " + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
11827
11828        var records = store.pushMany(relationship.type, payload);
11829        return records;
11830      }, null, "DS: Extract payload of " + record + " : hasMany " + relationship.type);
11831    }
11832
11833    function _findBelongsTo(adapter, store, record, link, relationship) {
11834      var promise = adapter.findBelongsTo(store, record, link, relationship);
11835      var serializer = serializerForAdapter(adapter, relationship.type);
11836      var label = "DS: Handle Adapter#findBelongsTo of " + record + " : " + relationship.type;
11837
11838      promise = Promise.cast(promise, label);
11839      promise = _guard(promise, _bind(_objectIsAlive, store));
11840      promise = _guard(promise, _bind(_objectIsAlive, record));
11841
11842      return promise.then(function(adapterPayload) {
11843        var payload = serializer.extract(store, relationship.type, adapterPayload, null, 'findBelongsTo');
11844        var record = store.push(relationship.type, payload);
11845        return record;
11846      }, null, "DS: Extract payload of " + record + " : " + relationship.type);
11847    }
11848
11849    function _findAll(adapter, store, type, sinceToken) {
11850      var promise = adapter.findAll(store, type, sinceToken);
11851      var serializer = serializerForAdapter(adapter, type);
11852      var label = "DS: Handle Adapter#findAll of " + type;
11853
11854      promise = Promise.cast(promise, label);
11855      promise = _guard(promise, _bind(_objectIsAlive, store));
11856
11857      return promise.then(function(adapterPayload) {
11858        var payload = serializer.extract(store, type, adapterPayload, null, 'findAll');
11859
11860        Ember.assert("The response from a findAll must be an Array, not " + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
11861
11862        store.pushMany(type, payload);
11863        store.didUpdateAll(type);
11864        return store.all(type);
11865      }, null, "DS: Extract payload of findAll " + type);
11866    }
11867
11868    function _findQuery(adapter, store, type, query, recordArray) {
11869      var promise = adapter.findQuery(store, type, query, recordArray);
11870      var serializer = serializerForAdapter(adapter, type);
11871      var label = "DS: Handle Adapter#findQuery of " + type;
11872
11873      promise = Promise.cast(promise, label);
11874      promise = _guard(promise, _bind(_objectIsAlive, store));
11875
11876      return promise.then(function(adapterPayload) {
11877        var payload = serializer.extract(store, type, adapterPayload, null, 'findQuery');
11878
11879        Ember.assert("The response from a findQuery must be an Array, not " + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
11880
11881        recordArray.load(payload);
11882        return recordArray;
11883      }, null, "DS: Extract payload of findQuery " + type);
11884    }
11885
11886    function _commit(adapter, store, operation, record) {
11887      var type = record.constructor;
11888      var promise = adapter[operation](store, type, record);
11889      var serializer = serializerForAdapter(adapter, type);
11890      var label = "DS: Extract and notify about " + operation + " completion of " + record;
11891
11892      Ember.assert("Your adapter's '" + operation + "' method must return a value, but it returned `undefined", promise !==undefined);
11893
11894      promise = Promise.cast(promise, label);
11895      promise = _guard(promise, _bind(_objectIsAlive, store));
11896      promise = _guard(promise, _bind(_objectIsAlive, record));
11897
11898      return promise.then(function(adapterPayload) {
11899        var payload;
11900
11901        if (adapterPayload) {
11902          payload = serializer.extract(store, type, adapterPayload, get(record, 'id'), operation);
11903        } else {
11904          payload = adapterPayload;
11905        }
11906
11907        store.didSaveRecord(record, payload);
11908        return record;
11909      }, function(reason) {
11910        if (reason instanceof InvalidError) {
11911          store.recordWasInvalid(record, reason.errors);
11912        } else {
11913          store.recordWasError(record, reason);
11914        }
11915
11916        throw reason;
11917      }, label);
11918    }
11919
11920    function setupRelationships(store, record, data) {
11921      var type = record.constructor;
11922
11923      type.eachRelationship(function(key, descriptor) {
11924        var kind = descriptor.kind;
11925        var value = data[key];
11926        var relationship = record._relationships[key];
11927
11928        if (data.links && data.links[key]) {
11929          relationship.updateLink(data.links[key]);
11930        }
11931
11932        if (kind === 'belongsTo') {
11933          if (value === undefined) {
11934            return;
11935          }
11936          relationship.setRecord(value);
11937        } else if (kind === 'hasMany' && value) {
11938         relationship.updateRecordsFromAdapter(value);
11939        }
11940      });
11941    }
11942
11943    __exports__.Store = Store;
11944    __exports__["default"] = Store;
11945  });
11946define("ember-data/transforms",
11947  ["ember-data/transforms/base","ember-data/transforms/number","ember-data/transforms/date","ember-data/transforms/string","ember-data/transforms/boolean","exports"],
11948  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
11949    "use strict";
11950    var Transform = __dependency1__["default"];
11951    var NumberTransform = __dependency2__["default"];
11952    var DateTransform = __dependency3__["default"];
11953    var StringTransform = __dependency4__["default"];
11954    var BooleanTransform = __dependency5__["default"];
11955
11956    __exports__.Transform = Transform;
11957    __exports__.NumberTransform = NumberTransform;
11958    __exports__.DateTransform = DateTransform;
11959    __exports__.StringTransform = StringTransform;
11960    __exports__.BooleanTransform = BooleanTransform;
11961  });
11962define("ember-data/transforms/base",
11963  ["exports"],
11964  function(__exports__) {
11965    "use strict";
11966    /**
11967      The `DS.Transform` class is used to serialize and deserialize model
11968      attributes when they are saved or loaded from an
11969      adapter. Subclassing `DS.Transform` is useful for creating custom
11970      attributes. All subclasses of `DS.Transform` must implement a
11971      `serialize` and a `deserialize` method.
11972
11973      Example
11974
11975      ```javascript
11976      // Converts centigrade in the JSON to fahrenheit in the app
11977      App.TemperatureTransform = DS.Transform.extend({
11978        deserialize: function(serialized) {
11979          return (serialized *  1.8) + 32;
11980        },
11981        serialize: function(deserialized) {
11982          return (deserialized - 32) / 1.8;
11983        }
11984      });
11985      ```
11986
11987      Usage
11988
11989      ```javascript
11990      var attr = DS.attr;
11991      App.Requirement = DS.Model.extend({
11992        name: attr('string'),
11993        temperature: attr('temperature')
11994      });
11995      ```
11996
11997      @class Transform
11998      @namespace DS
11999     */
12000    __exports__["default"] = Ember.Object.extend({
12001      /**
12002        When given a deserialized value from a record attribute this
12003        method must return the serialized value.
12004
12005        Example
12006
12007        ```javascript
12008        serialize: function(deserialized) {
12009          return Ember.isEmpty(deserialized) ? null : Number(deserialized);
12010        }
12011        ```
12012
12013        @method serialize
12014        @param {mixed} deserialized The deserialized value
12015        @return {mixed} The serialized value
12016      */
12017      serialize: Ember.required(),
12018
12019      /**
12020        When given a serialize value from a JSON object this method must
12021        return the deserialized value for the record attribute.
12022
12023        Example
12024
12025        ```javascript
12026        deserialize: function(serialized) {
12027          return empty(serialized) ? null : Number(serialized);
12028        }
12029        ```
12030
12031        @method deserialize
12032        @param {mixed} serialized The serialized value
12033        @return {mixed} The deserialized value
12034      */
12035      deserialize: Ember.required()
12036    });
12037  });
12038define("ember-data/transforms/boolean",
12039  ["ember-data/transforms/base","exports"],
12040  function(__dependency1__, __exports__) {
12041    "use strict";
12042    var Transform = __dependency1__["default"];
12043
12044    /**
12045      The `DS.BooleanTransform` class is used to serialize and deserialize
12046      boolean attributes on Ember Data record objects. This transform is
12047      used when `boolean` is passed as the type parameter to the
12048      [DS.attr](../../data#method_attr) function.
12049
12050      Usage
12051
12052      ```javascript
12053      var attr = DS.attr;
12054      App.User = DS.Model.extend({
12055        isAdmin: attr('boolean'),
12056        name: attr('string'),
12057        email: attr('string')
12058      });
12059      ```
12060
12061      @class BooleanTransform
12062      @extends DS.Transform
12063      @namespace DS
12064     */
12065    __exports__["default"] = Transform.extend({
12066      deserialize: function(serialized) {
12067        var type = typeof serialized;
12068
12069        if (type === "boolean") {
12070          return serialized;
12071        } else if (type === "string") {
12072          return serialized.match(/^true$|^t$|^1$/i) !== null;
12073        } else if (type === "number") {
12074          return serialized === 1;
12075        } else {
12076          return false;
12077        }
12078      },
12079
12080      serialize: function(deserialized) {
12081        return Boolean(deserialized);
12082      }
12083    });
12084  });
12085define("ember-data/transforms/date",
12086  ["ember-data/transforms/base","exports"],
12087  function(__dependency1__, __exports__) {
12088    "use strict";
12089    /**
12090      The `DS.DateTransform` class is used to serialize and deserialize
12091      date attributes on Ember Data record objects. This transform is used
12092      when `date` is passed as the type parameter to the
12093      [DS.attr](../../data#method_attr) function.
12094
12095      ```javascript
12096      var attr = DS.attr;
12097      App.Score = DS.Model.extend({
12098        value: attr('number'),
12099        player: DS.belongsTo('player'),
12100        date: attr('date')
12101      });
12102      ```
12103
12104      @class DateTransform
12105      @extends DS.Transform
12106      @namespace DS
12107     */
12108    var Transform = __dependency1__["default"];
12109
12110    // Date.prototype.toISOString shim
12111    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
12112    var toISOString = Date.prototype.toISOString || function() {
12113      function pad(number) {
12114        if ( number < 10 ) {
12115          return '0' + number;
12116        }
12117        return number;
12118      }
12119
12120      return this.getUTCFullYear() +
12121        '-' + pad( this.getUTCMonth() + 1 ) +
12122        '-' + pad( this.getUTCDate() ) +
12123        'T' + pad( this.getUTCHours() ) +
12124        ':' + pad( this.getUTCMinutes() ) +
12125        ':' + pad( this.getUTCSeconds() ) +
12126        '.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) +
12127        'Z';
12128    };
12129
12130    if (Ember.SHIM_ES5) {
12131      if (!Date.prototype.toISOString) {
12132        Date.prototype.toISOString = toISOString;
12133      }
12134    }
12135
12136    __exports__["default"] = Transform.extend({
12137
12138      deserialize: function(serialized) {
12139        var type = typeof serialized;
12140
12141        if (type === "string") {
12142          return new Date(Ember.Date.parse(serialized));
12143        } else if (type === "number") {
12144          return new Date(serialized);
12145        } else if (serialized === null || serialized === undefined) {
12146          // if the value is not present in the data,
12147          // return undefined, not null.
12148          return serialized;
12149        } else {
12150          return null;
12151        }
12152      },
12153
12154      serialize: function(date) {
12155        if (date instanceof Date) {
12156          return toISOString.call(date);
12157        } else {
12158          return null;
12159        }
12160      }
12161    });
12162  });
12163define("ember-data/transforms/number",
12164  ["ember-data/transforms/base","exports"],
12165  function(__dependency1__, __exports__) {
12166    "use strict";
12167    var Transform = __dependency1__["default"];
12168
12169    var empty = Ember.isEmpty;
12170
12171    /**
12172      The `DS.NumberTransform` class is used to serialize and deserialize
12173      numeric attributes on Ember Data record objects. This transform is
12174      used when `number` is passed as the type parameter to the
12175      [DS.attr](../../data#method_attr) function.
12176
12177      Usage
12178
12179      ```javascript
12180      var attr = DS.attr;
12181      App.Score = DS.Model.extend({
12182        value: attr('number'),
12183        player: DS.belongsTo('player'),
12184        date: attr('date')
12185      });
12186      ```
12187
12188      @class NumberTransform
12189      @extends DS.Transform
12190      @namespace DS
12191     */
12192    __exports__["default"] = Transform.extend({
12193      deserialize: function(serialized) {
12194        return empty(serialized) ? null : Number(serialized);
12195      },
12196
12197      serialize: function(deserialized) {
12198        return empty(deserialized) ? null : Number(deserialized);
12199      }
12200    });
12201  });
12202define("ember-data/transforms/string",
12203  ["ember-data/transforms/base","exports"],
12204  function(__dependency1__, __exports__) {
12205    "use strict";
12206    var Transform = __dependency1__["default"];
12207    var none = Ember.isNone;
12208
12209    /**
12210      The `DS.StringTransform` class is used to serialize and deserialize
12211      string attributes on Ember Data record objects. This transform is
12212      used when `string` is passed as the type parameter to the
12213      [DS.attr](../../data#method_attr) function.
12214
12215      Usage
12216
12217      ```javascript
12218      var attr = DS.attr;
12219      App.User = DS.Model.extend({
12220        isAdmin: attr('boolean'),
12221        name: attr('string'),
12222        email: attr('string')
12223      });
12224      ```
12225
12226      @class StringTransform
12227      @extends DS.Transform
12228      @namespace DS
12229     */
12230    __exports__["default"] = Transform.extend({
12231      deserialize: function(serialized) {
12232        return none(serialized) ? null : String(serialized);
12233      },
12234      serialize: function(deserialized) {
12235        return none(deserialized) ? null : String(deserialized);
12236      }
12237    });
12238  });
12239define("ember-inflector",
12240  ["./system","./helpers","./ext/string","exports"],
12241  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
12242    "use strict";
12243    var Inflector = __dependency1__.Inflector;
12244    var defaultRules = __dependency1__.defaultRules;
12245    var pluralize = __dependency1__.pluralize;
12246    var singularize = __dependency1__.singularize;
12247
12248    Inflector.defaultRules = defaultRules;
12249    Ember.Inflector        = Inflector;
12250
12251    Ember.String.pluralize   = pluralize;
12252    Ember.String.singularize = singularize;
12253
12254
12255    __exports__["default"] = Inflector;
12256
12257    __exports__.pluralize = pluralize;
12258    __exports__.singularize = singularize;
12259  });
12260define("ember-inflector/ext/string",
12261  ["../system/string"],
12262  function(__dependency1__) {
12263    "use strict";
12264    var pluralize = __dependency1__.pluralize;
12265    var singularize = __dependency1__.singularize;
12266
12267    if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
12268      /**
12269        See {{#crossLink "Ember.String/pluralize"}}{{/crossLink}}
12270
12271        @method pluralize
12272        @for String
12273      */
12274      String.prototype.pluralize = function() {
12275        return pluralize(this);
12276      };
12277
12278      /**
12279        See {{#crossLink "Ember.String/singularize"}}{{/crossLink}}
12280
12281        @method singularize
12282        @for String
12283      */
12284      String.prototype.singularize = function() {
12285        return singularize(this);
12286      };
12287    }
12288  });
12289define("ember-inflector/helpers",
12290  ["./system/string"],
12291  function(__dependency1__) {
12292    "use strict";
12293    var singularize = __dependency1__.singularize;
12294    var pluralize = __dependency1__.pluralize;
12295
12296    /**
12297     *
12298     * If you have Ember Inflector (such as if Ember Data is present),
12299     * singularize a word. For example, turn "oxen" into "ox".
12300     *
12301     * Example:
12302     *
12303     * {{singularize myProperty}}
12304     * {{singularize "oxen"}}
12305     *
12306     * @for Ember.Handlebars.helpers
12307     * @method singularize
12308     * @param {String|Property} word word to singularize
12309    */
12310    Ember.Handlebars.helper('singularize', singularize);
12311
12312    /**
12313     *
12314     * If you have Ember Inflector (such as if Ember Data is present),
12315     * pluralize a word. For example, turn "ox" into "oxen".
12316     *
12317     * Example:
12318     *
12319     * {{pluralize myProperty}}
12320     * {{pluralize "oxen"}}
12321     *
12322     * @for Ember.Handlebars.helpers
12323     * @method pluralize
12324     * @param {String|Property} word word to pluralize
12325    */
12326    Ember.Handlebars.helper('pluralize', pluralize);
12327  });
12328define("ember-inflector/system",
12329  ["./system/inflector","./system/string","./system/inflections","exports"],
12330  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
12331    "use strict";
12332    var Inflector = __dependency1__["default"];
12333
12334    var pluralize = __dependency2__.pluralize;
12335    var singularize = __dependency2__.singularize;
12336
12337    var defaultRules = __dependency3__["default"];
12338
12339    
12340    Inflector.inflector = new Inflector(defaultRules);
12341    
12342    __exports__.Inflector = Inflector;
12343    __exports__.singularize = singularize;
12344    __exports__.pluralize = pluralize;
12345    __exports__.defaultRules = defaultRules;
12346  });
12347define("ember-inflector/system/inflections",
12348  ["exports"],
12349  function(__exports__) {
12350    "use strict";
12351    __exports__["default"] = {
12352      plurals: [
12353        [/$/, 's'],
12354        [/s$/i, 's'],
12355        [/^(ax|test)is$/i, '$1es'],
12356        [/(octop|vir)us$/i, '$1i'],
12357        [/(octop|vir)i$/i, '$1i'],
12358        [/(alias|status)$/i, '$1es'],
12359        [/(bu)s$/i, '$1ses'],
12360        [/(buffal|tomat)o$/i, '$1oes'],
12361        [/([ti])um$/i, '$1a'],
12362        [/([ti])a$/i, '$1a'],
12363        [/sis$/i, 'ses'],
12364        [/(?:([^f])fe|([lr])f)$/i, '$1$2ves'],
12365        [/(hive)$/i, '$1s'],
12366        [/([^aeiouy]|qu)y$/i, '$1ies'],
12367        [/(x|ch|ss|sh)$/i, '$1es'],
12368        [/(matr|vert|ind)(?:ix|ex)$/i, '$1ices'],
12369        [/^(m|l)ouse$/i, '$1ice'],
12370        [/^(m|l)ice$/i, '$1ice'],
12371        [/^(ox)$/i, '$1en'],
12372        [/^(oxen)$/i, '$1'],
12373        [/(quiz)$/i, '$1zes']
12374      ],
12375
12376      singular: [
12377        [/s$/i, ''],
12378        [/(ss)$/i, '$1'],
12379        [/(n)ews$/i, '$1ews'],
12380        [/([ti])a$/i, '$1um'],
12381        [/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '$1sis'],
12382        [/(^analy)(sis|ses)$/i, '$1sis'],
12383        [/([^f])ves$/i, '$1fe'],
12384        [/(hive)s$/i, '$1'],
12385        [/(tive)s$/i, '$1'],
12386        [/([lr])ves$/i, '$1f'],
12387        [/([^aeiouy]|qu)ies$/i, '$1y'],
12388        [/(s)eries$/i, '$1eries'],
12389        [/(m)ovies$/i, '$1ovie'],
12390        [/(x|ch|ss|sh)es$/i, '$1'],
12391        [/^(m|l)ice$/i, '$1ouse'],
12392        [/(bus)(es)?$/i, '$1'],
12393        [/(o)es$/i, '$1'],
12394        [/(shoe)s$/i, '$1'],
12395        [/(cris|test)(is|es)$/i, '$1is'],
12396        [/^(a)x[ie]s$/i, '$1xis'],
12397        [/(octop|vir)(us|i)$/i, '$1us'],
12398        [/(alias|status)(es)?$/i, '$1'],
12399        [/^(ox)en/i, '$1'],
12400        [/(vert|ind)ices$/i, '$1ex'],
12401        [/(matr)ices$/i, '$1ix'],
12402        [/(quiz)zes$/i, '$1'],
12403        [/(database)s$/i, '$1']
12404      ],
12405
12406      irregularPairs: [
12407        ['person', 'people'],
12408        ['man', 'men'],
12409        ['child', 'children'],
12410        ['sex', 'sexes'],
12411        ['move', 'moves'],
12412        ['cow', 'kine'],
12413        ['zombie', 'zombies']
12414      ],
12415
12416      uncountable: [
12417        'equipment',
12418        'information',
12419        'rice',
12420        'money',
12421        'species',
12422        'series',
12423        'fish',
12424        'sheep',
12425        'jeans',
12426        'police'
12427      ]
12428    };
12429  });
12430define("ember-inflector/system/inflector",
12431  ["exports"],
12432  function(__exports__) {
12433    "use strict";
12434    var BLANK_REGEX = /^\s*$/;
12435    var LAST_WORD_DASHED_REGEX = /(\w+[_-])([a-z\d]+$)/;
12436    var LAST_WORD_CAMELIZED_REGEX = /(\w+)([A-Z][a-z\d]*$)/;
12437    var CAMELIZED_REGEX = /[A-Z][a-z\d]*$/;
12438
12439    function loadUncountable(rules, uncountable) {
12440      for (var i = 0, length = uncountable.length; i < length; i++) {
12441        rules.uncountable[uncountable[i].toLowerCase()] = true;
12442      }
12443    }
12444
12445    function loadIrregular(rules, irregularPairs) {
12446      var pair;
12447
12448      for (var i = 0, length = irregularPairs.length; i < length; i++) {
12449        pair = irregularPairs[i];
12450
12451        //pluralizing
12452        rules.irregular[pair[0].toLowerCase()] = pair[1];
12453        rules.irregular[pair[1].toLowerCase()] = pair[1];
12454
12455        //singularizing
12456        rules.irregularInverse[pair[1].toLowerCase()] = pair[0];
12457        rules.irregularInverse[pair[0].toLowerCase()] = pair[0];
12458      }
12459    }
12460
12461    /**
12462      Inflector.Ember provides a mechanism for supplying inflection rules for your
12463      application. Ember includes a default set of inflection rules, and provides an
12464      API for providing additional rules.
12465
12466      Examples:
12467
12468      Creating an inflector with no rules.
12469
12470      ```js
12471      var inflector = new Ember.Inflector();
12472      ```
12473
12474      Creating an inflector with the default ember ruleset.
12475
12476      ```js
12477      var inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
12478
12479      inflector.pluralize('cow'); //=> 'kine'
12480      inflector.singularize('kine'); //=> 'cow'
12481      ```
12482
12483      Creating an inflector and adding rules later.
12484
12485      ```javascript
12486      var inflector = Ember.Inflector.inflector;
12487
12488      inflector.pluralize('advice'); // => 'advices'
12489      inflector.uncountable('advice');
12490      inflector.pluralize('advice'); // => 'advice'
12491
12492      inflector.pluralize('formula'); // => 'formulas'
12493      inflector.irregular('formula', 'formulae');
12494      inflector.pluralize('formula'); // => 'formulae'
12495
12496      // you would not need to add these as they are the default rules
12497      inflector.plural(/$/, 's');
12498      inflector.singular(/s$/i, '');
12499      ```
12500
12501      Creating an inflector with a nondefault ruleset.
12502
12503      ```javascript
12504      var rules = {
12505        plurals:  [ /$/, 's' ],
12506        singular: [ /\s$/, '' ],
12507        irregularPairs: [
12508          [ 'cow', 'kine' ]
12509        ],
12510        uncountable: [ 'fish' ]
12511      };
12512
12513      var inflector = new Ember.Inflector(rules);
12514      ```
12515
12516      @class Inflector
12517      @namespace Ember
12518    */
12519    function Inflector(ruleSet) {
12520      ruleSet = ruleSet || {};
12521      ruleSet.uncountable = ruleSet.uncountable || makeDictionary();
12522      ruleSet.irregularPairs = ruleSet.irregularPairs || makeDictionary();
12523
12524      var rules = this.rules = {
12525        plurals:  ruleSet.plurals || [],
12526        singular: ruleSet.singular || [],
12527        irregular: makeDictionary(),
12528        irregularInverse: makeDictionary(),
12529        uncountable: makeDictionary()
12530      };
12531
12532      loadUncountable(rules, ruleSet.uncountable);
12533      loadIrregular(rules, ruleSet.irregularPairs);
12534
12535      this.enableCache();
12536    }
12537
12538    if (!Object.create && !Object.create(null).hasOwnProperty) {
12539      throw new Error("This browser does not support Object.create(null), please polyfil with es5-sham: http://git.io/yBU2rg");
12540    }
12541
12542    function makeDictionary() {
12543      var cache = Object.create(null);
12544      cache['_dict'] = null;
12545      delete cache['_dict'];
12546      return cache;
12547    }
12548
12549    Inflector.prototype = {
12550      /**
12551        @public
12552
12553        As inflections can be costly, and commonly the same subset of words are repeatedly
12554        inflected an optional cache is provided.
12555
12556        @method enableCache
12557      */
12558      enableCache: function() {
12559        this.purgeCache();
12560
12561        this.singularize = function(word) {
12562          this._cacheUsed = true;
12563          return this._sCache[word] || (this._sCache[word] = this._singularize(word));
12564        };
12565
12566        this.pluralize = function(word) {
12567          this._cacheUsed = true;
12568          return this._pCache[word] || (this._pCache[word] = this._pluralize(word));
12569        };
12570      },
12571
12572      /**
12573        @public
12574
12575        @method purgedCache
12576      */
12577      purgeCache: function() {
12578        this._cacheUsed = false;
12579        this._sCache = makeDictionary();
12580        this._pCache = makeDictionary();
12581      },
12582
12583      /**
12584        @public
12585        disable caching
12586
12587        @method disableCache;
12588      */
12589      disableCache: function() {
12590        this._sCache = null;
12591        this._pCache = null;
12592        this.singularize = function(word) {
12593          return this._singularize(word);
12594        };
12595
12596        this.pluralize = function(word) {
12597          return this._pluralize(word);
12598        };
12599      },
12600
12601      /**
12602        @method plural
12603        @param {RegExp} regex
12604        @param {String} string
12605      */
12606      plural: function(regex, string) {
12607        if (this._cacheUsed) { this.purgeCache(); }
12608        this.rules.plurals.push([regex, string.toLowerCase()]);
12609      },
12610
12611      /**
12612        @method singular
12613        @param {RegExp} regex
12614        @param {String} string
12615      */
12616      singular: function(regex, string) {
12617        if (this._cacheUsed) { this.purgeCache(); }
12618        this.rules.singular.push([regex, string.toLowerCase()]);
12619      },
12620
12621      /**
12622        @method uncountable
12623        @param {String} regex
12624      */
12625      uncountable: function(string) {
12626        if (this._cacheUsed) { this.purgeCache(); }
12627        loadUncountable(this.rules, [string.toLowerCase()]);
12628      },
12629
12630      /**
12631        @method irregular
12632        @param {String} singular
12633        @param {String} plural
12634      */
12635      irregular: function (singular, plural) {
12636        if (this._cacheUsed) { this.purgeCache(); }
12637        loadIrregular(this.rules, [[singular, plural]]);
12638      },
12639
12640      /**
12641        @method pluralize
12642        @param {String} word
12643      */
12644      pluralize: function(word) {
12645        return this._pluralize(word);
12646      },
12647
12648      _pluralize: function(word) {
12649        return this.inflect(word, this.rules.plurals, this.rules.irregular);
12650      },
12651      /**
12652        @method singularize
12653        @param {String} word
12654      */
12655      singularize: function(word) {
12656        return this._singularize(word);
12657      },
12658
12659      _singularize: function(word) {
12660        return this.inflect(word, this.rules.singular,  this.rules.irregularInverse);
12661      },
12662
12663      /**
12664        @protected
12665
12666        @method inflect
12667        @param {String} word
12668        @param {Object} typeRules
12669        @param {Object} irregular
12670      */
12671      inflect: function(word, typeRules, irregular) {
12672        var inflection, substitution, result, lowercase, wordSplit,
12673          firstPhrase, lastWord, isBlank, isCamelized, isUncountable, 
12674          isIrregular, isIrregularInverse, rule;
12675      
12676        isBlank = BLANK_REGEX.test(word);
12677        isCamelized = CAMELIZED_REGEX.test(word);
12678        firstPhrase = "";
12679
12680        if (isBlank) {
12681          return word;
12682        }
12683
12684        lowercase = word.toLowerCase();
12685        wordSplit = LAST_WORD_DASHED_REGEX.exec(word) || LAST_WORD_CAMELIZED_REGEX.exec(word);
12686        if (wordSplit){
12687          firstPhrase = wordSplit[1];
12688          lastWord = wordSplit[2].toLowerCase();
12689        }
12690
12691        isUncountable = this.rules.uncountable[lowercase] || this.rules.uncountable[lastWord];
12692
12693        if (isUncountable) {
12694          return word;
12695        }
12696
12697        isIrregular = irregular && (irregular[lowercase] || irregular[lastWord]);
12698
12699        if (isIrregular) {
12700          if (irregular[lowercase]){
12701            return isIrregular;
12702          }
12703          else {
12704            isIrregular = (isCamelized) ? isIrregular.capitalize() : isIrregular;
12705            return firstPhrase + isIrregular;
12706          }
12707        }
12708
12709        for (var i = typeRules.length, min = 0; i > min; i--) {
12710           inflection = typeRules[i-1];
12711           rule = inflection[0];
12712
12713          if (rule.test(word)) {
12714            break;
12715          }
12716        }
12717
12718        inflection = inflection || [];
12719
12720        rule = inflection[0];
12721        substitution = inflection[1];
12722
12723        result = word.replace(rule, substitution);
12724
12725        return result;
12726      }
12727    };
12728
12729    __exports__["default"] = Inflector;
12730  });
12731define("ember-inflector/system/string",
12732  ["./inflector","exports"],
12733  function(__dependency1__, __exports__) {
12734    "use strict";
12735    var Inflector = __dependency1__["default"];
12736
12737    function pluralize(word) {
12738      return Inflector.inflector.pluralize(word);
12739    }
12740
12741    function singularize(word) {
12742      return Inflector.inflector.singularize(word);
12743    }
12744
12745    __exports__.pluralize = pluralize;
12746    __exports__.singularize = singularize;
12747  });
12748 global.DS = requireModule('ember-data')['default'];
12749 })(this);