epf-source 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. data/dist/epf.js +1053 -1083
  2. data/dist/epf.js.map +1 -1
  3. metadata +2 -2
@@ -34,7 +34,7 @@
34
34
  var cwd = '/';
35
35
  return {
36
36
  title: 'browser',
37
- version: 'v0.10.13',
37
+ version: 'v0.10.17',
38
38
  browser: true,
39
39
  env: {},
40
40
  argv: [],
@@ -50,11 +50,15 @@
50
50
  };
51
51
  }();
52
52
  require.define('/lib/index.js', function (module, exports, __dirname, __filename) {
53
+ require('/vendor/ember-inflector.js', module);
54
+ Ember.Inflector.loadAll();
53
55
  global.Ep = Ember.Namespace.create();
56
+ require('/lib/version.js', module);
54
57
  require('/lib/initializer.js', module);
55
58
  require('/lib/model/index.js', module);
56
59
  require('/lib/session/index.js', module);
57
60
  require('/lib/serializer/index.js', module);
61
+ require('/lib/transforms/index.js', module);
58
62
  require('/lib/local/index.js', module);
59
63
  require('/lib/rest/index.js', module);
60
64
  });
@@ -66,18 +70,35 @@
66
70
  require('/lib/serializer/index.js', module);
67
71
  var get = Ember.get;
68
72
  Ep.RestSerializer = Ep.JsonSerializer.extend({
69
- keyForAttributeName: function (type, name) {
70
- return Ember.String.decamelize(name);
73
+ metaKey: 'meta',
74
+ deserializePayload: function (hash, context) {
75
+ var result = [], metaKey = get(this, 'metaKey');
76
+ for (var prop in hash) {
77
+ if (!hash.hasOwnProperty(prop) || prop === metaKey) {
78
+ continue;
79
+ }
80
+ var type = this.typeFor(prop);
81
+ Ember.assert('Your server returned a hash with the key ' + prop + ' but has no corresponding type.', !!type);
82
+ var value = hash[prop];
83
+ if (value instanceof Array) {
84
+ for (var i = 0; i < value.length; i++) {
85
+ result.push(this.deserialize(type, value[i]));
86
+ }
87
+ } else {
88
+ result.push(this.deserialize(type, value));
89
+ }
90
+ }
91
+ return result;
71
92
  },
72
- keyForBelongsTo: function (type, name) {
73
- var key = this.keyForAttributeName(type, name);
93
+ keyForBelongsTo: function (name, type) {
94
+ var key = this._super(name, type);
74
95
  if (this.embeddedType(type, name)) {
75
96
  return key;
76
97
  }
77
98
  return key + '_id';
78
99
  },
79
- keyForHasMany: function (type, name) {
80
- var key = this.keyForAttributeName(type, name);
100
+ keyForHasMany: function (name, type) {
101
+ var key = this._super(name, type);
81
102
  if (this.embeddedType(type, name)) {
82
103
  return key;
83
104
  }
@@ -92,7 +113,7 @@
92
113
  extractValidationErrors: function (type, json) {
93
114
  var errors = {};
94
115
  get(type, 'attributes').forEach(function (name) {
95
- var key = this._keyForAttributeName(type, name);
116
+ var key = this.keyFor(name, type);
96
117
  if (json['errors'].hasOwnProperty(key)) {
97
118
  errors[name] = json['errors'][key];
98
119
  }
@@ -103,366 +124,23 @@
103
124
  });
104
125
  require.define('/lib/serializer/index.js', function (module, exports, __dirname, __filename) {
105
126
  require('/lib/serializer/serializer.js', module);
106
- require('/lib/serializer/json_serializer.js', module);
107
- });
108
- require.define('/lib/serializer/json_serializer.js', function (module, exports, __dirname, __filename) {
109
- require('/lib/serializer/serializer.js', module);
110
- require('/lib/transforms/json_transforms.js', module);
111
- var get = Ember.get, set = Ember.set;
112
- Ep.JsonSerializer = Ep.Serializer.extend({
113
- init: function () {
114
- this._super.apply(this, arguments);
115
- if (!get(this, 'transforms')) {
116
- this.set('transforms', Ep.JsonTransforms);
117
- }
118
- this.sideloadMapping = Ember.Map.create();
119
- this.metadataMapping = Ember.Map.create();
120
- this.configure({
121
- meta: 'meta',
122
- since: 'since'
123
- });
124
- },
125
- configure: function (type, configuration) {
126
- var key;
127
- if (type && !configuration) {
128
- for (key in type) {
129
- this.metadataMapping.set(get(type, key), key);
130
- }
131
- return this._super(type);
132
- }
133
- var sideloadAs = configuration.sideloadAs, sideloadMapping;
134
- if (sideloadAs) {
135
- sideloadMapping = this.aliases.sideloadMapping || Ember.Map.create();
136
- sideloadMapping.set(sideloadAs, type);
137
- this.aliases.sideloadMapping = sideloadMapping;
138
- delete configuration.sideloadAs;
139
- }
140
- this._super.apply(this, arguments);
141
- },
142
- addId: function (data, key, id) {
143
- data[key] = id;
144
- },
145
- addAttribute: function (hash, key, value) {
146
- hash[key] = value;
147
- },
148
- extractAttribute: function (type, hash, attributeName) {
149
- var key = this._keyForAttributeName(type, attributeName);
150
- return hash[key];
151
- },
152
- extractId: function (type, hash) {
153
- var primaryKey = this._primaryKey(type);
154
- if (hash.hasOwnProperty(primaryKey)) {
155
- return hash[primaryKey] + '';
156
- } else {
157
- return null;
158
- }
159
- },
160
- extractClientId: function (type, hash) {
161
- var clientKey = this._clientKey(type);
162
- if (hash.hasOwnProperty(clientKey) && hash[clientKey] !== null) {
163
- return hash[clientKey] + '';
164
- } else {
165
- return null;
166
- }
167
- },
168
- extractRevision: function (type, hash) {
169
- var revision = this._revision(type);
170
- if (hash.hasOwnProperty(revision) && hash[revision] !== null) {
171
- return parseInt(hash[revision]);
172
- } else {
173
- return undefined;
174
- }
175
- },
176
- extractClientRevision: function (type, hash) {
177
- var revision = this._clientRevision(type);
178
- if (hash.hasOwnProperty(revision) && hash[revision] !== null) {
179
- return parseInt(hash[revision]);
180
- } else {
181
- return undefined;
182
- }
183
- },
184
- extractHasMany: function (type, hash, key) {
185
- return hash[key];
186
- },
187
- extractBelongsTo: function (type, hash, key) {
188
- return hash[key];
189
- },
190
- extractBelongsToPolymorphic: function (type, hash, key) {
191
- var keyForId = this.keyForPolymorphicId(key), keyForType, id = hash[keyForId];
192
- if (id) {
193
- keyForType = this.keyForPolymorphicType(key);
194
- return {
195
- id: id,
196
- type: hash[keyForType]
197
- };
198
- }
199
- return null;
200
- },
201
- addBelongsTo: function (hash, record, key, relationship) {
202
- var type = record.constructor, name = relationship.key, value = null, includeType = relationship.options && relationship.options.polymorphic, embeddedChild, child, id;
203
- if (this.embeddedType(type, name)) {
204
- if (embeddedChild = get(record, name)) {
205
- value = this.serialize(embeddedChild, {
206
- includeId: true,
207
- includeType: includeType
208
- });
209
- }
210
- hash[key] = value;
211
- } else {
212
- child = get(record, relationship.key);
213
- id = get(child, 'id');
214
- if (relationship.options && relationship.options.polymorphic && !Ember.isNone(id)) {
215
- type = get(child, 'type');
216
- this.addBelongsToPolymorphic(hash, key, id, type);
217
- } else {
218
- hash[key] = id === undefined ? null : this.serializeId(id);
219
- }
220
- }
221
- },
222
- addBelongsToPolymorphic: function (hash, key, id, type) {
223
- var keyForId = this.keyForPolymorphicId(key), keyForType = this.keyForPolymorphicType(key);
224
- hash[keyForId] = id;
225
- hash[keyForType] = this.rootForType(type);
226
- },
227
- addHasMany: function (hash, record, key, relationship) {
228
- var type = record.constructor, name = relationship.key, serializedHasMany = [], includeType = relationship.options && relationship.options.polymorphic, manyArray, embeddedType;
229
- embeddedType = this.embeddedType(type, name);
230
- if (embeddedType !== 'always') {
231
- return;
232
- }
233
- manyArray = get(record, name);
234
- manyArray.forEach(function (record) {
235
- serializedHasMany.push(this.serialize(record, {
236
- includeId: true,
237
- includeType: includeType
238
- }));
239
- }, this);
240
- hash[key] = serializedHasMany;
241
- },
242
- addType: function (hash, type) {
243
- var keyForType = this.keyForEmbeddedType();
244
- hash[keyForType] = this.rootForType(type);
245
- },
246
- deserialize: function (data) {
247
- var result = [];
248
- for (var prop in data) {
249
- if (!data.hasOwnProperty(prop) || !!this.metadataMapping.get(prop)) {
250
- continue;
251
- }
252
- var type = this.typeFromAlias(prop);
253
- Ember.assert('Your server returned a hash with the key ' + prop + ' but you have no mapping for it', !!type);
254
- var value = data[prop];
255
- if (value instanceof Array) {
256
- for (var i = 0; i < value.length; i++) {
257
- result.push(this.deserializeModel(type, value[i]));
258
- }
259
- } else {
260
- result.push(this.deserializeModel(type, value));
261
- }
262
- }
263
- return result;
264
- },
265
- extractMeta: function (type, json) {
266
- var meta = this.configOption(type, 'meta'), data = json, value;
267
- if (meta && json[meta]) {
268
- data = json[meta];
269
- }
270
- var result = {};
271
- this.metadataMapping.forEach(function (property, key) {
272
- if (value = data[property]) {
273
- result[key] = value;
274
- }
275
- });
276
- return result;
277
- },
278
- extractEmbeddedType: function (relationship, data) {
279
- var foundType = relationship.type;
280
- if (relationship.options && relationship.options.polymorphic) {
281
- var key = this.keyFor(relationship), keyForEmbeddedType = this.keyForEmbeddedType(key);
282
- foundType = this.typeFromAlias(data[keyForEmbeddedType]);
283
- delete data[keyForEmbeddedType];
284
- }
285
- return foundType;
286
- },
287
- configureSideloadMappingForType: function (type, configured) {
288
- if (!configured) {
289
- configured = Ember.A([]);
290
- }
291
- configured.pushObject(type);
292
- type.eachRelatedType(function (relatedType) {
293
- if (!configured.contains(relatedType)) {
294
- var root = this.defaultSideloadRootForType(relatedType);
295
- this.aliases.set(root, relatedType);
296
- this.configureSideloadMappingForType(relatedType, configured);
297
- }
298
- }, this);
299
- },
300
- keyForPolymorphicId: Ember.K,
301
- keyForPolymorphicType: Ember.K,
302
- keyForEmbeddedType: function () {
303
- return 'type';
304
- },
305
- rootForType: function (type) {
306
- var typeString = type.toString();
307
- Ember.assert('Your model must not be anonymous. It was ' + type, typeString.charAt(0) !== '(');
308
- var parts = typeString.split('.');
309
- var name = parts[parts.length - 1];
310
- return name.replace(/([A-Z])/g, '_$1').toLowerCase().slice(1);
311
- },
312
- defaultSideloadRootForType: function (type) {
313
- return this.pluralize(this.rootForType(type));
314
- }
315
- });
316
- });
317
- require.define('/lib/transforms/json_transforms.js', function (module, exports, __dirname, __filename) {
318
- var none = Ember.isNone, empty = Ember.isEmpty;
319
- require('/lib/ext/date.js', module);
320
- Ep.JsonTransforms = {
321
- string: {
322
- deserialize: function (serialized) {
323
- return none(serialized) ? null : String(serialized);
324
- },
325
- serialize: function (deserialized) {
326
- return none(deserialized) ? null : String(deserialized);
327
- }
328
- },
329
- number: {
330
- deserialize: function (serialized) {
331
- return empty(serialized) ? null : Number(serialized);
332
- },
333
- serialize: function (deserialized) {
334
- return empty(deserialized) ? null : Number(deserialized);
335
- }
336
- },
337
- 'boolean': {
338
- deserialize: function (serialized) {
339
- var type = typeof serialized;
340
- if (type === 'boolean') {
341
- return serialized;
342
- } else if (type === 'string') {
343
- return serialized.match(/^true$|^t$|^1$/i) !== null;
344
- } else if (type === 'number') {
345
- return serialized === 1;
346
- } else {
347
- return false;
348
- }
349
- },
350
- serialize: function (deserialized) {
351
- return Boolean(deserialized);
352
- }
353
- },
354
- date: {
355
- deserialize: function (serialized) {
356
- var type = typeof serialized;
357
- if (type === 'string') {
358
- return new Date(Ember.Date.parse(serialized));
359
- } else if (type === 'number') {
360
- return new Date(serialized);
361
- } else if (serialized === null || serialized === undefined) {
362
- return serialized;
363
- } else {
364
- return null;
365
- }
366
- },
367
- serialize: function (date) {
368
- if (date instanceof Date) {
369
- var days = [
370
- 'Sun',
371
- 'Mon',
372
- 'Tue',
373
- 'Wed',
374
- 'Thu',
375
- 'Fri',
376
- 'Sat'
377
- ];
378
- var months = [
379
- 'Jan',
380
- 'Feb',
381
- 'Mar',
382
- 'Apr',
383
- 'May',
384
- 'Jun',
385
- 'Jul',
386
- 'Aug',
387
- 'Sep',
388
- 'Oct',
389
- 'Nov',
390
- 'Dec'
391
- ];
392
- var pad = function (num) {
393
- return num < 10 ? '0' + num : '' + num;
394
- };
395
- var utcYear = date.getUTCFullYear(), utcMonth = date.getUTCMonth(), utcDayOfMonth = date.getUTCDate(), utcDay = date.getUTCDay(), utcHours = date.getUTCHours(), utcMinutes = date.getUTCMinutes(), utcSeconds = date.getUTCSeconds();
396
- var dayOfWeek = days[utcDay];
397
- var dayOfMonth = pad(utcDayOfMonth);
398
- var month = months[utcMonth];
399
- return dayOfWeek + ', ' + dayOfMonth + ' ' + month + ' ' + utcYear + ' ' + pad(utcHours) + ':' + pad(utcMinutes) + ':' + pad(utcSeconds) + ' GMT';
400
- } else {
401
- return null;
402
- }
403
- }
404
- }
405
- };
127
+ require('/lib/serializer/json_serializer/index.js', module);
406
128
  });
407
- require.define('/lib/ext/date.js', function (module, exports, __dirname, __filename) {
408
- Ember.Date = Ember.Date || {};
409
- var origParse = Date.parse, numericKeys = [
410
- 1,
411
- 4,
412
- 5,
413
- 6,
414
- 7,
415
- 10,
416
- 11
417
- ];
418
- Ember.Date.parse = function (date) {
419
- var timestamp, struct, minutesOffset = 0;
420
- 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)) {
421
- for (var i = 0, k; k = numericKeys[i]; ++i) {
422
- struct[k] = +struct[k] || 0;
423
- }
424
- struct[2] = (+struct[2] || 1) - 1;
425
- struct[3] = +struct[3] || 1;
426
- if (struct[8] !== 'Z' && struct[9] !== undefined) {
427
- minutesOffset = struct[10] * 60 + struct[11];
428
- if (struct[9] === '+') {
429
- minutesOffset = 0 - minutesOffset;
430
- }
431
- }
432
- timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
433
- } else {
434
- timestamp = origParse ? origParse(date) : NaN;
435
- }
436
- return timestamp;
437
- };
438
- if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Date) {
439
- Date.parse = Ember.Date.parse;
440
- }
129
+ require.define('/lib/serializer/json_serializer/index.js', function (module, exports, __dirname, __filename) {
130
+ require('/lib/serializer/json_serializer/embedded_helpers_mixin.js', module);
131
+ require('/lib/serializer/json_serializer/json_serializer.js', module);
132
+ require('/lib/serializer/json_serializer/serialize.js', module);
133
+ require('/lib/serializer/json_serializer/deserialize.js', module);
441
134
  });
442
- require.define('/lib/serializer/serializer.js', function (module, exports, __dirname, __filename) {
443
- require('/lib/model/index.js', module);
444
- var get = Ember.get, set = Ember.set, map = Ember.ArrayPolyfills.map, isNone = Ember.isNone;
445
- function mustImplement(name) {
446
- return function () {
447
- throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
135
+ require.define('/lib/serializer/json_serializer/deserialize.js', function (module, exports, __dirname, __filename) {
136
+ var get = Ember.get, set = Ember.set;
137
+ function extractPropertyHook(name) {
138
+ return function (type, hash) {
139
+ return this.extractProperty(type, hash, name);
448
140
  };
449
141
  }
450
- Ep.Serializer = Ember.Object.extend({
451
- init: function () {
452
- this.mappings = Ember.Map.create();
453
- this.aliases = Ember.Map.create();
454
- this.configurations = Ember.Map.create();
455
- this.globalConfigurations = {};
456
- },
457
- deserialize: mustImplement('deserialize'),
458
- extractId: mustImplement('extractId'),
459
- extractClientId: mustImplement('extractClientId'),
460
- extractRevision: mustImplement('extractRevision'),
461
- extractClientRevision: mustImplement('extractClientRevision'),
462
- extractAttribute: mustImplement('extractAttribute'),
463
- extractHasMany: mustImplement('extractHasMany'),
464
- extractBelongsTo: mustImplement('extractBelongsTo'),
465
- deserializeModel: function (type, hash) {
142
+ Ep.JsonSerializer.reopen({
143
+ deserialize: function (type, hash) {
466
144
  var model = this.createModel(type);
467
145
  set(model, 'id', this.extractId(type, hash));
468
146
  set(model, 'clientId', this.extractClientId(type, hash));
@@ -475,19 +153,34 @@
475
153
  createModel: function (type) {
476
154
  return type.create();
477
155
  },
478
- deserializeValue: function (value, attributeType) {
479
- var transform = this.transforms ? this.transforms[attributeType] : null;
480
- Ember.assert('You tried to use a attribute type (' + attributeType + ') that has not been registered', transform);
481
- return transform.deserialize(value);
156
+ extractProperty: function (type, hash, name) {
157
+ var key = this.keyFor(name, type);
158
+ return hash[key];
159
+ },
160
+ extractId: function (type, hash) {
161
+ var key = this.keyFor('id', type);
162
+ if (hash.hasOwnProperty(key)) {
163
+ return hash[key] + '';
164
+ } else {
165
+ return null;
166
+ }
482
167
  },
483
- deserializeAttributes: function (model, data) {
168
+ extractClientId: extractPropertyHook('clientId'),
169
+ extractRevision: extractPropertyHook('rev'),
170
+ extractClientRevision: extractPropertyHook('clientRev'),
171
+ deserializeAttributes: function (model, hash) {
484
172
  model.eachAttribute(function (name, attribute) {
485
- set(model, name, this.deserializeAttribute(model, data, name, attribute.type));
173
+ set(model, name, this.extractAttribute(model, hash, name, attribute));
486
174
  }, this);
487
175
  },
488
- deserializeAttribute: function (record, data, attributeName, attributeType) {
489
- var value = this.extractAttribute(record.constructor, data, attributeName);
490
- return this.deserializeValue(value, attributeType);
176
+ extractAttribute: function (model, hash, name, attribute) {
177
+ var key = this.keyFor(name, get(model, 'type'));
178
+ return this.deserializeValue(hash[key], attribute.type);
179
+ },
180
+ deserializeValue: function (value, attributeType) {
181
+ var transform = this.transformFor(attributeType);
182
+ Ember.assert('You tried to use a attribute type (' + attributeType + ') that has not been registered', transform);
183
+ return transform.deserialize(value);
491
184
  },
492
185
  deserializeRelationships: function (model, hash) {
493
186
  model.eachRelationship(function (name, relationship) {
@@ -499,7 +192,7 @@
499
192
  }, this);
500
193
  },
501
194
  deserializeHasMany: function (name, model, data, relationship) {
502
- var type = get(model, 'type'), key = this._keyForHasMany(type, relationship.key), embeddedType = this.embeddedType(type, name), value = this.extractHasMany(type, data, key);
195
+ var type = get(model, 'type'), key = this.keyForHasMany(name, type), embeddedType = this.embeddedType(type, name), value = this.extractHasMany(type, data, key);
503
196
  if (embeddedType) {
504
197
  this.deserializeEmbeddedHasMany(name, model, value, relationship);
505
198
  } else {
@@ -507,16 +200,19 @@
507
200
  }
508
201
  },
509
202
  deserializeEmbeddedHasMany: function (name, model, values, relationship) {
510
- get(model, name).addObjects(values.map(function (data) {
203
+ if (!values) {
204
+ return;
205
+ }
206
+ get(model, name).pushObjects(values.map(function (data) {
511
207
  var type = this.extractEmbeddedType(relationship, data);
512
- return this.deserializeModel(type, data);
208
+ return this.deserialize(type, data);
513
209
  }, this));
514
210
  },
515
211
  deserializeLazyHasMany: function (name, model, values, relationship) {
516
212
  if (!values) {
517
213
  return;
518
214
  }
519
- get(model, name).addObjects(values.map(function (value) {
215
+ get(model, name).pushObjects(values.map(function (value) {
520
216
  return Ep.LazyModel.create({
521
217
  id: value && value.toString(),
522
218
  type: relationship.type
@@ -524,7 +220,7 @@
524
220
  }, this));
525
221
  },
526
222
  deserializeBelongsTo: function (name, model, hash, relationship) {
527
- var type = get(model, 'type'), key = this._keyForBelongsTo(type, relationship.key), embeddedType = this.embeddedType(type, name), value;
223
+ var type = get(model, 'type'), key = this.keyForBelongsTo(name, type), embeddedType = this.embeddedType(type, name), value;
528
224
  if (embeddedType) {
529
225
  if (relationship.options && relationship.options.polymorphic) {
530
226
  value = this.extractBelongsToPolymorphic(type, hash, key);
@@ -542,7 +238,7 @@
542
238
  return;
543
239
  }
544
240
  var type = this.extractEmbeddedType(relationship, value);
545
- var child = this.deserializeModel(type, value);
241
+ var child = this.deserialize(type, value);
546
242
  set(model, name, child);
547
243
  },
548
244
  deserializeLazyBelongsTo: function (name, model, value, relationship) {
@@ -555,67 +251,52 @@
555
251
  }));
556
252
  },
557
253
  extractEmbeddedType: function (relationship, data) {
558
- return relationship.type;
559
- },
560
- _convertPrematerializedHasMany: function (type, prematerializedHasMany) {
561
- var tuplesOrReferencesOrOpaque;
562
- if (typeof prematerializedHasMany === 'string') {
563
- tuplesOrReferencesOrOpaque = prematerializedHasMany;
564
- } else {
565
- tuplesOrReferencesOrOpaque = this._convertTuples(type, prematerializedHasMany);
254
+ var foundType = relationship.type;
255
+ if (relationship.options && relationship.options.polymorphic) {
256
+ var key = this.keyForRelationship(relationship), keyForEmbeddedType = this.keyForEmbeddedType(key);
257
+ foundType = this.typeFromAlias(data[keyForEmbeddedType]);
258
+ delete data[keyForEmbeddedType];
566
259
  }
567
- return tuplesOrReferencesOrOpaque;
568
- },
569
- _convertTuples: function (type, idsOrTuples) {
570
- return map.call(idsOrTuples, function (idOrTuple) {
571
- return this._convertTuple(type, idOrTuple);
572
- }, this);
260
+ return foundType;
573
261
  },
574
- _convertTuple: function (type, idOrTuple) {
575
- var foundType;
576
- if (typeof idOrTuple === 'object') {
577
- if (Ep.Model.detect(idOrTuple.type)) {
578
- return idOrTuple;
579
- } else {
580
- foundType = this.typeFromAlias(idOrTuple.type);
581
- Ember.assert('Unable to resolve type ' + idOrTuple.type + '. You may need to configure your serializer aliases.', !!foundType);
582
- return {
583
- id: idOrTuple.id,
584
- type: foundType
585
- };
586
- }
262
+ extractHasMany: Ember.aliasMethod('extractProperty'),
263
+ extractBelongsTo: Ember.aliasMethod('extractProperty')
264
+ });
265
+ });
266
+ require.define('/lib/serializer/json_serializer/serialize.js', function (module, exports, __dirname, __filename) {
267
+ var get = Ember.get, set = Ember.set;
268
+ function addPropertyHook(name) {
269
+ return function (serialized, model) {
270
+ return this.addProperty(serialized, name, model);
271
+ };
272
+ }
273
+ Ep.JsonSerializer.reopen({
274
+ serialize: function (model, options) {
275
+ var serialized = {}, id, rev, clientRev;
276
+ if (id = get(model, 'id')) {
277
+ this.addId(serialized, model);
587
278
  }
588
- return {
589
- id: idOrTuple,
590
- type: type
591
- };
592
- },
593
- serialize: function (record, options) {
594
- options = options || {};
595
- var serialized = this.createSerializedForm(), id, rev, clientRev;
596
- if (options.includeId) {
597
- if (id = get(record, 'id')) {
598
- this._addId(serialized, record.constructor, id);
599
- }
600
- this._addClientId(serialized, record.constructor, get(record, 'clientId'));
601
- if (rev = get(record, 'rev')) {
602
- this._addRevision(serialized, record.constructor, get(record, 'rev'));
603
- }
604
- if (clientRev = get(record, 'clientRev')) {
605
- this._addClientRevision(serialized, record.constructor, get(record, 'clientRev'));
606
- }
279
+ this.addClientId(serialized, model);
280
+ if (rev = get(model, 'rev')) {
281
+ this.addRevision(serialized, model);
282
+ }
283
+ if (clientRev = get(model, 'clientRev')) {
284
+ this.addClientRevision(serialized, model);
607
285
  }
608
- if (options.includeType) {
609
- this.addType(serialized, record.constructor);
286
+ if (options && options.includeType) {
287
+ this.addType(serialized, model);
610
288
  }
611
- this.addAttributes(serialized, record);
612
- this.addRelationships(serialized, record);
289
+ this.addAttributes(serialized, model);
290
+ this.addRelationships(serialized, model);
613
291
  return serialized;
614
292
  },
615
- serializeValue: function (value, attributeType) {
616
- var transform = this.transforms ? this.transforms[attributeType] : null;
617
- Ember.assert('You tried to use an attribute type (' + attributeType + ') that has not been registered', transform);
618
- return transform.serialize(value);
293
+ addProperty: function (serialized, name, model) {
294
+ var key = this.keyFor(name);
295
+ serialized[key] = get(model, name);
296
+ },
297
+ addId: function (serialized, model) {
298
+ var key = this.keyFor('id');
299
+ serialized[key] = this.serializeId(get(model, 'id'));
619
300
  },
620
301
  serializeId: function (id) {
621
302
  if (isNaN(id)) {
@@ -623,337 +304,175 @@
623
304
  }
624
305
  return +id;
625
306
  },
626
- serializeClientId: function (clientId) {
627
- return clientId;
628
- },
629
- serializeRevision: function (rev) {
630
- return rev;
631
- },
632
- serializeClientRevision: function (rev) {
633
- return rev;
634
- },
635
- addAttributes: function (data, record) {
636
- record.eachAttribute(function (name, attribute) {
637
- this._addAttribute(data, record, name, attribute.type);
307
+ addClientId: addPropertyHook('clientId'),
308
+ addRevision: addPropertyHook('rev'),
309
+ addClientRevision: addPropertyHook('clientRev'),
310
+ addType: addPropertyHook('type'),
311
+ addAttributes: function (serialized, model) {
312
+ model.eachAttribute(function (name, attribute) {
313
+ this.addAttribute(serialized, name, model, attribute);
638
314
  }, this);
639
315
  },
640
- addAttribute: mustImplement('addAttribute'),
641
- addId: mustImplement('addId'),
642
- addType: Ember.K,
643
- createSerializedForm: function () {
644
- return {};
316
+ addAttribute: function (serialized, name, model, attribute) {
317
+ var key = this.keyFor(name);
318
+ serialized[key] = this.serializeValue(get(model, name), attribute.type);
319
+ },
320
+ serializeValue: function (value, attributeType) {
321
+ var transform = this.transformFor(attributeType);
322
+ Ember.assert('You tried to use an attribute type (' + attributeType + ') that has not been registered', transform);
323
+ return transform.serialize(value);
645
324
  },
646
- addRelationships: function (data, record) {
647
- record.eachRelationship(function (name, relationship) {
325
+ addRelationships: function (serialized, model) {
326
+ model.eachRelationship(function (name, relationship) {
648
327
  if (relationship.kind === 'belongsTo') {
649
- this._addBelongsTo(data, record, name, relationship);
328
+ this.addBelongsTo(serialized, model, name, relationship);
650
329
  } else if (relationship.kind === 'hasMany') {
651
- this._addHasMany(data, record, name, relationship);
330
+ this.addHasMany(serialized, model, name, relationship);
652
331
  }
653
332
  }, this);
654
333
  },
655
- addBelongsTo: mustImplement('addBelongsTo'),
656
- addHasMany: mustImplement('addHasMany'),
657
- keyForAttributeName: function (type, name) {
658
- return name;
659
- },
660
- primaryKey: function (type) {
661
- return 'id';
662
- },
663
- clientKey: function (type) {
664
- return 'client_id';
665
- },
666
- revision: function (type) {
667
- return 'rev';
668
- },
669
- clientRevision: function (type) {
670
- return 'client_rev';
671
- },
672
- keyForBelongsTo: function (type, name) {
673
- return this.keyForAttributeName(type, name);
674
- },
675
- keyForHasMany: function (type, name) {
676
- return this.keyForAttributeName(type, name);
677
- },
678
- _primaryKey: function (type) {
679
- var config = this.configurationForType(type), primaryKey = config && config.primaryKey;
680
- if (primaryKey) {
681
- return primaryKey;
682
- } else {
683
- return this.primaryKey(type);
684
- }
685
- },
686
- _clientKey: function (type) {
687
- var config = this.configurationForType(type), clientKey = config && config.clientKey;
688
- if (clientKey) {
689
- return clientKey;
690
- } else {
691
- return this.clientKey(type);
692
- }
693
- },
694
- _revision: function (type) {
695
- var config = this.configurationForType(type), revision = config && config.revision;
696
- if (revision) {
697
- return revision;
698
- } else {
699
- return this.revision(type);
700
- }
701
- },
702
- _clientRevision: function (type) {
703
- var config = this.configurationForType(type), clientRevision = config && config.clientRevision;
704
- if (clientRevision) {
705
- return clientRevision;
706
- } else {
707
- return this.clientRevision(type);
708
- }
709
- },
710
- _addAttribute: function (data, record, attributeName, attributeType) {
711
- var key = this._keyForAttributeName(record.constructor, attributeName);
712
- var value = get(record, attributeName);
713
- this.addAttribute(data, key, this.serializeValue(value, attributeType));
714
- },
715
- _addId: function (hash, type, id) {
716
- var primaryKey = this._primaryKey(type);
717
- this.addId(hash, primaryKey, this.serializeId(id));
718
- },
719
- _addClientId: function (hash, type, id) {
720
- var clientKey = this._clientKey(type);
721
- this.addId(hash, clientKey, this.serializeClientId(id));
722
- },
723
- _addRevision: function (hash, type, rev) {
724
- var revision = this._revision(type);
725
- this.addId(hash, revision, this.serializeRevision(rev));
726
- },
727
- _addClientRevision: function (hash, type, rev) {
728
- var revision = this._clientRevision(type);
729
- this.addId(hash, revision, this.serializeClientRevision(rev));
730
- },
731
- _keyForAttributeName: function (type, name) {
732
- return this._keyFromMappingOrHook('keyForAttributeName', type, name);
733
- },
734
- _keyForBelongsTo: function (type, name) {
735
- return this._keyFromMappingOrHook('keyForBelongsTo', type, name);
736
- },
737
- keyFor: function (description) {
738
- var type = description.parentType, name = description.key;
739
- switch (description.kind) {
740
- case 'belongsTo':
741
- return this._keyForBelongsTo(type, name);
742
- case 'hasMany':
743
- return this._keyForHasMany(type, name);
744
- }
745
- },
746
- _keyForHasMany: function (type, name) {
747
- return this._keyFromMappingOrHook('keyForHasMany', type, name);
748
- },
749
- _addBelongsTo: function (data, record, name, relationship) {
750
- var key = this._keyForBelongsTo(record.constructor, name);
751
- this.addBelongsTo(data, record, key, relationship);
752
- },
753
- _addHasMany: function (data, record, name, relationship) {
754
- var key = this._keyForHasMany(record.constructor, name);
755
- this.addHasMany(data, record, key, relationship);
756
- },
757
- _keyFromMappingOrHook: function (publicMethod, type, name) {
758
- var key = this.mappingOption(type, name, 'key');
759
- if (key) {
760
- return key;
334
+ addBelongsTo: function (serialized, model, name, relationship) {
335
+ var type = get(model, 'type'), key = this.keyForBelongsTo(name, type), value = null, includeType = relationship.options && relationship.options.polymorphic, embeddedChild, child, id;
336
+ if (this.embeddedType(type, name)) {
337
+ if (embeddedChild = get(model, name)) {
338
+ value = this.serialize(embeddedChild, { includeType: includeType });
339
+ }
340
+ serialized[key] = value;
761
341
  } else {
762
- return this[publicMethod](type, name);
342
+ child = get(model, relationship.key);
343
+ id = get(child, 'id');
344
+ if (relationship.options && relationship.options.polymorphic && !Ember.isNone(id)) {
345
+ throw 'Polymorphism is not quite ready';
346
+ } else {
347
+ serialized[key] = id === undefined ? null : this.serializeId(id);
348
+ }
763
349
  }
764
350
  },
765
- registerTransform: function (type, transform) {
766
- this.transforms[type] = transform;
767
- },
768
- registerEnumTransform: function (type, objects) {
769
- var transform = {
770
- deserialize: function (serialized) {
771
- return Ember.A(objects).objectAt(serialized);
772
- },
773
- serialize: function (deserialized) {
774
- return Ember.EnumerableUtils.indexOf(objects, deserialized);
775
- },
776
- values: objects
777
- };
778
- this.registerTransform(type, transform);
351
+ addBelongsToPolymorphic: function (hash, key, id, type) {
352
+ var keyForId = this.keyForPolymorphicId(key), keyForType = this.keyForPolymorphicType(key);
353
+ hash[keyForId] = id;
354
+ hash[keyForType] = this.rootForType(type);
779
355
  },
780
- map: function (type, mappings) {
781
- this.mappings.set(type, mappings);
356
+ rootForType: function (type) {
357
+ return get(type, 'typeKey');
782
358
  },
783
- configure: function (type, configuration) {
784
- if (type && !configuration) {
785
- Ember.merge(this.globalConfigurations, type);
359
+ addHasMany: function (serialized, model, name, relationship) {
360
+ var type = get(model, 'type'), key = this.keyForHasMany(name, type), serializedHasMany = [], includeType = relationship.options && relationship.options.polymorphic, manyArray, embeddedType;
361
+ embeddedType = this.embeddedType(type, name);
362
+ if (embeddedType !== 'always') {
786
363
  return;
787
364
  }
788
- var config, alias;
789
- if (configuration.alias) {
790
- alias = configuration.alias;
791
- this.aliases.set(alias, type);
792
- delete configuration.alias;
793
- }
794
- config = Ember.create(this.globalConfigurations);
795
- Ember.merge(config, configuration);
796
- this.configurations.set(type, config);
797
- },
798
- typeFromAlias: function (alias) {
799
- this._completeAliases();
800
- var singular = this.singularize(alias);
801
- return this.container.lookup('model:' + singular);
802
- },
803
- mappingForType: function (type) {
804
- this._reifyMappings();
805
- return this.mappings.get(type) || {};
806
- },
807
- configurationForType: function (type) {
808
- this._reifyConfigurations();
809
- return this.configurations.get(type) || this.globalConfigurations;
810
- },
811
- _completeAliases: function () {
812
- this._pluralizeAliases();
813
- this._reifyAliases();
365
+ manyArray = get(model, name);
366
+ manyArray.forEach(function (model) {
367
+ serializedHasMany.push(this.serialize(model, { includeType: includeType }));
368
+ }, this);
369
+ serialized[key] = serializedHasMany;
370
+ }
371
+ });
372
+ });
373
+ require.define('/lib/serializer/json_serializer/json_serializer.js', function (module, exports, __dirname, __filename) {
374
+ require('/lib/serializer/serializer.js', module);
375
+ var get = Ember.get, set = Ember.set;
376
+ Ep.JsonSerializer = Ep.Serializer.extend(Ep.EmbeddedHelpersMixin, {
377
+ mergedProperties: [
378
+ 'properties',
379
+ 'aliases'
380
+ ],
381
+ properties: {},
382
+ aliases: {},
383
+ _keyCache: null,
384
+ _nameCache: null,
385
+ init: function () {
386
+ this._super();
387
+ this._keyCache = {};
388
+ this._nameCache = {};
814
389
  },
815
- _pluralizeAliases: function () {
816
- if (this._didPluralizeAliases) {
817
- return;
390
+ nameFor: function (key) {
391
+ var name;
392
+ if (name = this._nameCache[key]) {
393
+ return name;
818
394
  }
819
- var aliases = this.aliases, sideloadMapping = this.aliases.sideloadMapping, plural, self = this;
820
- aliases.forEach(function (key, type) {
821
- plural = self.pluralize(key);
822
- Ember.assert('The \'' + key + '\' alias has already been defined', !aliases.get(plural));
823
- aliases.set(plural, type);
824
- });
825
- if (sideloadMapping) {
826
- sideloadMapping.forEach(function (key, type) {
827
- Ember.assert('The \'' + key + '\' alias has already been defined', !aliases.get(key) || aliases.get(key) === type);
828
- aliases.set(key, type);
829
- });
830
- delete this.aliases.sideloadMapping;
395
+ var configs = get(this, 'properties');
396
+ for (var currentName in configs) {
397
+ var current = configs[name];
398
+ var keyName = current.key;
399
+ if (keyName && key === keyName) {
400
+ name = currentName;
401
+ }
831
402
  }
832
- this._didPluralizeAliases = true;
403
+ name = name || Ember.String.camelize(key);
404
+ this._nameCache[key] = name;
405
+ return name;
833
406
  },
834
- _reifyAliases: function () {
835
- if (this._didReifyAliases) {
836
- return;
837
- }
838
- var aliases = this.aliases, reifiedAliases = Ember.Map.create(), foundType;
839
- aliases.forEach(function (key, type) {
840
- if (typeof type === 'string') {
841
- foundType = Ember.get(Ember.lookup, type);
842
- Ember.assert('Could not find model at path ' + key, type);
843
- reifiedAliases.set(key, foundType);
844
- } else {
845
- reifiedAliases.set(key, type);
846
- }
847
- });
848
- this.aliases = reifiedAliases;
849
- this._didReifyAliases = true;
407
+ configFor: function (name) {
408
+ return this.properties[name] || {};
850
409
  },
851
- _reifyMappings: function () {
852
- if (this._didReifyMappings) {
853
- return;
410
+ keyFor: function (name, type) {
411
+ var key;
412
+ if (key = this._keyCache[name]) {
413
+ return key;
854
414
  }
855
- var mappings = this.mappings, reifiedMappings = Ember.Map.create();
856
- mappings.forEach(function (key, mapping) {
857
- if (typeof key === 'string') {
858
- var type = Ember.get(Ember.lookup, key);
859
- Ember.assert('Could not find model at path ' + key, type);
860
- reifiedMappings.set(type, mapping);
861
- } else {
862
- reifiedMappings.set(key, mapping);
863
- }
864
- });
865
- this.mappings = reifiedMappings;
866
- this._didReifyMappings = true;
415
+ var config = this.configFor(name);
416
+ key = config.key || Ember.String.underscore(name);
417
+ this._keyCache[name] = key;
418
+ return key;
867
419
  },
868
- _reifyConfigurations: function () {
869
- if (this._didReifyConfigurations) {
870
- return;
420
+ keyForBelongsTo: Ember.aliasMethod('keyFor'),
421
+ keyForHasMany: Ember.aliasMethod('keyFor'),
422
+ keyForRelationship: function (relationship) {
423
+ var type = relationship.parentType, name = relationship.key;
424
+ switch (description.kind) {
425
+ case 'belongsTo':
426
+ return this.keyForBelongsTo(name, type);
427
+ case 'hasMany':
428
+ return this.keyForHasMany(name, type);
871
429
  }
872
- var configurations = this.configurations, reifiedConfigurations = Ember.Map.create();
873
- configurations.forEach(function (key, mapping) {
874
- if (typeof key === 'string' && key !== 'plurals') {
875
- var type = Ember.get(Ember.lookup, key);
876
- Ember.assert('Could not find model at path ' + key, type);
877
- reifiedConfigurations.set(type, mapping);
878
- } else {
879
- reifiedConfigurations.set(key, mapping);
880
- }
881
- });
882
- this.configurations = reifiedConfigurations;
883
- this._didReifyConfigurations = true;
884
- },
885
- mappingOption: function (type, name, option) {
886
- var mapping = this.mappingForType(type)[name];
887
- return mapping && mapping[option];
888
- },
889
- configOption: function (type, option) {
890
- var config = this.configurationForType(type);
891
- return config[option];
892
- },
893
- embeddedType: function (type, name) {
894
- return this.mappingOption(type, name, 'embedded');
895
- },
896
- eachEmbeddedRecord: function (record, callback, binding) {
897
- this.eachEmbeddedBelongsToRecord(record, callback, binding);
898
- this.eachEmbeddedHasManyRecord(record, callback, binding);
899
- },
900
- eachEmbeddedBelongsToRecord: function (record, callback, binding) {
901
- this.eachEmbeddedBelongsTo(record.constructor, function (name, relationship, embeddedType) {
902
- var embeddedRecord = get(record, name);
903
- if (embeddedRecord) {
904
- callback.call(binding, embeddedRecord, embeddedType);
905
- }
906
- });
907
- },
908
- eachEmbeddedHasManyRecord: function (record, callback, binding) {
909
- this.eachEmbeddedHasMany(record.constructor, function (name, relationship, embeddedType) {
910
- var array = get(record, name);
911
- for (var i = 0, l = get(array, 'length'); i < l; i++) {
912
- callback.call(binding, array.objectAt(i), embeddedType);
913
- }
914
- });
915
- },
916
- eachEmbeddedHasMany: function (type, callback, binding) {
917
- this.eachEmbeddedRelationship(type, 'hasMany', callback, binding);
918
430
  },
919
- eachEmbeddedBelongsTo: function (type, callback, binding) {
920
- this.eachEmbeddedRelationship(type, 'belongsTo', callback, binding);
431
+ keyForEmbeddedType: function () {
432
+ return 'type';
921
433
  },
922
- eachEmbeddedRelationship: function (type, kind, callback, binding) {
923
- type.eachRelationship(function (name, relationship) {
924
- var embeddedType = this.embeddedType(type, name);
925
- if (embeddedType) {
926
- if (relationship.kind === kind) {
927
- callback.call(binding, name, relationship, embeddedType);
928
- }
929
- }
930
- }, this);
434
+ transformFor: function (attributeType) {
435
+ return this.container.lookup('transform:' + attributeType);
931
436
  },
932
437
  pluralize: function (name) {
933
- var plurals = this.configurations.get('plurals');
934
- return plurals && plurals[name] || name + 's';
438
+ return Ember.String.pluralize(name);
935
439
  },
936
440
  singularize: function (name) {
937
- var plurals = this.configurations.get('plurals');
938
- if (plurals) {
939
- for (var i in plurals) {
940
- if (plurals[i] === name) {
941
- return i;
942
- }
943
- }
441
+ return Ember.String.singularize(name);
442
+ },
443
+ typeFor: function (name) {
444
+ var type;
445
+ if (type = this.container.lookup('model:' + name)) {
446
+ return type;
944
447
  }
945
- if (name.lastIndexOf('s') === name.length - 1) {
946
- return name.substring(0, name.length - 1);
947
- } else {
948
- return name;
448
+ var singular = this.singularize(name);
449
+ if (type = this.container.lookup('model:' + singular)) {
450
+ return type;
949
451
  }
452
+ var aliases = get(this, 'aliases');
453
+ var alias = aliases[name];
454
+ return alias && this.container.lookup('model:' + alias);
950
455
  }
951
456
  });
952
457
  });
458
+ require.define('/lib/serializer/serializer.js', function (module, exports, __dirname, __filename) {
459
+ require('/lib/model/index.js', module);
460
+ var get = Ember.get, set = Ember.set, map = Ember.ArrayPolyfills.map, isNone = Ember.isNone;
461
+ function mustImplement(name) {
462
+ return function () {
463
+ throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
464
+ };
465
+ }
466
+ Ep.Serializer = Ember.Object.extend({
467
+ deserialize: mustImplement('deserialize'),
468
+ serialize: mustImplement('serialize')
469
+ });
470
+ });
953
471
  require.define('/lib/model/index.js', function (module, exports, __dirname, __filename) {
954
472
  require('/lib/model/model.js', module);
955
473
  require('/lib/model/proxies.js', module);
956
474
  require('/lib/model/attribute.js', module);
475
+ require('/lib/model/debug.js', module);
957
476
  require('/lib/model/relationships/belongs_to.js', module);
958
477
  require('/lib/model/relationships/has_many.js', module);
959
478
  require('/lib/model/relationships/ext.js', module);
@@ -1018,14 +537,16 @@
1018
537
  Ember.assert('Must be attached to a session', !!session);
1019
538
  this.eachRelationship(function (name, relationship) {
1020
539
  if (relationship.kind === 'belongsTo') {
1021
- var model = get(this, name);
1022
- if (model) {
1023
- session.belongsToManager.register(model, name, this);
540
+ var child = get(this, name);
541
+ if (child) {
542
+ session.reifyClientId(child);
543
+ session.belongsToManager.register(this, name, child);
1024
544
  }
1025
545
  } else if (relationship.kind === 'hasMany') {
1026
546
  var children = get(this, name);
1027
- children.forEach(function (model) {
1028
- session.collectionManager.register(children, model);
547
+ children.forEach(function (child) {
548
+ session.reifyClientId(child);
549
+ session.collectionManager.register(children, child);
1029
550
  }, this);
1030
551
  }
1031
552
  }, this);
@@ -1085,7 +606,7 @@
1085
606
  this.eachComputedProperty(function (name, meta) {
1086
607
  if (meta.isRelationship) {
1087
608
  if (typeof meta.type === 'string') {
1088
- meta.type = Ep.__container__.lookup('model:' + type);
609
+ meta.type = Ep.__container__.lookup('model:' + meta.type);
1089
610
  }
1090
611
  var relationshipsForType = map.get(meta.type);
1091
612
  relationshipsForType.push({
@@ -1132,7 +653,7 @@
1132
653
  meta.key = name;
1133
654
  type = meta.type;
1134
655
  if (typeof type === 'string') {
1135
- type = Ep.__container__.lookup('model:' + type);
656
+ meta.type = Ep.__container__.lookup('model:' + type);
1136
657
  }
1137
658
  map.set(name, meta);
1138
659
  }
@@ -1164,7 +685,9 @@
1164
685
  Ep.Model.reopen({
1165
686
  eachRelationship: function (callback, binding) {
1166
687
  this.constructor.eachRelationship(callback, binding);
1167
- },
688
+ }
689
+ });
690
+ Ep.ModelMixin.reopen({
1168
691
  eachRelatedModel: function (callback, binding, cache) {
1169
692
  if (!cache)
1170
693
  cache = Ember.Set.create();
@@ -1187,6 +710,21 @@
1187
710
  }, this);
1188
711
  }
1189
712
  }, this);
713
+ },
714
+ eachChild: function (callback, binding) {
715
+ this.eachRelationship(function (name, relationship) {
716
+ if (relationship.kind === 'belongsTo') {
717
+ var child = get(this, name);
718
+ if (child) {
719
+ callback.call(binding, child);
720
+ }
721
+ } else if (relationship.kind === 'hasMany') {
722
+ var children = get(this, name);
723
+ children.forEach(function (child) {
724
+ callback.call(binding, child);
725
+ }, this);
726
+ }
727
+ }, this);
1190
728
  }
1191
729
  });
1192
730
  });
@@ -1223,7 +761,6 @@
1223
761
  return Ep.HasManyArray.create({
1224
762
  owner: this,
1225
763
  name: key,
1226
- session: session,
1227
764
  content: content
1228
765
  });
1229
766
  }).property().meta(meta);
@@ -1231,6 +768,7 @@
1231
768
  Ep.HasManyArray = Ep.ModelArray.extend({
1232
769
  name: null,
1233
770
  owner: null,
771
+ session: Ember.computed.alias('owner.session'),
1234
772
  replaceContent: function (idx, amt, objects) {
1235
773
  var session = get(this, 'session');
1236
774
  if (session) {
@@ -1240,8 +778,15 @@
1240
778
  }
1241
779
  this._super(idx, amt, objects);
1242
780
  },
781
+ objectAtContent: function (index) {
782
+ var content = get(this, 'content'), model = content.objectAt(index), session = get(this, 'session');
783
+ if (session && model) {
784
+ return session.add(model);
785
+ }
786
+ return model;
787
+ },
1243
788
  arrayContentWillChange: function (index, removed, added) {
1244
- var owner = get(this, 'owner'), name = get(this, 'name'), session = get(owner, 'session');
789
+ var owner = get(this, 'owner'), name = get(this, 'name'), session = get(this, 'session');
1245
790
  if (session) {
1246
791
  session.modelWillBecomeDirty(owner);
1247
792
  }
@@ -1262,7 +807,7 @@
1262
807
  session.belongsToManager.unregister(model, inverse.name, owner);
1263
808
  }
1264
809
  }
1265
- });
810
+ }, this);
1266
811
  }
1267
812
  }
1268
813
  }
@@ -1283,12 +828,12 @@
1283
828
  get(model, inverse.name).addObject(owner);
1284
829
  } else if (inverse.kind === 'belongsTo') {
1285
830
  set(model, inverse.name, owner);
1286
- var session = get(owner, 'session');
831
+ var session = get(this, 'session');
1287
832
  if (session) {
1288
833
  session.belongsToManager.register(model, inverse.name, owner);
1289
834
  }
1290
835
  }
1291
- });
836
+ }, this);
1292
837
  }
1293
838
  }
1294
839
  }
@@ -1303,8 +848,9 @@
1303
848
  arrayContentWillChange: function (index, removed, added) {
1304
849
  for (var i = index; i < index + removed; i++) {
1305
850
  var model = this.objectAt(i);
1306
- if (this.session) {
1307
- this.session.collectionManager.unregister(this, model);
851
+ var session = get(this, 'session');
852
+ if (session) {
853
+ session.collectionManager.unregister(this, model);
1308
854
  }
1309
855
  }
1310
856
  this._super.apply(this, arguments);
@@ -1313,8 +859,9 @@
1313
859
  this._super.apply(this, arguments);
1314
860
  for (var i = index; i < index + added; i++) {
1315
861
  var model = this.objectAt(i);
1316
- if (this.session) {
1317
- this.session.collectionManager.register(this, model);
862
+ var session = get(this, 'session');
863
+ if (session) {
864
+ session.collectionManager.register(this, model);
1318
865
  }
1319
866
  }
1320
867
  },
@@ -1342,7 +889,7 @@
1342
889
  if (existing.contains(model)) {
1343
890
  existing.remove(model);
1344
891
  } else {
1345
- dest.addObject(model);
892
+ dest.pushObject(model);
1346
893
  }
1347
894
  });
1348
895
  dest.removeObjects(existing);
@@ -1420,9 +967,11 @@
1420
967
  Ep.Model = Ember.Object.extend(Ember.Copyable, Ep.ModelMixin, {
1421
968
  isPromise: false,
1422
969
  isProxy: false,
1423
- isNew: true,
1424
970
  isDeleted: false,
1425
971
  isLoaded: true,
972
+ isNew: Ember.computed(function () {
973
+ return !get(this, 'id');
974
+ }).property('id'),
1426
975
  isDirty: Ember.computed(function () {
1427
976
  var session = get(this, 'session');
1428
977
  if (!session)
@@ -1496,6 +1045,7 @@
1496
1045
  var dest = this.constructor.create();
1497
1046
  dest.beginPropertyChanges();
1498
1047
  this.copyAttributes(dest);
1048
+ this.copyMeta(dest);
1499
1049
  this.eachRelationship(function (name, relationship) {
1500
1050
  if (relationship.kind === 'belongsTo') {
1501
1051
  var child = get(this, name);
@@ -1506,7 +1056,7 @@
1506
1056
  var children = get(this, name);
1507
1057
  var destChildren = get(dest, name);
1508
1058
  children.forEach(function (child) {
1509
- destChildren.addObject(child.lazyCopy());
1059
+ destChildren.pushObject(child.lazyCopy());
1510
1060
  });
1511
1061
  }
1512
1062
  }, this);
@@ -1515,19 +1065,20 @@
1515
1065
  },
1516
1066
  copyAttributes: function (dest) {
1517
1067
  dest.beginPropertyChanges();
1518
- set(dest, 'id', get(this, 'id'));
1519
- set(dest, 'clientId', get(this, 'clientId'));
1520
- set(dest, 'rev', get(this, 'rev'));
1521
- set(dest, 'clientRev', get(this, 'clientRev'));
1522
- set(dest, 'errors', Ember.copy(get(this, 'errors')));
1523
- set(dest, 'isNew', get(this, 'isNew'));
1524
- set(dest, 'isDeleted', get(this, 'isDeleted'));
1525
1068
  this.eachAttribute(function (name, meta) {
1526
1069
  var left = get(this, name);
1527
1070
  var right = get(dest, name);
1528
1071
  set(dest, name, left);
1529
1072
  }, this);
1530
1073
  dest.endPropertyChanges();
1074
+ },
1075
+ copyMeta: function (dest) {
1076
+ set(dest, 'id', get(this, 'id'));
1077
+ set(dest, 'clientId', get(this, 'clientId'));
1078
+ set(dest, 'rev', get(this, 'rev'));
1079
+ set(dest, 'clientRev', get(this, 'clientRev'));
1080
+ set(dest, 'errors', Ember.copy(get(this, 'errors')));
1081
+ set(dest, 'isDeleted', get(this, 'isDeleted'));
1531
1082
  }
1532
1083
  });
1533
1084
  Ep.Model.reopenClass({
@@ -1538,7 +1089,10 @@
1538
1089
  var container = Ep.__container__;
1539
1090
  var session = container.lookup('session:main');
1540
1091
  return session.find(this, id);
1541
- }
1092
+ },
1093
+ typeKey: Ember.computed(function () {
1094
+ return Ember.String.underscore(this.toString().split('.')[1]);
1095
+ })
1542
1096
  });
1543
1097
  });
1544
1098
  require.define('/lib/collections/model_set.js', function (module, exports, __dirname, __filename) {
@@ -1709,6 +1263,22 @@
1709
1263
  });
1710
1264
  require.define('/lib/model/relationships/belongs_to.js', function (module, exports, __dirname, __filename) {
1711
1265
  var get = Ember.get, set = Ember.set, isNone = Ember.isNone;
1266
+ function BelongsToDescriptor(func, opts) {
1267
+ Ember.ComputedProperty.apply(this, arguments);
1268
+ }
1269
+ BelongsToDescriptor.prototype = new Ember.ComputedProperty();
1270
+ BelongsToDescriptor.prototype.get = function (obj, keyName) {
1271
+ if (!get(obj, 'isDetached') && this._suspended !== obj) {
1272
+ var ret, cache, cached, meta, session, existing;
1273
+ meta = Ember.meta(obj);
1274
+ cache = meta.cache;
1275
+ session = get(obj, 'session');
1276
+ if ((cached = cache[keyName]) && (existing = session.fetch(cached)) && existing !== cached) {
1277
+ cache[keyName] = existing;
1278
+ }
1279
+ }
1280
+ return Ember.ComputedProperty.prototype.get.apply(this, arguments);
1281
+ };
1712
1282
  Ep.belongsTo = function (type, options) {
1713
1283
  Ember.assert('The type passed to Ep.belongsTo must be defined', !!type);
1714
1284
  options = options || {};
@@ -1718,7 +1288,7 @@
1718
1288
  options: options,
1719
1289
  kind: 'belongsTo'
1720
1290
  };
1721
- return Ember.computed(function (key, value) {
1291
+ return new BelongsToDescriptor(function (key, value) {
1722
1292
  if (arguments.length === 1) {
1723
1293
  return null;
1724
1294
  } else {
@@ -1728,9 +1298,17 @@
1728
1298
  }
1729
1299
  return value;
1730
1300
  }
1731
- }).property().meta(meta);
1301
+ }).meta(meta);
1732
1302
  };
1733
1303
  Ep.Model.reopen({
1304
+ init: function () {
1305
+ this._super();
1306
+ this.eachRelationship(function (name, relationship) {
1307
+ if (relationship.kind === 'belongsTo') {
1308
+ this.belongsToDidChange(this, name);
1309
+ }
1310
+ }, this);
1311
+ },
1734
1312
  belongsToWillChange: Ember.beforeObserver(function (model, key) {
1735
1313
  var oldParent = get(model, key);
1736
1314
  var session = get(model, 'session');
@@ -1780,6 +1358,58 @@
1780
1358
  })
1781
1359
  });
1782
1360
  });
1361
+ require.define('/lib/model/debug.js', function (module, exports, __dirname, __filename) {
1362
+ Ep.Model.reopen({
1363
+ _debugInfo: function () {
1364
+ var attributes = ['id'], relationships = {
1365
+ belongsTo: [],
1366
+ hasMany: []
1367
+ }, expensiveProperties = [];
1368
+ this.eachAttribute(function (name, meta) {
1369
+ attributes.push(name);
1370
+ }, this);
1371
+ this.eachRelationship(function (name, relationship) {
1372
+ relationships[relationship.kind].push(name);
1373
+ expensiveProperties.push(name);
1374
+ });
1375
+ var groups = [
1376
+ {
1377
+ name: 'Attributes',
1378
+ properties: attributes,
1379
+ expand: true
1380
+ },
1381
+ {
1382
+ name: 'Belongs To',
1383
+ properties: relationships.belongsTo,
1384
+ expand: true
1385
+ },
1386
+ {
1387
+ name: 'Has Many',
1388
+ properties: relationships.hasMany,
1389
+ expand: true
1390
+ },
1391
+ {
1392
+ name: 'Flags',
1393
+ properties: [
1394
+ 'isLoaded',
1395
+ 'isDirty',
1396
+ 'isDeleted',
1397
+ 'isNew',
1398
+ 'isPromise',
1399
+ 'isProxy'
1400
+ ]
1401
+ }
1402
+ ];
1403
+ return {
1404
+ propertyInfo: {
1405
+ includeOtherProperties: true,
1406
+ groups: groups,
1407
+ expensiveProperties: expensiveProperties
1408
+ }
1409
+ };
1410
+ }
1411
+ });
1412
+ });
1783
1413
  require.define('/lib/model/attribute.js', function (module, exports, __dirname, __filename) {
1784
1414
  var get = Ember.get, set = Ember.set;
1785
1415
  Ep.Model.reopenClass({
@@ -1881,12 +1511,16 @@
1881
1511
  return content.copy();
1882
1512
  }
1883
1513
  return this.lazyCopy();
1884
- }
1514
+ },
1515
+ diff: passThroughMethod('diff', []),
1516
+ suspendRelationshipObservers: passThroughMethod('suspendRelationshipObservers'),
1517
+ eachAttribute: passThroughMethod('eachAttribute'),
1518
+ eachRelationship: passThroughMethod('eachRelationship'),
1519
+ _registerRelationships: passThroughMethod('_registerRelationships')
1885
1520
  });
1886
1521
  Ep.LoadError = Ep.ModelProxy.extend({});
1887
1522
  Ep.ModelPromise = Ep.ModelProxy.extend(Ember.DeferredMixin, {
1888
1523
  isPromise: true,
1889
- isNew: false,
1890
1524
  resolve: function (model) {
1891
1525
  set(this, 'content', model);
1892
1526
  return this._super.apply(this, arguments);
@@ -1904,12 +1538,7 @@
1904
1538
  } else {
1905
1539
  return '(no identifiers)';
1906
1540
  }
1907
- },
1908
- diff: passThroughMethod('diff', []),
1909
- suspendRelationshipObservers: passThroughMethod('suspendRelationshipObservers'),
1910
- eachAttribute: passThroughMethod('eachAttribute'),
1911
- eachRelationship: passThroughMethod('eachRelationship'),
1912
- _registerRelationships: passThroughMethod('_registerRelationships')
1541
+ }
1913
1542
  });
1914
1543
  Ep.LazyModel = Ep.ModelPromise.extend({
1915
1544
  willWatchProperty: triggerLoad(true),
@@ -1976,16 +1605,70 @@
1976
1605
  throw err;
1977
1606
  });
1978
1607
  }
1979
- return promise;
1980
- };
1608
+ return promise;
1609
+ };
1610
+ });
1611
+ require.define('/lib/serializer/json_serializer/embedded_helpers_mixin.js', function (module, exports, __dirname, __filename) {
1612
+ var get = Ember.get, set = Ember.set;
1613
+ Ep.EmbeddedHelpersMixin = Ember.Mixin.create({
1614
+ serializerFor: function (type) {
1615
+ var key = get(type, 'typeKey');
1616
+ return this.container.lookup('serializer:' + key) || this.container.lookup('serializer:main');
1617
+ },
1618
+ embeddedType: function (type, name) {
1619
+ var serializer = this.serializerFor(type);
1620
+ if (this === serializer) {
1621
+ var config = this.configFor(name);
1622
+ return config.embedded;
1623
+ }
1624
+ return serializer.embeddedType(type, name);
1625
+ },
1626
+ eachEmbeddedRecord: function (record, callback, binding) {
1627
+ this.eachEmbeddedBelongsToRecord(record, callback, binding);
1628
+ this.eachEmbeddedHasManyRecord(record, callback, binding);
1629
+ },
1630
+ eachEmbeddedBelongsToRecord: function (record, callback, binding) {
1631
+ this.eachEmbeddedBelongsTo(record.constructor, function (name, relationship, embeddedType) {
1632
+ var embeddedRecord = get(record, name);
1633
+ if (embeddedRecord) {
1634
+ callback.call(binding, embeddedRecord, embeddedType);
1635
+ }
1636
+ });
1637
+ },
1638
+ eachEmbeddedHasManyRecord: function (record, callback, binding) {
1639
+ this.eachEmbeddedHasMany(record.constructor, function (name, relationship, embeddedType) {
1640
+ var array = get(record, name);
1641
+ for (var i = 0, l = get(array, 'length'); i < l; i++) {
1642
+ callback.call(binding, array.objectAt(i), embeddedType);
1643
+ }
1644
+ });
1645
+ },
1646
+ eachEmbeddedHasMany: function (type, callback, binding) {
1647
+ this.eachEmbeddedRelationship(type, 'hasMany', callback, binding);
1648
+ },
1649
+ eachEmbeddedBelongsTo: function (type, callback, binding) {
1650
+ this.eachEmbeddedRelationship(type, 'belongsTo', callback, binding);
1651
+ },
1652
+ eachEmbeddedRelationship: function (type, kind, callback, binding) {
1653
+ type.eachRelationship(function (name, relationship) {
1654
+ var embeddedType = this.embeddedType(type, name);
1655
+ if (embeddedType) {
1656
+ if (relationship.kind === kind) {
1657
+ callback.call(binding, name, relationship, embeddedType);
1658
+ }
1659
+ }
1660
+ }, this);
1661
+ }
1662
+ });
1981
1663
  });
1982
1664
  require.define('/lib/rest/rest_adapter.js', function (module, exports, __dirname, __filename) {
1983
1665
  require('/lib/adapter.js', module);
1984
1666
  require('/lib/rest/embedded_manager.js', module);
1985
1667
  require('/lib/rest/operation_graph.js', module);
1986
1668
  require('/lib/rest/rest_errors.js', module);
1669
+ require('/lib/serializer/json_serializer/embedded_helpers_mixin.js', module);
1987
1670
  var get = Ember.get, set = Ember.set;
1988
- Ep.RestAdapter = Ep.Adapter.extend({
1671
+ Ep.RestAdapter = Ep.Adapter.extend(Ep.EmbeddedHelpersMixin, {
1989
1672
  init: function () {
1990
1673
  this._super.apply(this, arguments);
1991
1674
  this._embeddedManager = Ep.EmbeddedManager.create({ adapter: this });
@@ -1994,65 +1677,55 @@
1994
1677
  load: function (type, id) {
1995
1678
  var root = this.rootForType(type), adapter = this;
1996
1679
  return this.ajax(this.buildURL(root, id), 'GET').then(function (json) {
1997
- return Ember.run(adapter, 'didReceiveDataForLoad', json, type, id);
1680
+ return adapter.didReceiveDataForLoad(json, type, id);
1998
1681
  }, function (xhr) {
1999
1682
  var model = Ep.LoadError.create({
2000
1683
  id: id,
2001
1684
  type: type
2002
1685
  });
2003
- throw Ember.run(adapter, 'didError', xhr, model);
1686
+ throw adapter.didError(xhr, model);
2004
1687
  });
2005
1688
  },
2006
1689
  refresh: function (model) {
2007
- var type = get(model, 'type');
2008
- var root = this.rootForType(type), adapter = this;
2009
- var id = get(model, 'id');
1690
+ var type = get(model, 'type'), root = this.rootForType(type), id = get(model, 'id'), adapter = this;
2010
1691
  return this.ajax(this.buildURL(root, id), 'GET').then(function (json) {
2011
- return Ember.run(adapter, 'didReceiveData', json, model);
1692
+ return adapter.didReceiveData(json, model);
2012
1693
  }, function (xhr) {
2013
- throw Ember.run(adapter, 'didError', xhr, model);
1694
+ throw adapter.didError(xhr, model);
2014
1695
  });
2015
1696
  },
2016
1697
  update: function (model) {
2017
- var id, root, adapter, data, type = get(model, 'type');
2018
- id = get(model, 'id');
2019
- root = this.rootForType(type);
2020
- adapter = this;
2021
- data = {};
2022
- data[root] = get(this, 'serializer').serialize(model);
1698
+ var type = get(model, 'type'), root = this.rootForType(type), id = get(model, 'id'), adapter = this, serializer = this.serializerFor(type);
1699
+ var data = {};
1700
+ data[root] = serializer.serialize(model);
2023
1701
  return this.ajax(this.buildURL(root, id), 'PUT', { data: data }).then(function (json) {
2024
- return Ember.run(adapter, 'didReceiveData', json, model);
1702
+ return adapter.didReceiveData(json, model);
2025
1703
  }, function (xhr) {
2026
- throw Ember.run(adapter, 'didError', xhr, model);
1704
+ throw adapter.didError(xhr, model);
2027
1705
  });
2028
1706
  },
2029
1707
  create: function (model) {
2030
- var type = get(model, 'type');
2031
- var root = this.rootForType(type);
2032
- var adapter = this;
1708
+ var type = get(model, 'type'), root = this.rootForType(type), adapter = this, serializer = this.serializerFor(type);
2033
1709
  var data = {};
2034
- data[root] = get(this, 'serializer').serialize(model, { includeId: true });
1710
+ data[root] = serializer.serialize(model, { includeId: true });
2035
1711
  return this.ajax(this.buildURL(root), 'POST', { data: data }).then(function (json) {
2036
- return Ember.run(adapter, 'didReceiveData', json, model);
1712
+ return adapter.didReceiveData(json, model);
2037
1713
  }, function (xhr) {
2038
- throw Ember.run(adapter, 'didError', xhr, model);
1714
+ throw adapter.didError(xhr, model);
2039
1715
  });
2040
1716
  },
2041
1717
  deleteModel: function (model) {
2042
- var id, root, adapter, type = get(model, 'type');
2043
- id = get(model, 'id');
2044
- root = this.rootForType(type);
2045
- adapter = this;
1718
+ var type = get(model, 'type'), root = this.rootForType(type), id = get(model, 'id'), adapter = this;
2046
1719
  return this.ajax(this.buildURL(root, id), 'DELETE').then(function (json) {
2047
- return Ember.run(adapter, 'didReceiveData', json, model);
1720
+ return adapter.didReceiveData(json, model);
2048
1721
  }, function (xhr) {
2049
- throw Ember.run(adapter, 'didError', xhr, model);
1722
+ throw adapter.didError(xhr, model);
2050
1723
  });
2051
1724
  },
2052
1725
  query: function (type, query) {
2053
1726
  var root = this.rootForType(type), adapter = this;
2054
1727
  return this.ajax(this.buildURL(root), 'GET', { data: query }).then(function (json) {
2055
- return Ember.run(adapter, 'didReceiveDataForFind', json, type);
1728
+ return adapter.didReceiveDataForFind(json, type);
2056
1729
  }, function (xhr) {
2057
1730
  throw xhr;
2058
1731
  });
@@ -2060,26 +1733,26 @@
2060
1733
  remoteCall: function (context, name, params) {
2061
1734
  var url, adapter = this;
2062
1735
  if (typeof context === 'string') {
2063
- context = this.lookupType(context);
1736
+ context = this.typeFor(context);
2064
1737
  }
2065
1738
  if (typeof context === 'function') {
2066
1739
  url = this.buildURL(this.rootForType(context));
2067
1740
  } else {
2068
1741
  var id = get(context, 'id');
2069
1742
  Ember.assert('Cannot perform a remote call with a context that doesn\'t have an id', id);
2070
- url = this.buildURL(this.rootForType(context.constructor), id);
1743
+ url = this.buildURL(this.rootForType(get(context, 'type')), id);
2071
1744
  }
2072
1745
  url = url + '/' + name;
2073
1746
  var data = params;
2074
1747
  var method = 'POST';
2075
1748
  return this.ajax(url, method, { data: data }).then(function (json) {
2076
- return Ember.run(adapter, 'didReceiveDataForRpc', json, context);
1749
+ return adapter.didReceiveDataForRpc(json, context);
2077
1750
  }, function (xhr) {
2078
- throw Ember.run(adapter, 'didError', xhr, context);
1751
+ throw adapter.didError(xhr, context);
2079
1752
  });
2080
1753
  },
2081
- lookupType: function (type) {
2082
- return this.container.lookup('model:' + type);
1754
+ typeFor: function (typeName) {
1755
+ return this.container.lookup('model:' + typeName);
2083
1756
  },
2084
1757
  didReceiveData: function (data, targetModel) {
2085
1758
  var result = null;
@@ -2112,7 +1785,7 @@
2112
1785
  return this.didReceiveData(data, context);
2113
1786
  },
2114
1787
  processData: function (data, callback, binding) {
2115
- var models = get(this, 'serializer').deserialize(data);
1788
+ var models = get(this, 'serializer').deserializePayload(data);
2116
1789
  models.forEach(function (model) {
2117
1790
  this.willLoadModel(model);
2118
1791
  }, this);
@@ -2221,7 +1894,8 @@
2221
1894
  },
2222
1895
  isRelationshipOwner: function (relationship) {
2223
1896
  var serializer = get(this, 'serializer');
2224
- var owner = serializer.mappingOption(relationship.parentType, relationship.key, 'owner');
1897
+ var config = this.configFor(relationship.parentType);
1898
+ var owner = config[relationship.key] && config[relationship.key].owner;
2225
1899
  return relationship.kind === 'belongsTo' && owner !== false || relationship.kind === 'hasMany' && owner === true;
2226
1900
  },
2227
1901
  isDirtyFromRelationships: function (model, cached, relDiff) {
@@ -2254,42 +1928,17 @@
2254
1928
  shadows.removeObjects(orphans);
2255
1929
  },
2256
1930
  dirtyEmbedded: function (models, shadows, session) {
2257
- this.dirtyEmbeddedParents(models, shadows, session);
2258
1931
  models.forEach(function (model) {
2259
- this.dirtyEmbeddedTree(model, models, shadows, session);
2260
- }, this);
2261
- },
2262
- dirtyEmbeddedParents: function (models, shadows, session) {
2263
- models.forEach(function (model) {
2264
- var parent;
2265
- while (parent = this._embeddedManager.findParent(model)) {
2266
- model = session.getModel(parent);
2267
- if (!models.contains(model)) {
2268
- var copy = model.copy();
2269
- models.add(copy);
2270
- shadows.add(copy);
1932
+ this.eachEmbeddedRelative(model, function (embeddedModel) {
1933
+ this._embeddedManager.updateParents(embeddedModel);
1934
+ if (models.contains(embeddedModel)) {
1935
+ return;
2271
1936
  }
2272
- }
2273
- this._embeddedManager.updateParents(model);
2274
- }, this);
2275
- },
2276
- dirtyEmbeddedTree: function (model, models, shadows, session) {
2277
- get(this, 'serializer').eachEmbeddedRecord(model, function (embeddedRecord, embeddedType) {
2278
- if (embeddedType !== 'always') {
2279
- return;
2280
- }
2281
- if (models.contains(embeddedRecord)) {
2282
- return;
2283
- }
2284
- embeddedRecord = session.getModel(embeddedRecord);
2285
- if (!embeddedRecord)
2286
- return;
2287
- if (!models.contains(embeddedRecord)) {
2288
- var copy = embeddedRecord.copy();
1937
+ embeddedModel = session.getModel(embeddedModel);
1938
+ var copy = embeddedModel.copy();
2289
1939
  models.add(copy);
2290
1940
  shadows.add(copy);
2291
- }
2292
- this.dirtyEmbeddedTree(embeddedRecord, models, shadows, session);
1941
+ }, this);
2293
1942
  }, this);
2294
1943
  },
2295
1944
  findEmbeddedRoot: function (model, models) {
@@ -2300,6 +1949,23 @@
2300
1949
  }
2301
1950
  return models.getModel(model);
2302
1951
  },
1952
+ eachEmbeddedRelative: function (model, callback, binding, visited) {
1953
+ if (!get(model, 'isLoaded'))
1954
+ return;
1955
+ if (!visited)
1956
+ visited = new Ember.Set();
1957
+ if (visited.contains(model))
1958
+ return;
1959
+ visited.add(model);
1960
+ callback.call(binding, model);
1961
+ get(this, 'serializer').eachEmbeddedRecord(model, function (embeddedRecord, embeddedType) {
1962
+ this.eachEmbeddedRelative(embeddedRecord, callback, binding, visited);
1963
+ }, this);
1964
+ var parent = this._embeddedManager.findParent(model);
1965
+ if (parent) {
1966
+ this.eachEmbeddedRelative(parent, callback, binding, visited);
1967
+ }
1968
+ },
2303
1969
  materializeRelationships: function (models) {
2304
1970
  if (!(models instanceof Ep.ModelSet)) {
2305
1971
  models = Ep.ModelSet.fromArray(models);
@@ -2326,24 +1992,40 @@
2326
1992
  }, this);
2327
1993
  },
2328
1994
  ajax: function (url, type, hash) {
2329
- try {
1995
+ var adapter = this;
1996
+ return new Ember.RSVP.Promise(function (resolve, reject) {
2330
1997
  hash = hash || {};
2331
1998
  hash.url = url;
2332
1999
  hash.type = type;
2333
2000
  hash.dataType = 'json';
2334
- hash.context = this;
2001
+ hash.context = adapter;
2335
2002
  if (hash.data && type !== 'GET') {
2336
2003
  hash.contentType = 'application/json; charset=utf-8';
2337
2004
  hash.data = JSON.stringify(hash.data);
2338
2005
  }
2339
- return Ember.RSVP.resolve(jQuery.ajax(hash));
2340
- } catch (error) {
2341
- return Ember.RSVP.resolve(error);
2342
- }
2006
+ if (adapter.headers !== undefined) {
2007
+ var headers = adapter.headers;
2008
+ hash.beforeSend = function (xhr) {
2009
+ forEach.call(Ember.keys(headers), function (key) {
2010
+ xhr.setRequestHeader(key, headers[key]);
2011
+ });
2012
+ };
2013
+ }
2014
+ hash.success = function (json) {
2015
+ Ember.run(null, resolve, json);
2016
+ };
2017
+ hash.error = function (jqXHR, textStatus, errorThrown) {
2018
+ if (jqXHR) {
2019
+ jqXHR.then = null;
2020
+ }
2021
+ Ember.run(null, reject, jqXHR);
2022
+ };
2023
+ Ember.$.ajax(hash);
2024
+ });
2343
2025
  },
2344
2026
  url: '',
2345
2027
  rootForType: function (type) {
2346
- var serializer = get(this, 'serializer');
2028
+ var serializer = this.serializerFor(type);
2347
2029
  return serializer.rootForType(type);
2348
2030
  },
2349
2031
  pluralize: function (string) {
@@ -2363,7 +2045,10 @@
2363
2045
  url.push(suffix);
2364
2046
  }
2365
2047
  return url.join('/');
2366
- }
2048
+ },
2049
+ serializer: Ember.computed(function () {
2050
+ return container.lookup('serializer:main');
2051
+ })
2367
2052
  });
2368
2053
  });
2369
2054
  require.define('/lib/rest/rest_errors.js', function (module, exports, __dirname, __filename) {
@@ -2407,6 +2092,7 @@
2407
2092
  },
2408
2093
  build: function () {
2409
2094
  var adapter = get(this, 'adapter');
2095
+ var serializer = get(adapter, 'serializer');
2410
2096
  var models = get(this, 'models');
2411
2097
  var shadows = get(this, 'shadows');
2412
2098
  var rootOps = get(this, 'rootOps');
@@ -2433,7 +2119,8 @@
2433
2119
  var d = rels[i];
2434
2120
  var name = d.name;
2435
2121
  var parentModel = model.get(name) || shadows.getModel(d.oldValue);
2436
- if (parentModel) {
2122
+ var isEmbeddedRel = serializer.embeddedType(get(model, 'type'), name);
2123
+ if (parentModel && !isEmbeddedRel) {
2437
2124
  var parentOp = this.getOp(parentModel);
2438
2125
  parentOp.addChild(op);
2439
2126
  }
@@ -2638,8 +2325,7 @@
2638
2325
  this._cachedIsEmbedded = Ember.Map.create();
2639
2326
  },
2640
2327
  updateParents: function (model) {
2641
- var serializer = get(this, 'adapter.serializer');
2642
- var parentType = get(model, 'type');
2328
+ var type = get(model, 'type'), adapter = get(this, 'adapter'), serializer = adapter.serializerFor(type);
2643
2329
  serializer.eachEmbeddedRecord(model, function (embedded, kind) {
2644
2330
  this._parentMap[get(embedded, 'clientId')] = model;
2645
2331
  }, this);
@@ -2649,19 +2335,17 @@
2649
2335
  return parent;
2650
2336
  },
2651
2337
  isEmbedded: function (model) {
2652
- var type = get(model, 'type');
2653
- var result = this._cachedIsEmbedded.get(type);
2654
- if (result === true || result === false)
2338
+ var type = get(model, 'type'), result = this._cachedIsEmbedded.get(type);
2339
+ if (result !== undefined)
2655
2340
  return result;
2656
- var adapter = get(this, 'adapter');
2657
- var mappings = get(adapter, 'serializer.mappings');
2658
- var result = false;
2659
- mappings.forEach(function (parentType, value) {
2660
- for (var name in value) {
2661
- var embedded = value[name]['embedded'];
2662
- result = result || embedded === 'always' && parentType.typeForRelationship(name).detect(type);
2663
- }
2664
- });
2341
+ var adapter = get(this, 'adapter'), result = false;
2342
+ type.eachRelationship(function (name, relationship) {
2343
+ var parentType = relationship.type, serializer = adapter.serializerFor(parentType), inverse = type.inverseFor(relationship.key);
2344
+ if (!inverse)
2345
+ return;
2346
+ var config = serializer.configFor(inverse.name);
2347
+ result = result || config.embedded === 'always';
2348
+ }, this);
2665
2349
  this._cachedIsEmbedded.set(type, result);
2666
2350
  return result;
2667
2351
  }
@@ -2669,34 +2353,35 @@
2669
2353
  });
2670
2354
  require.define('/lib/adapter.js', function (module, exports, __dirname, __filename) {
2671
2355
  var get = Ember.get, set = Ember.set, merge = Ember.merge;
2672
- require('/lib/mixins/mappable.js', module);
2673
2356
  function mustImplement(name) {
2674
2357
  return function () {
2675
2358
  throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
2676
2359
  };
2677
2360
  }
2678
2361
  var uuid = 1;
2679
- Ep.Adapter = Ember.Object.extend(Ep._Mappable, {
2362
+ Ep.Adapter = Ember.Object.extend({
2363
+ mergedProperties: ['configs'],
2680
2364
  init: function () {
2681
2365
  this._super.apply(this, arguments);
2366
+ this.configs = {};
2682
2367
  this.idMaps = Ember.MapWithDefault.create({
2683
2368
  defaultValue: function (type) {
2684
2369
  return Ember.Map.create();
2685
2370
  }
2686
2371
  });
2687
2372
  },
2373
+ configFor: function (type) {
2374
+ var configs = get(this, 'configs'), typeKey = get(type, 'typeKey');
2375
+ return configs[typeKey] || {};
2376
+ },
2688
2377
  newSession: function () {
2689
2378
  var session = this.container.lookup('session:base');
2690
2379
  set(session, 'adapter', this);
2691
2380
  return session;
2692
2381
  },
2693
- serializer: Ember.computed(function (key, serializer) {
2694
- this._attributesMap = this.createInstanceMapFor('attributes');
2695
- this._configurationsMap = this.createInstanceMapFor('configurations');
2696
- this.registerSerializerTransforms(this.constructor, serializer, {});
2697
- this.registerSerializerMappings(serializer);
2698
- return serializer;
2699
- }),
2382
+ serializerFor: function (type) {
2383
+ return this.container.lookup('serializer:' + type) || this.container.lookup('serializer:main');
2384
+ },
2700
2385
  load: mustImplement('load'),
2701
2386
  query: mustImplement('find'),
2702
2387
  refresh: mustImplement('refresh'),
@@ -2708,32 +2393,6 @@
2708
2393
  shouldSave: function (model) {
2709
2394
  return true;
2710
2395
  },
2711
- registerSerializerTransforms: function (klass, serializer, seen) {
2712
- var transforms = klass._registeredTransforms, superclass, prop;
2713
- var enumTransforms = klass._registeredEnumTransforms;
2714
- for (prop in transforms) {
2715
- if (!transforms.hasOwnProperty(prop) || prop in seen) {
2716
- continue;
2717
- }
2718
- seen[prop] = true;
2719
- serializer.registerTransform(prop, transforms[prop]);
2720
- }
2721
- for (prop in enumTransforms) {
2722
- if (!enumTransforms.hasOwnProperty(prop) || prop in seen) {
2723
- continue;
2724
- }
2725
- seen[prop] = true;
2726
- serializer.registerEnumTransform(prop, enumTransforms[prop]);
2727
- }
2728
- if (superclass = klass.superclass) {
2729
- this.registerSerializerTransforms(superclass, serializer, seen);
2730
- }
2731
- },
2732
- registerSerializerMappings: function (serializer) {
2733
- var mappings = this._attributesMap, configurations = this._configurationsMap;
2734
- mappings.forEach(serializer.map, serializer);
2735
- configurations.forEach(serializer.configure, serializer);
2736
- },
2737
2396
  reifyClientId: function (model) {
2738
2397
  var id = get(model, 'id'), clientId = get(model, 'clientId'), type = get(model, 'type'), idMap = this.idMaps.get(type);
2739
2398
  if (id && clientId) {
@@ -2759,109 +2418,9 @@
2759
2418
  return idMap.get(id);
2760
2419
  },
2761
2420
  _generateClientId: function (type) {
2762
- return this._typeToString(type) + uuid++;
2763
- },
2764
- _typeToString: function (type) {
2765
- return type.toString().split('.')[1].underscore();
2766
- }
2767
- });
2768
- Ep.Adapter.reopenClass({
2769
- registerTransform: function (attributeType, transform) {
2770
- var registeredTransforms = this._registeredTransforms || {};
2771
- registeredTransforms[attributeType] = transform;
2772
- this._registeredTransforms = registeredTransforms;
2773
- },
2774
- registerEnumTransform: function (attributeType, objects) {
2775
- var registeredEnumTransforms = this._registeredEnumTransforms || {};
2776
- registeredEnumTransforms[attributeType] = objects;
2777
- this._registeredEnumTransforms = registeredEnumTransforms;
2778
- },
2779
- map: Ep._Mappable.generateMapFunctionFor('attributes', function (key, newValue, map) {
2780
- var existingValue = map.get(key);
2781
- merge(existingValue, newValue);
2782
- }),
2783
- configure: Ep._Mappable.generateMapFunctionFor('configurations', function (key, newValue, map) {
2784
- var existingValue = map.get(key);
2785
- var mappings = newValue && newValue.mappings;
2786
- if (mappings) {
2787
- this.map(key, mappings);
2788
- delete newValue.mappings;
2789
- }
2790
- merge(existingValue, newValue);
2791
- }),
2792
- resolveMapConflict: function (oldValue, newValue) {
2793
- merge(newValue, oldValue);
2794
- return newValue;
2795
- }
2796
- });
2797
- });
2798
- require.define('/lib/mixins/mappable.js', function (module, exports, __dirname, __filename) {
2799
- var get = Ember.get;
2800
- var resolveMapConflict = function (oldValue, newValue) {
2801
- return oldValue;
2802
- };
2803
- var transformMapKey = function (key, value) {
2804
- return key;
2805
- };
2806
- var transformMapValue = function (key, value) {
2807
- return value;
2808
- };
2809
- Ep._Mappable = Ember.Mixin.create({
2810
- createInstanceMapFor: function (mapName) {
2811
- var instanceMeta = getMappableMeta(this);
2812
- instanceMeta.values = instanceMeta.values || {};
2813
- if (instanceMeta.values[mapName]) {
2814
- return instanceMeta.values[mapName];
2815
- }
2816
- var instanceMap = instanceMeta.values[mapName] = new Ember.Map();
2817
- var klass = this.constructor;
2818
- while (klass && klass !== Ep.Store) {
2819
- this._copyMap(mapName, klass, instanceMap);
2820
- klass = klass.superclass;
2821
- }
2822
- instanceMeta.values[mapName] = instanceMap;
2823
- return instanceMap;
2824
- },
2825
- _copyMap: function (mapName, klass, instanceMap) {
2826
- var classMeta = getMappableMeta(klass);
2827
- var classMap = classMeta[mapName];
2828
- if (classMap) {
2829
- classMap.forEach(eachMap, this);
2830
- }
2831
- function eachMap(key, value) {
2832
- var transformedKey = (klass.transformMapKey || transformMapKey)(key, value);
2833
- var transformedValue = (klass.transformMapValue || transformMapValue)(key, value);
2834
- var oldValue = instanceMap.get(transformedKey);
2835
- var newValue = transformedValue;
2836
- if (oldValue) {
2837
- newValue = (this.constructor.resolveMapConflict || resolveMapConflict)(oldValue, newValue);
2838
- }
2839
- instanceMap.set(transformedKey, newValue);
2840
- }
2421
+ return get(type, 'typeKey') + uuid++;
2841
2422
  }
2842
2423
  });
2843
- Ep._Mappable.generateMapFunctionFor = function (mapName, transform) {
2844
- return function (key, value) {
2845
- var meta = getMappableMeta(this);
2846
- var map = meta[mapName] || Ember.MapWithDefault.create({
2847
- defaultValue: function () {
2848
- return {};
2849
- }
2850
- });
2851
- transform.call(this, key, value, map);
2852
- meta[mapName] = map;
2853
- };
2854
- };
2855
- function getMappableMeta(obj) {
2856
- var meta = Ember.meta(obj, true), keyName = 'Ep.Mappable', value = meta[keyName];
2857
- if (!value) {
2858
- meta[keyName] = {};
2859
- }
2860
- if (!meta.hasOwnProperty(keyName)) {
2861
- meta[keyName] = Ember.create(meta[keyName]);
2862
- }
2863
- return meta[keyName];
2864
- }
2865
2424
  });
2866
2425
  require.define('/lib/local/index.js', function (module, exports, __dirname, __filename) {
2867
2426
  require('/lib/local/local_adapter.js', module);
@@ -2883,6 +2442,149 @@
2883
2442
  }
2884
2443
  });
2885
2444
  });
2445
+ require.define('/lib/transforms/index.js', function (module, exports, __dirname, __filename) {
2446
+ require('/lib/transforms/base.js', module);
2447
+ require('/lib/transforms/boolean.js', module);
2448
+ require('/lib/transforms/date.js', module);
2449
+ require('/lib/transforms/number.js', module);
2450
+ require('/lib/transforms/string.js', module);
2451
+ });
2452
+ require.define('/lib/transforms/string.js', function (module, exports, __dirname, __filename) {
2453
+ var none = Ember.isNone, empty = Ember.isEmpty;
2454
+ Ep.StringTransform = Ep.Transform.extend({
2455
+ deserialize: function (serialized) {
2456
+ return none(serialized) ? null : String(serialized);
2457
+ },
2458
+ serialize: function (deserialized) {
2459
+ return none(deserialized) ? null : String(deserialized);
2460
+ }
2461
+ });
2462
+ });
2463
+ require.define('/lib/transforms/number.js', function (module, exports, __dirname, __filename) {
2464
+ var empty = Ember.isEmpty;
2465
+ Ep.NumberTransform = Ep.Transform.extend({
2466
+ deserialize: function (serialized) {
2467
+ return empty(serialized) ? null : Number(serialized);
2468
+ },
2469
+ serialize: function (deserialized) {
2470
+ return empty(deserialized) ? null : Number(deserialized);
2471
+ }
2472
+ });
2473
+ });
2474
+ require.define('/lib/transforms/date.js', function (module, exports, __dirname, __filename) {
2475
+ require('/lib/ext/date.js', module);
2476
+ Ep.DateTransform = Ep.Transform.extend({
2477
+ deserialize: function (serialized) {
2478
+ var type = typeof serialized;
2479
+ if (type === 'string') {
2480
+ return new Date(Ember.Date.parse(serialized));
2481
+ } else if (type === 'number') {
2482
+ return new Date(serialized);
2483
+ } else if (serialized === null || serialized === undefined) {
2484
+ return serialized;
2485
+ } else {
2486
+ return null;
2487
+ }
2488
+ },
2489
+ serialize: function (date) {
2490
+ if (date instanceof Date) {
2491
+ var days = [
2492
+ 'Sun',
2493
+ 'Mon',
2494
+ 'Tue',
2495
+ 'Wed',
2496
+ 'Thu',
2497
+ 'Fri',
2498
+ 'Sat'
2499
+ ];
2500
+ var months = [
2501
+ 'Jan',
2502
+ 'Feb',
2503
+ 'Mar',
2504
+ 'Apr',
2505
+ 'May',
2506
+ 'Jun',
2507
+ 'Jul',
2508
+ 'Aug',
2509
+ 'Sep',
2510
+ 'Oct',
2511
+ 'Nov',
2512
+ 'Dec'
2513
+ ];
2514
+ var pad = function (num) {
2515
+ return num < 10 ? '0' + num : '' + num;
2516
+ };
2517
+ var utcYear = date.getUTCFullYear(), utcMonth = date.getUTCMonth(), utcDayOfMonth = date.getUTCDate(), utcDay = date.getUTCDay(), utcHours = date.getUTCHours(), utcMinutes = date.getUTCMinutes(), utcSeconds = date.getUTCSeconds();
2518
+ var dayOfWeek = days[utcDay];
2519
+ var dayOfMonth = pad(utcDayOfMonth);
2520
+ var month = months[utcMonth];
2521
+ return dayOfWeek + ', ' + dayOfMonth + ' ' + month + ' ' + utcYear + ' ' + pad(utcHours) + ':' + pad(utcMinutes) + ':' + pad(utcSeconds) + ' GMT';
2522
+ } else {
2523
+ return null;
2524
+ }
2525
+ }
2526
+ });
2527
+ });
2528
+ require.define('/lib/ext/date.js', function (module, exports, __dirname, __filename) {
2529
+ Ember.Date = Ember.Date || {};
2530
+ var origParse = Date.parse, numericKeys = [
2531
+ 1,
2532
+ 4,
2533
+ 5,
2534
+ 6,
2535
+ 7,
2536
+ 10,
2537
+ 11
2538
+ ];
2539
+ Ember.Date.parse = function (date) {
2540
+ var timestamp, struct, minutesOffset = 0;
2541
+ 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)) {
2542
+ for (var i = 0, k; k = numericKeys[i]; ++i) {
2543
+ struct[k] = +struct[k] || 0;
2544
+ }
2545
+ struct[2] = (+struct[2] || 1) - 1;
2546
+ struct[3] = +struct[3] || 1;
2547
+ if (struct[8] !== 'Z' && struct[9] !== undefined) {
2548
+ minutesOffset = struct[10] * 60 + struct[11];
2549
+ if (struct[9] === '+') {
2550
+ minutesOffset = 0 - minutesOffset;
2551
+ }
2552
+ }
2553
+ timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
2554
+ } else {
2555
+ timestamp = origParse ? origParse(date) : NaN;
2556
+ }
2557
+ return timestamp;
2558
+ };
2559
+ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Date) {
2560
+ Date.parse = Ember.Date.parse;
2561
+ }
2562
+ });
2563
+ require.define('/lib/transforms/boolean.js', function (module, exports, __dirname, __filename) {
2564
+ Ep.BooleanTransform = Ep.Transform.extend({
2565
+ deserialize: function (serialized) {
2566
+ var type = typeof serialized;
2567
+ if (type === 'boolean') {
2568
+ return serialized;
2569
+ } else if (type === 'string') {
2570
+ return serialized.match(/^true$|^t$|^1$/i) !== null;
2571
+ } else if (type === 'number') {
2572
+ return serialized === 1;
2573
+ } else {
2574
+ return false;
2575
+ }
2576
+ },
2577
+ serialize: function (deserialized) {
2578
+ return Boolean(deserialized);
2579
+ }
2580
+ });
2581
+ });
2582
+ require.define('/lib/transforms/base.js', function (module, exports, __dirname, __filename) {
2583
+ Ep.Transform = Ember.Object.extend({
2584
+ serialize: Ember.required(),
2585
+ deserialize: Ember.required()
2586
+ });
2587
+ });
2886
2588
  require.define('/lib/session/index.js', function (module, exports, __dirname, __filename) {
2887
2589
  require('/lib/session/session.js', module);
2888
2590
  require('/lib/session/merge.js', module);
@@ -2891,6 +2593,24 @@
2891
2593
  require.define('/lib/session/child_session.js', function (module, exports, __dirname, __filename) {
2892
2594
  var get = Ember.get, set = Ember.set;
2893
2595
  Ep.ChildSession = Ep.Session.extend({
2596
+ fetch: function (model) {
2597
+ var res = this._super(model);
2598
+ if (!res) {
2599
+ res = get(this, 'parent').fetch(model);
2600
+ if (res) {
2601
+ res = this.adopt(res.copy());
2602
+ res.eachRelationship(function (name, relationship) {
2603
+ if (relationship.kind === 'belongsTo') {
2604
+ var child = get(res, name);
2605
+ if (child) {
2606
+ set(child, 'session', this);
2607
+ }
2608
+ }
2609
+ }, this);
2610
+ }
2611
+ }
2612
+ return res;
2613
+ },
2894
2614
  load: function (type, id) {
2895
2615
  if (typeof type === 'string') {
2896
2616
  type = this.lookupType(type);
@@ -2920,7 +2640,7 @@
2920
2640
  });
2921
2641
  set(merged, 'meta', get(models, 'meta'));
2922
2642
  models.forEach(function (model) {
2923
- merged.addObject(session.merge(model));
2643
+ merged.pushObject(session.merge(model));
2924
2644
  });
2925
2645
  return merged;
2926
2646
  });
@@ -2943,12 +2663,12 @@
2943
2663
  var res = models.map(function (model) {
2944
2664
  return session.merge(model);
2945
2665
  });
2946
- return models;
2666
+ return res;
2947
2667
  }, function (models) {
2948
2668
  var res = models.map(function (model) {
2949
2669
  return session.merge(model);
2950
2670
  });
2951
- throw models;
2671
+ throw res;
2952
2672
  });
2953
2673
  dirtyModels.forEach(function (model) {
2954
2674
  this.shadows.add(model.copy());
@@ -2976,13 +2696,31 @@
2976
2696
  require.define('/lib/session/merge.js', function (module, exports, __dirname, __filename) {
2977
2697
  var get = Ember.get, set = Ember.set;
2978
2698
  Ep.Session.reopen({
2979
- merge: function (model, strategy) {
2699
+ merge: function (model, strategy, visited) {
2980
2700
  this.reifyClientId(model);
2701
+ if (!visited)
2702
+ visited = new Ember.Set();
2703
+ if (visited.contains(model)) {
2704
+ return this.getModel(model);
2705
+ }
2706
+ visited.add(model);
2707
+ var detachedChildren = [];
2708
+ model.eachChild(function (child) {
2709
+ if (get(child, 'isDetached')) {
2710
+ detachedChildren.push(child);
2711
+ }
2712
+ }, this);
2713
+ var merged;
2981
2714
  if (get(model, 'hasErrors')) {
2982
- return this._mergeError(model, strategy);
2715
+ merged = this._mergeError(model, strategy);
2983
2716
  } else {
2984
- return this._mergeSuccess(model, strategy);
2717
+ merged = this._mergeSuccess(model, strategy);
2718
+ }
2719
+ for (var i = 0; i < detachedChildren.length; i++) {
2720
+ var child = detachedChildren[i];
2721
+ this.merge(child, strategy, visited);
2985
2722
  }
2723
+ return merged;
2986
2724
  },
2987
2725
  _mergeSuccess: function (model, strategy) {
2988
2726
  var models = get(this, 'models'), shadows = get(this, 'shadows'), newModels = get(this, 'newModels'), originals = get(this, 'originals'), merged, ancestor, existing = models.getModel(model);
@@ -3038,9 +2776,6 @@
3038
2776
  _mergeModel: function (dest, ancestor, model, strategy) {
3039
2777
  if (!strategy)
3040
2778
  strategy = get(this, 'mergeStrategy').create({ session: this });
3041
- if (model === dest) {
3042
- return model;
3043
- }
3044
2779
  if (get(model, 'isPromise')) {
3045
2780
  return this._mergePromise(dest, ancestor, model, strategy);
3046
2781
  }
@@ -3050,13 +2785,16 @@
3050
2785
  dest = dest.content;
3051
2786
  }
3052
2787
  if (!dest) {
3053
- dest = model.constructor.create();
2788
+ if (get(model, 'isDetached')) {
2789
+ dest = model;
2790
+ } else {
2791
+ dest = model.copy();
2792
+ }
2793
+ this.adopt(dest);
3054
2794
  if (promise) {
3055
2795
  promise.resolve(dest);
3056
2796
  }
3057
- }
3058
- if (!get(model, 'hasErrors')) {
3059
- set(dest, 'isNew', false);
2797
+ return dest;
3060
2798
  }
3061
2799
  set(dest, 'id', get(model, 'id'));
3062
2800
  set(dest, 'clientId', get(model, 'clientId'));
@@ -3075,7 +2813,11 @@
3075
2813
  return this._mergeModel(dest, ancestor, content, strategy);
3076
2814
  }
3077
2815
  if (!dest) {
3078
- dest = promise.lazyCopy();
2816
+ if (get(promise, 'isDetached')) {
2817
+ dest = promise;
2818
+ } else {
2819
+ dest = promise.lazyCopy();
2820
+ }
3079
2821
  this.adopt(dest);
3080
2822
  }
3081
2823
  return dest;
@@ -3118,74 +2860,41 @@
3118
2860
  }
3119
2861
  var model = type.create(hash);
3120
2862
  model = this.add(model);
3121
- model._registerRelationships();
3122
2863
  return model;
3123
2864
  },
3124
2865
  adopt: function (model) {
2866
+ Ember.assert('Cannot adopt a model with a clientId!', get(model, 'clientId'));
3125
2867
  Ember.assert('Models instances cannot be moved between sessions. Use `add` or `update` instead.', !get(model, 'session') || get(model, 'session') === this);
2868
+ Ember.assert('An equivalent model already exists in the session!', !this.getModel(model) || this.getModel(model) === model);
3126
2869
  set(model, 'session', this);
3127
2870
  if (get(model, 'isNew')) {
3128
2871
  this.newModels.add(model);
3129
2872
  }
3130
- this.models.add(model);
3131
- model._registerRelationships();
2873
+ if (!get(model, 'isProxy')) {
2874
+ this.models.add(model);
2875
+ model._registerRelationships();
2876
+ }
3132
2877
  return model;
3133
2878
  },
3134
- add: function (model, depth) {
2879
+ add: function (model) {
3135
2880
  this.reifyClientId(model);
3136
- var dest = this.getModel(model);
2881
+ var dest = this.fetch(model);
3137
2882
  if (dest && get(dest, 'isLoaded'))
3138
2883
  return dest;
3139
- if (typeof depth === 'undefined') {
3140
- depth = 2;
3141
- }
3142
- depth--;
3143
2884
  if (get(model, 'isProxy')) {
3144
2885
  var content = get(model, 'content');
3145
2886
  if (content) {
3146
2887
  return this.add(content);
3147
2888
  }
3148
- dest = model.lazyCopy();
3149
- return this.adopt(dest);
3150
2889
  }
3151
- if (get(model, 'isDetached')) {
2890
+ if (get(model, 'isNew') && get(model, 'isDetached')) {
3152
2891
  dest = model;
2892
+ } else if (get(model, 'isNew')) {
2893
+ dest = model.copy();
3153
2894
  } else {
3154
- dest = model.constructor.create();
3155
- model.copyAttributes(dest);
2895
+ dest = model.lazyCopy();
3156
2896
  }
3157
- this.adopt(dest);
3158
- model.eachRelationship(function (name, relationship) {
3159
- if (relationship.kind === 'belongsTo') {
3160
- var child = get(model, name);
3161
- if (child) {
3162
- if (get(child, 'session') === this) {
3163
- model.belongsToDidChange(model, name);
3164
- } else {
3165
- if (depth >= 0 || get(child, 'isDetached') || get(child, 'isNew')) {
3166
- child = this.add(child, depth);
3167
- } else {
3168
- child = child.lazyCopy();
3169
- }
3170
- dest.suspendRelationshipObservers(function () {
3171
- set(dest, name, child);
3172
- });
3173
- }
3174
- }
3175
- } else if (relationship.kind === 'hasMany') {
3176
- var children = get(model, name);
3177
- var copied = children.map(function (child) {
3178
- if (depth >= 0 || get(child, 'isDetached') || get(child, 'isNew')) {
3179
- child = this.add(child, depth);
3180
- } else {
3181
- child = child.lazyCopy();
3182
- }
3183
- return child;
3184
- }, this);
3185
- set(dest, name, copied);
3186
- }
3187
- }, this);
3188
- return dest;
2897
+ return this.adopt(dest);
3189
2898
  },
3190
2899
  remove: function (model) {
3191
2900
  get(this, 'models').remove(model);
@@ -3201,7 +2910,12 @@
3201
2910
  }
3202
2911
  throw new Ember.Error('Cannot update with an unloaded model: ' + model.toString());
3203
2912
  }
3204
- var dest = this.getModel(model);
2913
+ var dest = this.fetch(model);
2914
+ if (get(model, 'isNew') && !dest) {
2915
+ dest = get(model, 'type').create();
2916
+ set(dest, 'clientId', get(model, 'clientId'));
2917
+ this.adopt(dest);
2918
+ }
3205
2919
  if (get(model, 'isDetached') || !dest || !get(dest, 'isLoaded')) {
3206
2920
  return this.add(model);
3207
2921
  }
@@ -3212,6 +2926,7 @@
3212
2926
  return dest;
3213
2927
  }
3214
2928
  model.copyAttributes(dest);
2929
+ model.copyMeta(dest);
3215
2930
  model.eachRelationship(function (name, relationship) {
3216
2931
  if (relationship.kind === 'belongsTo') {
3217
2932
  var child = get(model, name);
@@ -3259,6 +2974,9 @@
3259
2974
  }
3260
2975
  return this.load(type, query);
3261
2976
  },
2977
+ fetch: function (model) {
2978
+ return this.getModel(model);
2979
+ },
3262
2980
  query: function (type, query) {
3263
2981
  if (typeof type === 'string') {
3264
2982
  type = this.lookupType(type);
@@ -3271,7 +2989,7 @@
3271
2989
  });
3272
2990
  set(merged, 'meta', get(models, 'meta'));
3273
2991
  models.forEach(function (model) {
3274
- merged.addObject(session.merge(model));
2992
+ merged.pushObject(session.merge(model));
3275
2993
  });
3276
2994
  return merged;
3277
2995
  });
@@ -3394,11 +3112,6 @@
3394
3112
  });
3395
3113
  require.define('/lib/session/merge_strategies/per_field.js', function (module, exports, __dirname, __filename) {
3396
3114
  var get = Ember.get, set = Ember.set, isEqual = Ember.isEqual;
3397
- function mergeIfPresent(session, model, strategy) {
3398
- if (!model)
3399
- return null;
3400
- return session.merge(model, strategy);
3401
- }
3402
3115
  Ep.PerField = Ep.MergeStrategy.extend({
3403
3116
  init: function () {
3404
3117
  this.cache = Ep.ModelSet.create();
@@ -3432,9 +3145,8 @@
3432
3145
  var oursValue = get(ours, name);
3433
3146
  var theirsValue = get(theirs, name);
3434
3147
  var originalValue = get(ancestor, name);
3435
- var merged = mergeIfPresent(session, theirsValue, this);
3436
3148
  if (isEqual(oursValue, originalValue)) {
3437
- set(ours, name, merged);
3149
+ set(ours, name, theirsValue);
3438
3150
  }
3439
3151
  } else if (relationship.kind === 'hasMany') {
3440
3152
  var theirChildren = get(theirs, name);
@@ -3445,17 +3157,12 @@
3445
3157
  existing.addObjects(ourChildren);
3446
3158
  theirChildren.forEach(function (model) {
3447
3159
  if (existing.contains(model)) {
3448
- session.merge(model, this);
3449
3160
  existing.remove(model);
3450
3161
  } else {
3451
- ourChildren.addObject(session.merge(model, this));
3162
+ ourChildren.pushObject(model);
3452
3163
  }
3453
3164
  }, this);
3454
3165
  ourChildren.removeObjects(existing);
3455
- } else {
3456
- theirChildren.forEach(function (model) {
3457
- session.merge(model, this);
3458
- }, this);
3459
3166
  }
3460
3167
  }
3461
3168
  }, this);
@@ -3465,15 +3172,10 @@
3465
3172
  require.define('/lib/session/merge_strategies/theirs.js', function (module, exports, __dirname, __filename) {
3466
3173
  var get = Ember.get, set = Ember.set;
3467
3174
  Ep.Theirs = Ep.MergeStrategy.extend({
3468
- init: function () {
3469
- this.cache = Ep.ModelSet.create();
3470
- },
3471
3175
  merge: function (dest, ancestor, model) {
3472
- if (this.cache.contains(model))
3473
- return dest;
3474
- this.cache.addObject(model);
3475
3176
  dest.beginPropertyChanges();
3476
3177
  this.copyAttributes(model, dest);
3178
+ this.copyMeta(model, dest);
3477
3179
  this.copyRelationships(model, dest);
3478
3180
  dest.endPropertyChanges();
3479
3181
  return dest;
@@ -3492,10 +3194,8 @@
3492
3194
  if (relationship.kind === 'belongsTo') {
3493
3195
  var child = get(model, name);
3494
3196
  var destChild = get(dest, name);
3495
- if (child && destChild) {
3496
- session.merge(child, this);
3497
- } else if (child) {
3498
- set(dest, name, session.merge(child, this));
3197
+ if (child) {
3198
+ set(dest, name, child);
3499
3199
  } else if (destChild) {
3500
3200
  set(dest, name, null);
3501
3201
  }
@@ -3503,14 +3203,13 @@
3503
3203
  var children = get(model, name);
3504
3204
  var destChildren = get(dest, name);
3505
3205
  var modelSet = Ep.ModelSet.create();
3506
- modelSet.addObjects(destChildren);
3206
+ modelSet.pushObjects(destChildren);
3507
3207
  set(destChildren, 'meta', get(children, 'meta'));
3508
3208
  children.forEach(function (child) {
3509
3209
  if (modelSet.contains(child)) {
3510
- session.merge(child, this);
3511
3210
  modelSet.remove(child);
3512
3211
  } else {
3513
- destChildren.addObject(session.merge(child, this));
3212
+ destChildren.addObject(child);
3514
3213
  }
3515
3214
  }, this);
3516
3215
  destChildren.removeObjects(modelSet);
@@ -3523,7 +3222,7 @@
3523
3222
  var get = Ember.get, set = Ember.set;
3524
3223
  function mustImplement(name) {
3525
3224
  return function () {
3526
- throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
3225
+ throw new Ember.Error('Your merge strategy ' + this.toString() + ' does not implement the required method ' + name);
3527
3226
  };
3528
3227
  }
3529
3228
  Ep.MergeStrategy = Ember.Object.extend({
@@ -3624,6 +3323,11 @@
3624
3323
  application.register('session:child', application.ChildSession || Ep.ChildSession, { singleton: false });
3625
3324
  application.register('session:main', application.DefaultSession || Ep.Session);
3626
3325
  application.register('serializer:main', application.Serializer || Ep.RestSerializer);
3326
+ require('/lib/transforms/index.js', module);
3327
+ application.register('transform:boolean', Ep.BooleanTransform);
3328
+ application.register('transform:date', Ep.DateTransform);
3329
+ application.register('transform:number', Ep.NumberTransform);
3330
+ application.register('transform:string', Ep.StringTransform);
3627
3331
  application.inject('adapter', 'serializer', 'serializer:main');
3628
3332
  application.inject('session', 'adapter', 'adapter:main');
3629
3333
  container.optionsForType('model', { instantiate: false });
@@ -3635,6 +3339,272 @@
3635
3339
  });
3636
3340
  });
3637
3341
  });
3342
+ require.define('/lib/version.js', function (module, exports, __dirname, __filename) {
3343
+ Ep.VERSION = '0.1.3';
3344
+ Ember.libraries && Ember.libraries.register('EPF', Ep.VERSION);
3345
+ });
3346
+ require.define('/vendor/ember-inflector.js', function (module, exports, __dirname, __filename) {
3347
+ (function () {
3348
+ Ember.INFLECTED_CLASSIFY = Ember.ENV.INFLECTED_CLASSIFY;
3349
+ if (typeof Ember.INFLECTED_CLASSIFY === 'undefined') {
3350
+ Ember.INFLECTED_CLASSIFY = false;
3351
+ }
3352
+ Ember.String.pluralize = function (word) {
3353
+ return Ember.Inflector.inflect(word, Ember.Inflector.rules.plurals);
3354
+ };
3355
+ Ember.String.singularize = function (word) {
3356
+ return Ember.Inflector.inflect(word, Ember.Inflector.rules.singular);
3357
+ };
3358
+ Ember.String.humanize = function (word) {
3359
+ var inflected = Ember.Inflector.inflect(word, Ember.Inflector.rules.humans);
3360
+ inflected = inflected.replace(Ember.Inflector.KEY_SUFFIX_REGEX, '');
3361
+ inflected = inflected.replace(Ember.Inflector.WHITESPACE_REGEX, ' ');
3362
+ inflected = inflected.replace(/_/g, ' ');
3363
+ return Ember.String.capitalize(inflected);
3364
+ };
3365
+ Ember.String.titleize = function (word) {
3366
+ var result = Ember.String.humanize(word);
3367
+ result = result.replace(/\b(?:<!['’`])[a-z]/).toLowerCase().replace(/^.|\s\S/g, function (a) {
3368
+ return a.toUpperCase();
3369
+ });
3370
+ return result;
3371
+ };
3372
+ Ember.String.capitalize = function (word) {
3373
+ return word.replace(Ember.Inflector.FIRST_LETTER_REGEX, function (match) {
3374
+ return match.toUpperCase();
3375
+ });
3376
+ };
3377
+ Ember.String.tableize = function (word) {
3378
+ return Ember.String.pluralize(Ember.String.underscore(word.toLowerCase()));
3379
+ };
3380
+ if (Ember.INFLECTED_CLASSIFY) {
3381
+ Ember.String.classify = function (word) {
3382
+ return Ember.String.capitalize(Ember.String.camelize(Ember.String.singularize(word)));
3383
+ };
3384
+ }
3385
+ }());
3386
+ (function () {
3387
+ Ember.Inflector = {
3388
+ FIRST_LETTER_REGEX: /^\w/,
3389
+ WHITESPACE_REGEX: /\s+/,
3390
+ KEY_SUFFIX_REGEX: /_id$/,
3391
+ BLANK_REGEX: /^\s*$/,
3392
+ _CACHE: {},
3393
+ cache: function (word, rules, value) {
3394
+ Ember.Inflector._CACHE[word] = Ember.Inflector._CACHE[word] || {};
3395
+ if (value) {
3396
+ Ember.Inflector._CACHE[word][rules] = value;
3397
+ }
3398
+ return Ember.Inflector._CACHE[word][rules];
3399
+ },
3400
+ clearCache: function () {
3401
+ Ember.Inflector._CACHE = {};
3402
+ },
3403
+ clearRules: function () {
3404
+ Ember.Inflector.rules.plurals = [];
3405
+ Ember.Inflector.rules.plurals = [];
3406
+ Ember.Inflector.rules.singular = [];
3407
+ Ember.Inflector.rules.humans = [];
3408
+ Ember.Inflector.rules.uncountable = {};
3409
+ Ember.Inflector.rules.irregular = {};
3410
+ Ember.Inflector.rules.irregularInverse = {};
3411
+ },
3412
+ rules: {
3413
+ plurals: [],
3414
+ singular: [],
3415
+ humans: [],
3416
+ irregular: {},
3417
+ irregularInverse: {},
3418
+ uncountable: {}
3419
+ },
3420
+ reset: function () {
3421
+ Ember.Inflector.clearCache();
3422
+ Ember.Inflector.clearRules();
3423
+ },
3424
+ plural: function (rule, substituion) {
3425
+ Ember.Inflector.rules.plurals.addObject([
3426
+ rule,
3427
+ substituion
3428
+ ]);
3429
+ },
3430
+ singular: function (rule, substituion) {
3431
+ Ember.Inflector.rules.singular.addObject([
3432
+ rule,
3433
+ substituion
3434
+ ]);
3435
+ },
3436
+ human: function (rule, substituion) {
3437
+ Ember.Inflector.rules.humans.addObject([
3438
+ rule,
3439
+ substituion
3440
+ ]);
3441
+ },
3442
+ irregular: function (rule, substituion) {
3443
+ Ember.Inflector.rules.irregular[rule] = substituion;
3444
+ Ember.Inflector.rules.irregularInverse[substituion] = rule;
3445
+ },
3446
+ uncountable: function (uncountable) {
3447
+ uncountable.forEach(function (word) {
3448
+ Ember.Inflector.rules.uncountable[word] = true;
3449
+ });
3450
+ },
3451
+ inflect: function (word, rules) {
3452
+ var inflection, substitution, result, lowercase, isCached, isIrregular, isIrregularInverse, rule;
3453
+ if (Ember.Inflector.BLANK_REGEX.test(word)) {
3454
+ return word;
3455
+ }
3456
+ lowercase = word.toLowerCase();
3457
+ isCached = Ember.Inflector.cache(lowercase, rules);
3458
+ if (isCached) {
3459
+ return isCached;
3460
+ }
3461
+ if (Ember.Inflector.rules.uncountable[lowercase]) {
3462
+ return word;
3463
+ }
3464
+ isIrregular = Ember.Inflector.rules.irregular[lowercase];
3465
+ if (isIrregular) {
3466
+ return isIrregular;
3467
+ }
3468
+ isIrregularInverse = Ember.Inflector.rules.irregularInverse[lowercase];
3469
+ if (isIrregularInverse) {
3470
+ return isIrregularInverse;
3471
+ }
3472
+ for (var i = rules.length, min = 0; i > min; i--) {
3473
+ inflection = rules[i - 1], rule = inflection[0];
3474
+ if (rule.test(word)) {
3475
+ break;
3476
+ }
3477
+ }
3478
+ inflection = inflection || [];
3479
+ rule = inflection[0];
3480
+ substitution = inflection[1];
3481
+ result = word.replace(rule, substitution);
3482
+ Ember.Inflector.cache(lowercase, rules, result);
3483
+ return result;
3484
+ }
3485
+ };
3486
+ }());
3487
+ (function () {
3488
+ Ember.Inflector.loadAll = function () {
3489
+ Ember.Inflector.plural(/$/, 's');
3490
+ Ember.Inflector.plural(/s$/i, 's');
3491
+ Ember.Inflector.plural(/^(ax|test)is$/i, '$1es');
3492
+ Ember.Inflector.plural(/(octop|vir)us$/i, '$1i');
3493
+ Ember.Inflector.plural(/(octop|vir)i$/i, '$1i');
3494
+ Ember.Inflector.plural(/(alias|status)$/i, '$1es');
3495
+ Ember.Inflector.plural(/(bu)s$/i, '$1ses');
3496
+ Ember.Inflector.plural(/(buffal|tomat)o$/i, '$1oes');
3497
+ Ember.Inflector.plural(/([ti])um$/i, '$1a');
3498
+ Ember.Inflector.plural(/([ti])a$/i, '$1a');
3499
+ Ember.Inflector.plural(/sis$/i, 'ses');
3500
+ Ember.Inflector.plural(/(?:([^f])fe|([lr])f)$/i, '$1$2ves');
3501
+ Ember.Inflector.plural(/(hive)$/i, '$1s');
3502
+ Ember.Inflector.plural(/([^aeiouy]|qu)y$/i, '$1ies');
3503
+ Ember.Inflector.plural(/(x|ch|ss|sh)$/i, '$1es');
3504
+ Ember.Inflector.plural(/(matr|vert|ind)(?:ix|ex)$/i, '$1ices');
3505
+ Ember.Inflector.plural(/^(m|l)ouse$/i, '$1ice');
3506
+ Ember.Inflector.plural(/^(m|l)ice$/i, '$1ice');
3507
+ Ember.Inflector.plural(/^(ox)$/i, '$1en');
3508
+ Ember.Inflector.plural(/^(oxen)$/i, '$1');
3509
+ Ember.Inflector.plural(/(quiz)$/i, '$1zes');
3510
+ Ember.Inflector.singular(/s$/i, '');
3511
+ Ember.Inflector.singular(/(ss)$/i, '$1');
3512
+ Ember.Inflector.singular(/(n)ews$/i, '$1ews');
3513
+ Ember.Inflector.singular(/([ti])a$/i, '$1um');
3514
+ Ember.Inflector.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '$1sis');
3515
+ Ember.Inflector.singular(/(^analy)(sis|ses)$/i, '$1sis');
3516
+ Ember.Inflector.singular(/([^f])ves$/i, '$1fe');
3517
+ Ember.Inflector.singular(/(hive)s$/i, '$1');
3518
+ Ember.Inflector.singular(/(tive)s$/i, '$1');
3519
+ Ember.Inflector.singular(/([lr])ves$/i, '$1f');
3520
+ Ember.Inflector.singular(/([^aeiouy]|qu)ies$/i, '$1y');
3521
+ Ember.Inflector.singular(/(s)eries$/i, '$1eries');
3522
+ Ember.Inflector.singular(/(m)ovies$/i, '$1ovie');
3523
+ Ember.Inflector.singular(/(x|ch|ss|sh)es$/i, '$1');
3524
+ Ember.Inflector.singular(/^(m|l)ice$/i, '$1ouse');
3525
+ Ember.Inflector.singular(/(bus)(es)?$/i, '$1');
3526
+ Ember.Inflector.singular(/(o)es$/i, '$1');
3527
+ Ember.Inflector.singular(/(shoe)s$/i, '$1');
3528
+ Ember.Inflector.singular(/(cris|test)(is|es)$/i, '$1is');
3529
+ Ember.Inflector.singular(/^(a)x[ie]s$/i, '$1xis');
3530
+ Ember.Inflector.singular(/(octop|vir)(us|i)$/i, '$1us');
3531
+ Ember.Inflector.singular(/(alias|status)(es)?$/i, '$1');
3532
+ Ember.Inflector.singular(/^(ox)en/i, '$1');
3533
+ Ember.Inflector.singular(/(vert|ind)ices$/i, '$1ex');
3534
+ Ember.Inflector.singular(/(matr)ices$/i, '$1ix');
3535
+ Ember.Inflector.singular(/(quiz)zes$/i, '$1');
3536
+ Ember.Inflector.singular(/(database)s$/i, '$1');
3537
+ Ember.Inflector.irregular('person', 'people');
3538
+ Ember.Inflector.irregular('man', 'men');
3539
+ Ember.Inflector.irregular('child', 'children');
3540
+ Ember.Inflector.irregular('sex', 'sexes');
3541
+ Ember.Inflector.irregular('move', 'moves');
3542
+ Ember.Inflector.irregular('cow', 'kine');
3543
+ Ember.Inflector.irregular('zombie', 'zombies');
3544
+ Ember.Inflector.uncountable('equipment information rice money species series fish sheep jeans police'.w());
3545
+ };
3546
+ }());
3547
+ (function () {
3548
+ Ember.Inflector.rules.ordinalization = {
3549
+ 'default': 'th',
3550
+ 0: '',
3551
+ 1: 'st',
3552
+ 2: 'nd',
3553
+ 3: 'rd',
3554
+ 11: 'th',
3555
+ 12: 'th',
3556
+ 13: 'th'
3557
+ };
3558
+ Ember.Inflector.ordinal = function (number) {
3559
+ number = parseInt(number, 10);
3560
+ number = Math.abs(number);
3561
+ if (number > 10 && number < 14) {
3562
+ number %= 100;
3563
+ } else {
3564
+ number %= 10;
3565
+ }
3566
+ var ordinalization = Ember.Inflector.rules.ordinalization;
3567
+ return ordinalization[number] || ordinalization['default'];
3568
+ };
3569
+ Ember.String.ordinalize = function (word) {
3570
+ var ordinalization = Ember.Inflector.ordinal(word);
3571
+ return [
3572
+ word,
3573
+ ordinalization
3574
+ ].join('');
3575
+ };
3576
+ }());
3577
+ (function () {
3578
+ var pluralize = Ember.String.pluralize, singularize = Ember.String.singularize, humanize = Ember.String.humanize, titleize = Ember.String.titleize, capitalize = Ember.String.capitalize, tableize = Ember.String.tableize, classify = Ember.String.classify;
3579
+ if (Ember.EXTEND_PROTOTYPES) {
3580
+ String.prototype.pluralize = function () {
3581
+ return pluralize(this, arguments);
3582
+ };
3583
+ String.prototype.singularize = function () {
3584
+ return singularize(this, arguments);
3585
+ };
3586
+ String.prototype.humanize = function () {
3587
+ return humanize(this, arguments);
3588
+ };
3589
+ String.prototype.titleize = function () {
3590
+ return titleize(this, arguments);
3591
+ };
3592
+ String.prototype.capitalize = function () {
3593
+ return capitalize(this, arguments);
3594
+ };
3595
+ String.prototype.tableize = function () {
3596
+ return tableize(this, arguments);
3597
+ };
3598
+ String.prototype.classify = function () {
3599
+ return classify(this, arguments);
3600
+ };
3601
+ }
3602
+ }());
3603
+ (function () {
3604
+ }());
3605
+ (function () {
3606
+ }());
3607
+ });
3638
3608
  global.epf = require('/lib/index.js');
3639
3609
  }.call(this, this));
3640
3610
  /*