activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chir...@apache.org
Subject svn commit: r1424630 [7/10] - in /activemq/activemq-apollo/trunk/apollo-web: ./ src/main/less/ src/main/webapp/WEB-INF/ src/main/webapp/console/ src/main/webapp/console/css/ src/main/webapp/console/font/ src/main/webapp/console/js/
Date Thu, 20 Dec 2012 18:37:46 GMT
Added: activemq/activemq-apollo/trunk/apollo-web/src/main/webapp/console/js/ember-1.0.0-pre.2.js
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-web/src/main/webapp/console/js/ember-1.0.0-pre.2.js?rev=1424630&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-web/src/main/webapp/console/js/ember-1.0.0-pre.2.js (added)
+++ activemq/activemq-apollo/trunk/apollo-web/src/main/webapp/console/js/ember-1.0.0-pre.2.js Thu Dec 20 18:37:45 2012
@@ -0,0 +1,23162 @@
+// Version: v1.0.0-pre.2-1-gd1a2e84
+// Last commit: d1a2e84 (2012-10-25 13:51:08 -0700)
+
+
+(function() {
+/*global __fail__*/
+
+/**
+Ember Debug
+
+@module ember
+@submodule ember-debug
+*/
+
+/**
+@class Ember
+*/
+
+if ('undefined' === typeof Ember) {
+  Ember = {};
+
+  if ('undefined' !== typeof window) {
+    window.Em = window.Ember = Em = Ember;
+  }
+}
+
+Ember.ENV = 'undefined' === typeof ENV ? {} : ENV;
+
+if (!('MANDATORY_SETTER' in Ember.ENV)) {
+  Ember.ENV.MANDATORY_SETTER = true; // default to true for debug dist
+}
+
+/**
+  Define an assertion that will throw an exception if the condition is not
+  met.  Ember build tools will remove any calls to Ember.assert() when
+  doing a production build. Example:
+
+      // Test for truthiness
+      Ember.assert('Must pass a valid object', obj);
+      // Fail unconditionally
+      Ember.assert('This code path should never be run')
+
+  @method assert
+  @param {String} desc A description of the assertion.  This will become
+    the text of the Error thrown if the assertion fails.
+
+  @param {Boolean} test Must be truthy for the assertion to pass. If
+    falsy, an exception will be thrown.
+*/
+Ember.assert = function(desc, test) {
+  if (!test) throw new Error("assertion failed: "+desc);
+};
+
+
+/**
+  Display a warning with the provided message. Ember build tools will
+  remove any calls to Ember.warn() when doing a production build.
+
+  @method warn
+  @param {String} message A warning to display.
+  @param {Boolean} test An optional boolean. If falsy, the warning
+    will be displayed.
+*/
+Ember.warn = function(message, test) {
+  if (!test) {
+    Ember.Logger.warn("WARNING: "+message);
+    if ('trace' in Ember.Logger) Ember.Logger.trace();
+  }
+};
+
+/**
+  Display a deprecation warning with the provided message and a stack trace
+  (Chrome and Firefox only). Ember build tools will remove any calls to
+  Ember.deprecate() when doing a production build.
+
+  @method deprecate
+  @param {String} message A description of the deprecation.
+  @param {Boolean} test An optional boolean. If falsy, the deprecation
+    will be displayed.
+*/
+Ember.deprecate = function(message, test) {
+  if (Ember && Ember.TESTING_DEPRECATION) { return; }
+
+  if (arguments.length === 1) { test = false; }
+  if (test) { return; }
+
+  if (Ember && Ember.ENV.RAISE_ON_DEPRECATION) { throw new Error(message); }
+
+  var error;
+
+  // When using new Error, we can't do the arguments check for Chrome. Alternatives are welcome
+  try { __fail__.fail(); } catch (e) { error = e; }
+
+  if (Ember.LOG_STACKTRACE_ON_DEPRECATION && error.stack) {
+    var stack, stackStr = '';
+    if (error['arguments']) {
+      // Chrome
+      stack = error.stack.replace(/^\s+at\s+/gm, '').
+                          replace(/^([^\(]+?)([\n$])/gm, '{anonymous}($1)$2').
+                          replace(/^Object.<anonymous>\s*\(([^\)]+)\)/gm, '{anonymous}($1)').split('\n');
+      stack.shift();
+    } else {
+      // Firefox
+      stack = error.stack.replace(/(?:\n@:0)?\s+$/m, '').
+                          replace(/^\(/gm, '{anonymous}(').split('\n');
+    }
+
+    stackStr = "\n    " + stack.slice(2).join("\n    ");
+    message = message + stackStr;
+  }
+
+  Ember.Logger.warn("DEPRECATION: "+message);
+};
+
+
+
+/**
+  Display a deprecation warning with the provided message and a stack trace
+  (Chrome and Firefox only) when the wrapped method is called.
+
+  Ember build tools will not remove calls to Ember.deprecateFunc(), though
+  no warnings will be shown in production.
+
+  @method deprecateFunc
+  @param {String} message A description of the deprecation.
+  @param {Function} func The function to be deprecated.
+*/
+Ember.deprecateFunc = function(message, func) {
+  return function() {
+    Ember.deprecate(message);
+    return func.apply(this, arguments);
+  };
+};
+
+
+window.ember_assert         = Ember.deprecateFunc("ember_assert is deprecated. Please use Ember.assert instead.",               Ember.assert);
+window.ember_warn           = Ember.deprecateFunc("ember_warn is deprecated. Please use Ember.warn instead.",                   Ember.warn);
+window.ember_deprecate      = Ember.deprecateFunc("ember_deprecate is deprecated. Please use Ember.deprecate instead.",         Ember.deprecate);
+window.ember_deprecateFunc  = Ember.deprecateFunc("ember_deprecateFunc is deprecated. Please use Ember.deprecateFunc instead.", Ember.deprecateFunc);
+
+})();
+
+// Version: v1.0.0-pre.2-1-gd1a2e84
+// Last commit: d1a2e84 (2012-10-25 13:51:08 -0700)
+
+
+(function() {
+/*globals Em:true ENV */
+
+/**
+@module ember
+@submodule ember-metal
+*/
+
+/**
+  All Ember methods and functions are defined inside of this namespace.
+  You generally should not add new properties to this namespace as it may be
+  overwritten by future versions of Ember.
+
+  You can also use the shorthand "Em" instead of "Ember".
+
+  Ember-Runtime is a framework that provides core functions for
+  Ember including cross-platform functions, support for property
+  observing and objects. Its focus is on small size and performance. You can
+  use this in place of or along-side other cross-platform libraries such as
+  jQuery.
+
+  The core Runtime framework is based on the jQuery API with a number of
+  performance optimizations.
+
+  @class Ember
+  @static
+  @version 1.0.0-pre.2
+*/
+
+if ('undefined' === typeof Ember) {
+  // Create core object. Make it act like an instance of Ember.Namespace so that
+  // objects assigned to it are given a sane string representation.
+  Ember = {};
+}
+
+// Default imports, exports and lookup to the global object;
+var imports = Ember.imports = Ember.imports || this;
+var exports = Ember.exports = Ember.exports || this;
+var lookup  = Ember.lookup  = Ember.lookup  || this;
+
+// aliases needed to keep minifiers from removing the global context
+exports.Em = exports.Ember = Em = Ember;
+
+// Make sure these are set whether Ember was already defined or not
+
+Ember.isNamespace = true;
+
+Ember.toString = function() { return "Ember"; };
+
+
+/**
+  @property VERSION
+  @type String
+  @default '1.0.0-pre.2'
+  @final
+*/
+Ember.VERSION = '1.0.0-pre.2';
+
+/**
+  Standard environmental variables.  You can define these in a global `ENV`
+  variable before loading Ember to control various configuration
+  settings.
+
+  @property ENV
+  @type Hash
+*/
+Ember.ENV = Ember.ENV || ('undefined' === typeof ENV ? {} : ENV);
+
+Ember.config = Ember.config || {};
+
+// ..........................................................
+// BOOTSTRAP
+//
+
+/**
+  Determines whether Ember should enhances some built-in object
+  prototypes to provide a more friendly API.  If enabled, a few methods
+  will be added to Function, String, and Array.  Object.prototype will not be
+  enhanced, which is the one that causes most trouble for people.
+
+  In general we recommend leaving this option set to true since it rarely
+  conflicts with other code.  If you need to turn it off however, you can
+  define an ENV.EXTEND_PROTOTYPES config to disable it.
+
+  @property EXTEND_PROTOTYPES
+  @type Boolean
+  @default true
+*/
+Ember.EXTEND_PROTOTYPES = Ember.ENV.EXTEND_PROTOTYPES;
+
+if (typeof Ember.EXTEND_PROTOTYPES === 'undefined') {
+  Ember.EXTEND_PROTOTYPES = true;
+}
+
+/**
+  Determines whether Ember logs a full stack trace during deprecation warnings
+
+  @property LOG_STACKTRACE_ON_DEPRECATION
+  @type Boolean
+  @default true
+*/
+Ember.LOG_STACKTRACE_ON_DEPRECATION = (Ember.ENV.LOG_STACKTRACE_ON_DEPRECATION !== false);
+
+/**
+  Determines whether Ember should add ECMAScript 5 shims to older browsers.
+
+  @property SHIM_ES5
+  @type Boolean
+  @default Ember.EXTEND_PROTOTYPES
+*/
+Ember.SHIM_ES5 = (Ember.ENV.SHIM_ES5 === false) ? false : Ember.EXTEND_PROTOTYPES;
+
+/**
+  Empty function.  Useful for some operations.
+
+  @method K
+  @private
+  @return {Object}
+*/
+Ember.K = function() { return this; };
+
+
+// Stub out the methods defined by the ember-debug package in case it's not loaded
+
+if ('undefined' === typeof Ember.assert) { Ember.assert = Ember.K; }
+if ('undefined' === typeof Ember.warn) { Ember.warn = Ember.K; }
+if ('undefined' === typeof Ember.deprecate) { Ember.deprecate = Ember.K; }
+if ('undefined' === typeof Ember.deprecateFunc) {
+  Ember.deprecateFunc = function(_, func) { return func; };
+}
+
+// These are deprecated but still supported
+
+if ('undefined' === typeof ember_assert) { exports.ember_assert = Ember.K; }
+if ('undefined' === typeof ember_warn) { exports.ember_warn = Ember.K; }
+if ('undefined' === typeof ember_deprecate) { exports.ember_deprecate = Ember.K; }
+if ('undefined' === typeof ember_deprecateFunc) {
+  exports.ember_deprecateFunc = function(_, func) { return func; };
+}
+
+/**
+  Previously we used `Ember.$.uuid`, however `$.uuid` has been removed from jQuery master.
+  We'll just bootstrap our own uuid now.
+
+  @property uuid
+  @type Number
+  @private
+*/
+Ember.uuid = 0;
+
+// ..........................................................
+// LOGGER
+//
+
+/**
+  Inside Ember-Metal, simply uses the imports.console object.
+  Override this to provide more robust logging functionality.
+
+  @class Logger
+  @namespace Ember
+*/
+Ember.Logger = imports.console || { log: Ember.K, warn: Ember.K, error: Ember.K, info: Ember.K, debug: Ember.K };
+
+
+// ..........................................................
+// ERROR HANDLING
+//
+
+/**
+  A function may be assigned to `Ember.onerror` to be called when Ember internals encounter an error.
+  This is useful for specialized error handling and reporting code.
+
+  @event onerror
+  @for Ember
+  @param {Exception} error the error object
+*/
+Ember.onerror = null;
+
+/**
+  @private
+
+  Wrap code block in a try/catch if {{#crossLink "Ember/onerror"}}{{/crossLink}} is set.
+
+  @method handleErrors
+  @for Ember
+  @param {Function} func
+  @param [context]
+*/
+Ember.handleErrors = function(func, context) {
+  // Unfortunately in some browsers we lose the backtrace if we rethrow the existing error,
+  // so in the event that we don't have an `onerror` handler we don't wrap in a try/catch
+  if ('function' === typeof Ember.onerror) {
+    try {
+      return func.apply(context || this);
+    } catch (error) {
+      Ember.onerror(error);
+    }
+  } else {
+    return func.apply(context || this);
+  }
+};
+
+})();
+
+
+
+(function() {
+/**
+  The purpose of the Ember Instrumentation module is
+  to provide efficient, general-purpose instrumentation
+  for Ember.
+
+  Subscribe to a listener by using `Ember.subscribe`:
+
+      Ember.subscribe("render", {
+        before: function(name, timestamp, payload) {
+
+        },
+
+        after: function(name, timestamp, payload) {
+
+        }
+      });
+
+  If you return a value from the `before` callback, that same
+  value will be passed as a fourth parameter to the `after`
+  callback.
+
+  Instrument a block of code by using `Ember.instrument`:
+
+      Ember.instrument("render.handlebars", payload, function() {
+        // rendering logic
+      }, binding);
+
+  Event names passed to `Ember.instrument` are namespaced
+  by periods, from more general to more specific. Subscribers
+  can listen for events by whatever level of granularity they
+  are interested in.
+
+  In the above example, the event is `render.handlebars`,
+  and the subscriber listened for all events beginning with
+  `render`. It would receive callbacks for events named
+  `render`, `render.handlebars`, `render.container`, or
+  even `render.handlebars.layout`.
+
+  @class Instrumentation
+  @namespace Ember
+  @static
+*/
+Ember.Instrumentation = {};
+
+var subscribers = [], cache = {};
+
+var populateListeners = function(name) {
+  var listeners = [], subscriber;
+
+  for (var i=0, l=subscribers.length; i<l; i++) {
+    subscriber = subscribers[i];
+    if (subscriber.regex.test(name)) {
+      listeners.push(subscriber.object);
+    }
+  }
+
+  cache[name] = listeners;
+  return listeners;
+};
+
+var time = (function() {
+	var perf = window.performance || {};
+	var fn = perf.now || perf.mozNow || perf.webkitNow || perf.msNow || perf.oNow;
+	// fn.bind will be available in all the browsers that support the advanced window.performance... ;-)
+	return fn ? fn.bind(perf) : function() { return +new Date(); };
+})();
+
+
+Ember.Instrumentation.instrument = function(name, payload, callback, binding) {
+  var listeners = cache[name];
+
+  if (!listeners) {
+    listeners = populateListeners(name);
+  }
+
+  if (listeners.length === 0) { return callback.call(binding); }
+
+  var beforeValues = [], listener, ret, i, l;
+
+  try {
+    for (i=0, l=listeners.length; i<l; i++) {
+      listener = listeners[i];
+      beforeValues[i] = listener.before(name, time(), payload);
+    }
+
+    ret = callback.call(binding);
+  } catch(e) {
+    payload = payload || {};
+    payload.exception = e;
+  } finally {
+    for (i=0, l=listeners.length; i<l; i++) {
+      listener = listeners[i];
+      listener.after(name, time(), payload, beforeValues[i]);
+    }
+  }
+
+  return ret;
+};
+
+Ember.Instrumentation.subscribe = function(pattern, object) {
+  var paths = pattern.split("."), path, regex = [];
+
+  for (var i=0, l=paths.length; i<l; i++) {
+    path = paths[i];
+    if (path === "*") {
+      regex.push("[^\\.]*");
+    } else {
+      regex.push(path);
+    }
+  }
+
+  regex = regex.join("\\.");
+  regex = regex + "(\\..*)?";
+
+  var subscriber = {
+    pattern: pattern,
+    regex: new RegExp("^" + regex + "$"),
+    object: object
+  };
+
+  subscribers.push(subscriber);
+  cache = {};
+
+  return subscriber;
+};
+
+Ember.Instrumentation.unsubscribe = function(subscriber) {
+  var index;
+
+  for (var i=0, l=subscribers.length; i<l; i++) {
+    if (subscribers[i] === subscriber) {
+      index = i;
+    }
+  }
+
+  subscribers.splice(index, 1);
+  cache = {};
+};
+
+Ember.Instrumentation.reset = function() {
+  subscribers = [];
+  cache = {};
+};
+
+Ember.instrument = Ember.Instrumentation.instrument;
+Ember.subscribe = Ember.Instrumentation.subscribe;
+
+})();
+
+
+
+(function() {
+/*jshint newcap:false*/
+
+/**
+@module ember-metal
+*/
+
+// NOTE: There is a bug in jshint that doesn't recognize `Object()` without `new`
+// as being ok unless both `newcap:false` and not `use strict`.
+// https://github.com/jshint/jshint/issues/392
+
+// Testing this is not ideal, but we want to use native functions
+// if available, but not to use versions created by libraries like Prototype
+var isNativeFunc = function(func) {
+  // This should probably work in all browsers likely to have ES5 array methods
+  return func && Function.prototype.toString.call(func).indexOf('[native code]') > -1;
+};
+
+// From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/map
+var arrayMap = isNativeFunc(Array.prototype.map) ? Array.prototype.map : function(fun /*, thisp */) {
+  //"use strict";
+
+  if (this === void 0 || this === null) {
+    throw new TypeError();
+  }
+
+  var t = Object(this);
+  var len = t.length >>> 0;
+  if (typeof fun !== "function") {
+    throw new TypeError();
+  }
+
+  var res = new Array(len);
+  var thisp = arguments[1];
+  for (var i = 0; i < len; i++) {
+    if (i in t) {
+      res[i] = fun.call(thisp, t[i], i, t);
+    }
+  }
+
+  return res;
+};
+
+// From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach
+var arrayForEach = isNativeFunc(Array.prototype.forEach) ? Array.prototype.forEach : function(fun /*, thisp */) {
+  //"use strict";
+
+  if (this === void 0 || this === null) {
+    throw new TypeError();
+  }
+
+  var t = Object(this);
+  var len = t.length >>> 0;
+  if (typeof fun !== "function") {
+    throw new TypeError();
+  }
+
+  var thisp = arguments[1];
+  for (var i = 0; i < len; i++) {
+    if (i in t) {
+      fun.call(thisp, t[i], i, t);
+    }
+  }
+};
+
+var arrayIndexOf = isNativeFunc(Array.prototype.indexOf) ? Array.prototype.indexOf : function (obj, fromIndex) {
+  if (fromIndex === null || fromIndex === undefined) { fromIndex = 0; }
+  else if (fromIndex < 0) { fromIndex = Math.max(0, this.length + fromIndex); }
+  for (var i = fromIndex, j = this.length; i < j; i++) {
+    if (this[i] === obj) { return i; }
+  }
+  return -1;
+};
+
+Ember.ArrayPolyfills = {
+  map: arrayMap,
+  forEach: arrayForEach,
+  indexOf: arrayIndexOf
+};
+
+var utils = Ember.EnumerableUtils = {
+  map: function(obj, callback, thisArg) {
+    return obj.map ? obj.map.call(obj, callback, thisArg) : arrayMap.call(obj, callback, thisArg);
+  },
+
+  forEach: function(obj, callback, thisArg) {
+    return obj.forEach ? obj.forEach.call(obj, callback, thisArg) : arrayForEach.call(obj, callback, thisArg);
+  },
+
+  indexOf: function(obj, element, index) {
+    return obj.indexOf ? obj.indexOf.call(obj, element, index) : arrayIndexOf.call(obj, element, index);
+  },
+
+  indexesOf: function(obj, elements) {
+    return elements === undefined ? [] : utils.map(elements, function(item) {
+      return utils.indexOf(obj, item);
+    });
+  },
+
+  removeObject: function(array, item) {
+    var index = utils.indexOf(array, item);
+    if (index !== -1) { array.splice(index, 1); }
+  },
+
+  replace: function(array, idx, amt, objects) {
+    if (array.replace) {
+      return array.replace(idx, amt, objects);
+    } else {
+      var args = Array.prototype.concat.apply([idx, amt], objects);
+      return array.splice.apply(array, args);
+    }
+  }
+};
+
+
+if (Ember.SHIM_ES5) {
+  if (!Array.prototype.map) {
+    Array.prototype.map = arrayMap;
+  }
+
+  if (!Array.prototype.forEach) {
+    Array.prototype.forEach = arrayForEach;
+  }
+
+  if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = arrayIndexOf;
+  }
+}
+
+})();
+
+
+
+(function() {
+/*globals Node */
+/**
+@module ember-metal
+*/
+
+/**
+  Platform specific methods and feature detectors needed by the framework.
+
+  @class platform
+  @namespace Ember
+  @static
+*/
+var platform = Ember.platform = {};
+
+
+/**
+  Identical to Object.create().  Implements if not available natively.
+  @method create
+  @for Ember
+*/
+Ember.create = Object.create;
+
+if (!Ember.create) {
+  var K = function() {};
+
+  Ember.create = function(obj, props) {
+    K.prototype = obj;
+    obj = new K();
+    if (props) {
+      K.prototype = obj;
+      for (var prop in props) {
+        K.prototype[prop] = props[prop].value;
+      }
+      obj = new K();
+    }
+    K.prototype = null;
+
+    return obj;
+  };
+
+  Ember.create.isSimulated = true;
+}
+
+var defineProperty = Object.defineProperty;
+var canRedefineProperties, canDefinePropertyOnDOM;
+
+// Catch IE8 where Object.defineProperty exists but only works on DOM elements
+if (defineProperty) {
+  try {
+    defineProperty({}, 'a',{get:function(){}});
+  } catch (e) {
+    defineProperty = null;
+  }
+}
+
+if (defineProperty) {
+  // Detects a bug in Android <3.2 where you cannot redefine a property using
+  // Object.defineProperty once accessors have already been set.
+  canRedefineProperties = (function() {
+    var obj = {};
+
+    defineProperty(obj, 'a', {
+      configurable: true,
+      enumerable: true,
+      get: function() { },
+      set: function() { }
+    });
+
+    defineProperty(obj, 'a', {
+      configurable: true,
+      enumerable: true,
+      writable: true,
+      value: true
+    });
+
+    return obj.a === true;
+  })();
+
+  // This is for Safari 5.0, which supports Object.defineProperty, but not
+  // on DOM nodes.
+  canDefinePropertyOnDOM = (function(){
+    try {
+      defineProperty(document.createElement('div'), 'definePropertyOnDOM', {});
+      return true;
+    } catch(e) { }
+
+    return false;
+  })();
+
+  if (!canRedefineProperties) {
+    defineProperty = null;
+  } else if (!canDefinePropertyOnDOM) {
+    defineProperty = function(obj, keyName, desc){
+      var isNode;
+
+      if (typeof Node === "object") {
+        isNode = obj instanceof Node;
+      } else {
+        isNode = typeof obj === "object" && typeof obj.nodeType === "number" && typeof obj.nodeName === "string";
+      }
+
+      if (isNode) {
+        // TODO: Should we have a warning here?
+        return (obj[keyName] = desc.value);
+      } else {
+        return Object.defineProperty(obj, keyName, desc);
+      }
+    };
+  }
+}
+
+/**
+@class platform
+@namespace Ember
+*/
+
+/**
+  Identical to Object.defineProperty().  Implements as much functionality
+  as possible if not available natively.
+
+  @method defineProperty
+  @param {Object} obj The object to modify
+  @param {String} keyName property name to modify
+  @param {Object} desc descriptor hash
+  @return {void}
+*/
+platform.defineProperty = defineProperty;
+
+/**
+  Set to true if the platform supports native getters and setters.
+
+  @property hasPropertyAccessors
+  @final
+*/
+platform.hasPropertyAccessors = true;
+
+if (!platform.defineProperty) {
+  platform.hasPropertyAccessors = false;
+
+  platform.defineProperty = function(obj, keyName, desc) {
+    if (!desc.get) { obj[keyName] = desc.value; }
+  };
+
+  platform.defineProperty.isSimulated = true;
+}
+
+if (Ember.ENV.MANDATORY_SETTER && !platform.hasPropertyAccessors) {
+  Ember.ENV.MANDATORY_SETTER = false;
+}
+
+})();
+
+
+
+(function() {
+/**
+@module ember-metal
+*/
+
+var o_defineProperty = Ember.platform.defineProperty,
+    o_create = Ember.create,
+    // Used for guid generation...
+    GUID_KEY = '__ember'+ (+ new Date()),
+    uuid         = 0,
+    numberCache  = [],
+    stringCache  = {};
+
+var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
+
+/**
+  @private
+
+  A unique key used to assign guids and other private metadata to objects.
+  If you inspect an object in your browser debugger you will often see these.
+  They can be safely ignored.
+
+  On browsers that support it, these properties are added with enumeration
+  disabled so they won't show up when you iterate over your properties.
+
+  @property GUID_KEY
+  @for Ember
+  @type String
+  @final
+*/
+Ember.GUID_KEY = GUID_KEY;
+
+var GUID_DESC = {
+  writable:    false,
+  configurable: false,
+  enumerable:  false,
+  value: null
+};
+
+/**
+  @private
+
+  Generates a new guid, optionally saving the guid to the object that you
+  pass in.  You will rarely need to use this method.  Instead you should
+  call Ember.guidFor(obj), which return an existing guid if available.
+
+  @method generateGuid
+  @for Ember
+  @param {Object} [obj] Object the guid will be used for.  If passed in, the guid will
+    be saved on the object and reused whenever you pass the same object
+    again.
+
+    If no object is passed, just generate a new guid.
+
+  @param {String} [prefix] Prefix to place in front of the guid.  Useful when you want to
+    separate the guid into separate namespaces.
+
+  @return {String} the guid
+*/
+Ember.generateGuid = function generateGuid(obj, prefix) {
+  if (!prefix) prefix = 'ember';
+  var ret = (prefix + (uuid++));
+  if (obj) {
+    GUID_DESC.value = ret;
+    o_defineProperty(obj, GUID_KEY, GUID_DESC);
+  }
+  return ret ;
+};
+
+/**
+  @private
+
+  Returns a unique id for the object.  If the object does not yet have
+  a guid, one will be assigned to it.  You can call this on any object,
+  Ember.Object-based or not, but be aware that it will add a _guid property.
+
+  You can also use this method on DOM Element objects.
+
+  @method guidFor
+  @for Ember
+  @param obj {Object} any object, string, number, Element, or primitive
+  @return {String} the unique guid for this instance.
+*/
+Ember.guidFor = function guidFor(obj) {
+
+  // special cases where we don't want to add a key to object
+  if (obj === undefined) return "(undefined)";
+  if (obj === null) return "(null)";
+
+  var cache, ret;
+  var type = typeof obj;
+
+  // Don't allow prototype changes to String etc. to change the guidFor
+  switch(type) {
+    case 'number':
+      ret = numberCache[obj];
+      if (!ret) ret = numberCache[obj] = 'nu'+obj;
+      return ret;
+
+    case 'string':
+      ret = stringCache[obj];
+      if (!ret) ret = stringCache[obj] = 'st'+(uuid++);
+      return ret;
+
+    case 'boolean':
+      return obj ? '(true)' : '(false)';
+
+    default:
+      if (obj[GUID_KEY]) return obj[GUID_KEY];
+      if (obj === Object) return '(Object)';
+      if (obj === Array)  return '(Array)';
+      ret = 'ember'+(uuid++);
+      GUID_DESC.value = ret;
+      o_defineProperty(obj, GUID_KEY, GUID_DESC);
+      return ret;
+  }
+};
+
+// ..........................................................
+// META
+//
+
+var META_DESC = {
+  writable:    true,
+  configurable: false,
+  enumerable:  false,
+  value: null
+};
+
+var META_KEY = Ember.GUID_KEY+'_meta';
+
+/**
+  The key used to store meta information on object for property observing.
+
+  @property META_KEY
+  @for Ember
+  @private
+  @final
+  @type String
+*/
+Ember.META_KEY = META_KEY;
+
+// Placeholder for non-writable metas.
+var EMPTY_META = {
+  descs: {},
+  watching: {}
+};
+
+if (MANDATORY_SETTER) { EMPTY_META.values = {}; }
+
+Ember.EMPTY_META = EMPTY_META;
+
+if (Object.freeze) Object.freeze(EMPTY_META);
+
+var isDefinePropertySimulated = Ember.platform.defineProperty.isSimulated;
+
+function Meta(obj) {
+  this.descs = {};
+  this.watching = {};
+  this.cache = {};
+  this.source = obj;
+}
+
+if (isDefinePropertySimulated) {
+  // on platforms that don't support enumerable false
+  // make meta fail jQuery.isPlainObject() to hide from
+  // jQuery.extend() by having a property that fails
+  // hasOwnProperty check.
+  Meta.prototype.__preventPlainObject__ = true;
+}
+
+/**
+  Retrieves the meta hash for an object.  If 'writable' is true ensures the
+  hash is writable for this object as well.
+
+  The meta object contains information about computed property descriptors as
+  well as any watched properties and other information.  You generally will
+  not access this information directly but instead work with higher level
+  methods that manipulate this hash indirectly.
+
+  @method meta
+  @for Ember
+  @private
+
+  @param {Object} obj The object to retrieve meta for
+
+  @param {Boolean} [writable=true] Pass false if you do not intend to modify
+    the meta hash, allowing the method to avoid making an unnecessary copy.
+
+  @return {Hash}
+*/
+Ember.meta = function meta(obj, writable) {
+
+  var ret = obj[META_KEY];
+  if (writable===false) return ret || EMPTY_META;
+
+  if (!ret) {
+    if (!isDefinePropertySimulated) o_defineProperty(obj, META_KEY, META_DESC);
+
+    ret = new Meta(obj);
+
+    if (MANDATORY_SETTER) { ret.values = {}; }
+
+    obj[META_KEY] = ret;
+
+    // make sure we don't accidentally try to create constructor like desc
+    ret.descs.constructor = null;
+
+  } else if (ret.source !== obj) {
+    if (!isDefinePropertySimulated) o_defineProperty(obj, META_KEY, META_DESC);
+
+    ret = o_create(ret);
+    ret.descs    = o_create(ret.descs);
+    ret.watching = o_create(ret.watching);
+    ret.cache    = {};
+    ret.source   = obj;
+
+    if (MANDATORY_SETTER) { ret.values = o_create(ret.values); }
+
+    obj[META_KEY] = ret;
+  }
+  return ret;
+};
+
+Ember.getMeta = function getMeta(obj, property) {
+  var meta = Ember.meta(obj, false);
+  return meta[property];
+};
+
+Ember.setMeta = function setMeta(obj, property, value) {
+  var meta = Ember.meta(obj, true);
+  meta[property] = value;
+  return value;
+};
+
+/**
+  @private
+
+  In order to store defaults for a class, a prototype may need to create
+  a default meta object, which will be inherited by any objects instantiated
+  from the class's constructor.
+
+  However, the properties of that meta object are only shallow-cloned,
+  so if a property is a hash (like the event system's `listeners` hash),
+  it will by default be shared across all instances of that class.
+
+  This method allows extensions to deeply clone a series of nested hashes or
+  other complex objects. For instance, the event system might pass
+  ['listeners', 'foo:change', 'ember157'] to `prepareMetaPath`, which will
+  walk down the keys provided.
+
+  For each key, if the key does not exist, it is created. If it already
+  exists and it was inherited from its constructor, the constructor's
+  key is cloned.
+
+  You can also pass false for `writable`, which will simply return
+  undefined if `prepareMetaPath` discovers any part of the path that
+  shared or undefined.
+
+  @method metaPath
+  @for Ember
+  @param {Object} obj The object whose meta we are examining
+  @param {Array} path An array of keys to walk down
+  @param {Boolean} writable whether or not to create a new meta
+    (or meta property) if one does not already exist or if it's
+    shared with its constructor
+*/
+Ember.metaPath = function metaPath(obj, path, writable) {
+  var meta = Ember.meta(obj, writable), keyName, value;
+
+  for (var i=0, l=path.length; i<l; i++) {
+    keyName = path[i];
+    value = meta[keyName];
+
+    if (!value) {
+      if (!writable) { return undefined; }
+      value = meta[keyName] = { __ember_source__: obj };
+    } else if (value.__ember_source__ !== obj) {
+      if (!writable) { return undefined; }
+      value = meta[keyName] = o_create(value);
+      value.__ember_source__ = obj;
+    }
+
+    meta = value;
+  }
+
+  return value;
+};
+
+/**
+  @private
+
+  Wraps the passed function so that `this._super` will point to the superFunc
+  when the function is invoked.  This is the primitive we use to implement
+  calls to super.
+
+  @method wrap
+  @for Ember
+  @param {Function} func The function to call
+  @param {Function} superFunc The super function.
+  @return {Function} wrapped function.
+*/
+Ember.wrap = function(func, superFunc) {
+
+  function K() {}
+
+  var newFunc = function() {
+    var ret, sup = this._super;
+    this._super = superFunc || K;
+    ret = func.apply(this, arguments);
+    this._super = sup;
+    return ret;
+  };
+
+  newFunc.base = func;
+  return newFunc;
+};
+
+/**
+  Returns true if the passed object is an array or Array-like.
+
+  Ember Array Protocol:
+
+    - the object has an objectAt property
+    - the object is a native Array
+    - the object is an Object, and has a length property
+
+  Unlike Ember.typeOf this method returns true even if the passed object is
+  not formally array but appears to be array-like (i.e. implements Ember.Array)
+
+      Ember.isArray(); // false
+      Ember.isArray([]); // true
+      Ember.isArray( Ember.ArrayProxy.create({ content: [] }) ); // true
+
+  @method isArray
+  @for Ember
+  @param {Object} obj The object to test
+  @return {Boolean}
+*/
+Ember.isArray = function(obj) {
+  if (!obj || obj.setInterval) { return false; }
+  if (Array.isArray && Array.isArray(obj)) { return true; }
+  if (Ember.Array && Ember.Array.detect(obj)) { return true; }
+  if ((obj.length !== undefined) && 'object'===typeof obj) { return true; }
+  return false;
+};
+
+/**
+  Forces the passed object to be part of an array.  If the object is already
+  an array or array-like, returns the object.  Otherwise adds the object to
+  an array.  If obj is null or undefined, returns an empty array.
+
+      Ember.makeArray();          => []
+      Ember.makeArray(null);      => []
+      Ember.makeArray(undefined); => []
+      Ember.makeArray('lindsay'); => ['lindsay']
+      Ember.makeArray([1,2,42]);  => [1,2,42]
+
+      var controller = Ember.ArrayProxy.create({ content: [] });
+      Ember.makeArray(controller) === controller;   => true
+
+  @method makeArray
+  @for Ember
+  @param {Object} obj the object
+  @return {Array}
+*/
+Ember.makeArray = function(obj) {
+  if (obj === null || obj === undefined) { return []; }
+  return Ember.isArray(obj) ? obj : [obj];
+};
+
+function canInvoke(obj, methodName) {
+  return !!(obj && typeof obj[methodName] === 'function');
+}
+
+/**
+  Checks to see if the `methodName` exists on the `obj`.
+
+  @method canInvoke
+  @for Ember
+  @param {Object} obj The object to check for the method
+  @param {String} methodName The method name to check for
+*/
+Ember.canInvoke = canInvoke;
+
+/**
+  Checks to see if the `methodName` exists on the `obj`,
+  and if it does, invokes it with the arguments passed.
+
+  @method tryInvoke
+  @for Ember
+  @param {Object} obj The object to check for the method
+  @param {String} methodName The method name to check for
+  @param {Array} [args] The arguments to pass to the method
+  @return {anything} the return value of the invoked method or undefined if it cannot be invoked
+*/
+Ember.tryInvoke = function(obj, methodName, args) {
+  if (canInvoke(obj, methodName)) {
+    return obj[methodName].apply(obj, args || []);
+  }
+};
+
+})();
+
+
+
+(function() {
+/**
+@module ember-metal
+*/
+
+/*
+  JavaScript (before ES6) does not have a Map implementation. Objects,
+  which are often used as dictionaries, may only have Strings as keys.
+
+  Because Ember has a way to get a unique identifier for every object
+  via `Ember.guidFor`, we can implement a performant Map with arbitrary
+  keys. Because it is commonly used in low-level bookkeeping, Map is
+  implemented as a pure JavaScript object for performance.
+
+  This implementation follows the current iteration of the ES6 proposal
+  for maps (http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets),
+  with two exceptions. First, because we need our implementation to be
+  pleasant on older browsers, we do not use the `delete` name (using
+  `remove` instead). Second, as we do not have the luxury of in-VM
+  iteration, we implement a forEach method for iteration.
+
+  Map is mocked out to look like an Ember object, so you can do
+  `Ember.Map.create()` for symmetry with other Ember classes.
+*/
+var guidFor = Ember.guidFor,
+    indexOf = Ember.ArrayPolyfills.indexOf;
+
+var copy = function(obj) {
+  var output = {};
+
+  for (var prop in obj) {
+    if (obj.hasOwnProperty(prop)) { output[prop] = obj[prop]; }
+  }
+
+  return output;
+};
+
+var copyMap = function(original, newObject) {
+  var keys = original.keys.copy(),
+      values = copy(original.values);
+
+  newObject.keys = keys;
+  newObject.values = values;
+
+  return newObject;
+};
+
+/**
+  This class is used internally by Ember.js and Ember Data.
+  Please do not use it at this time. We plan to clean it up
+  and add many tests soon.
+
+  @class OrderedSet
+  @namespace Ember
+  @constructor
+  @private
+*/
+var OrderedSet = Ember.OrderedSet = function() {
+  this.clear();
+};
+
+/**
+  @method create
+  @static
+  @return {Ember.OrderedSet}
+*/
+OrderedSet.create = function() {
+  return new OrderedSet();
+};
+
+
+OrderedSet.prototype = {
+  /**
+    @method clear
+  */
+  clear: function() {
+    this.presenceSet = {};
+    this.list = [];
+  },
+
+  /**
+    @method add
+    @param obj
+  */
+  add: function(obj) {
+    var guid = guidFor(obj),
+        presenceSet = this.presenceSet,
+        list = this.list;
+
+    if (guid in presenceSet) { return; }
+
+    presenceSet[guid] = true;
+    list.push(obj);
+  },
+
+  /**
+    @method remove
+    @param obj
+  */
+  remove: function(obj) {
+    var guid = guidFor(obj),
+        presenceSet = this.presenceSet,
+        list = this.list;
+
+    delete presenceSet[guid];
+
+    var index = indexOf.call(list, obj);
+    if (index > -1) {
+      list.splice(index, 1);
+    }
+  },
+
+  /**
+    @method isEmpty
+    @return {Boolean}
+  */
+  isEmpty: function() {
+    return this.list.length === 0;
+  },
+
+  /**
+    @method has
+    @param obj
+    @return {Boolean}
+  */
+  has: function(obj) {
+    var guid = guidFor(obj),
+        presenceSet = this.presenceSet;
+
+    return guid in presenceSet;
+  },
+
+  /**
+    @method forEach
+    @param {Function} function
+    @param target
+  */
+  forEach: function(fn, self) {
+    // allow mutation during iteration
+    var list = this.list.slice();
+
+    for (var i = 0, j = list.length; i < j; i++) {
+      fn.call(self, list[i]);
+    }
+  },
+
+  /**
+    @method toArray
+    @return {Array}
+  */
+  toArray: function() {
+    return this.list.slice();
+  },
+
+  /**
+    @method copy
+    @return {Ember.OrderedSet}
+  */
+  copy: function() {
+    var set = new OrderedSet();
+
+    set.presenceSet = copy(this.presenceSet);
+    set.list = this.list.slice();
+
+    return set;
+  }
+};
+
+/**
+  A Map stores values indexed by keys. Unlike JavaScript's
+  default Objects, the keys of a Map can be any JavaScript
+  object.
+
+  Internally, a Map has two data structures:
+
+    `keys`: an OrderedSet of all of the existing keys
+    `values`: a JavaScript Object indexed by the
+      Ember.guidFor(key)
+
+  When a key/value pair is added for the first time, we
+  add the key to the `keys` OrderedSet, and create or
+  replace an entry in `values`. When an entry is deleted,
+  we delete its entry in `keys` and `values`.
+
+  @class Map
+  @namespace Ember
+  @private
+  @constructor
+*/
+var Map = Ember.Map = function() {
+  this.keys = Ember.OrderedSet.create();
+  this.values = {};
+};
+
+/**
+  @method create
+  @static
+*/
+Map.create = function() {
+  return new Map();
+};
+
+Map.prototype = {
+  /**
+    Retrieve the value associated with a given key.
+
+    @method get
+    @param {anything} key
+    @return {anything} the value associated with the key, or undefined
+  */
+  get: function(key) {
+    var values = this.values,
+        guid = guidFor(key);
+
+    return values[guid];
+  },
+
+  /**
+    Adds a value to the map. If a value for the given key has already been
+    provided, the new value will replace the old value.
+
+    @method set
+    @param {anything} key
+    @param {anything} value
+  */
+  set: function(key, value) {
+    var keys = this.keys,
+        values = this.values,
+        guid = guidFor(key);
+
+    keys.add(key);
+    values[guid] = value;
+  },
+
+  /**
+    Removes a value from the map for an associated key.
+
+    @method remove
+    @param {anything} key
+    @return {Boolean} true if an item was removed, false otherwise
+  */
+  remove: function(key) {
+    // don't use ES6 "delete" because it will be annoying
+    // to use in browsers that are not ES6 friendly;
+    var keys = this.keys,
+        values = this.values,
+        guid = guidFor(key),
+        value;
+
+    if (values.hasOwnProperty(guid)) {
+      keys.remove(key);
+      value = values[guid];
+      delete values[guid];
+      return true;
+    } else {
+      return false;
+    }
+  },
+
+  /**
+    Check whether a key is present.
+
+    @method has
+    @param {anything} key
+    @return {Boolean} true if the item was present, false otherwise
+  */
+  has: function(key) {
+    var values = this.values,
+        guid = guidFor(key);
+
+    return values.hasOwnProperty(guid);
+  },
+
+  /**
+    Iterate over all the keys and values. Calls the function once
+    for each key, passing in the key and value, in that order.
+
+    The keys are guaranteed to be iterated over in insertion order.
+
+    @method forEach
+    @param {Function} callback
+    @param {anything} self if passed, the `this` value inside the
+      callback. By default, `this` is the map.
+  */
+  forEach: function(callback, self) {
+    var keys = this.keys,
+        values = this.values;
+
+    keys.forEach(function(key) {
+      var guid = guidFor(key);
+      callback.call(self, key, values[guid]);
+    });
+  },
+
+  /**
+    @method copy
+    @return {Ember.Map}
+  */
+  copy: function() {
+    return copyMap(this, new Map());
+  }
+};
+
+/**
+  @class MapWithDefault
+  @namespace Ember
+  @extends Ember.Map
+  @private
+  @constructor
+  @param [options]
+    @param {anything} [options.defaultValue]
+*/
+var MapWithDefault = Ember.MapWithDefault = function(options) {
+  Map.call(this);
+  this.defaultValue = options.defaultValue;
+};
+
+/**
+  @method create
+  @static
+  @param [options]
+    @param {anything} [options.defaultValue]
+  @return {Ember.MapWithDefault|Ember.Map} If options are passed, returns Ember.MapWithDefault otherwise returns Ember.Map
+*/
+MapWithDefault.create = function(options) {
+  if (options) {
+    return new MapWithDefault(options);
+  } else {
+    return new Map();
+  }
+};
+
+MapWithDefault.prototype = Ember.create(Map.prototype);
+
+/**
+  Retrieve the value associated with a given key.
+
+  @method get
+  @param {anything} key
+  @return {anything} the value associated with the key, or the default value
+*/
+MapWithDefault.prototype.get = function(key) {
+  var hasValue = this.has(key);
+
+  if (hasValue) {
+    return Map.prototype.get.call(this, key);
+  } else {
+    var defaultValue = this.defaultValue(key);
+    this.set(key, defaultValue);
+    return defaultValue;
+  }
+};
+
+/**
+  @method copy
+  @return {Ember.MapWithDefault}
+*/
+MapWithDefault.prototype.copy = function() {
+  return copyMap(this, new MapWithDefault({
+    defaultValue: this.defaultValue
+  }));
+};
+
+})();
+
+
+
+(function() {
+/**
+@module ember-metal
+*/
+
+var META_KEY = Ember.META_KEY, get, set;
+
+var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
+
+var IS_GLOBAL = /^([A-Z$]|([0-9][A-Z$]))/;
+var IS_GLOBAL_PATH = /^([A-Z$]|([0-9][A-Z$])).*[\.\*]/;
+var HAS_THIS  = /^this[\.\*]/;
+var FIRST_KEY = /^([^\.\*]+)/;
+
+// ..........................................................
+// GET AND SET
+//
+// If we are on a platform that supports accessors we can get use those.
+// Otherwise simulate accessors by looking up the property directly on the
+// object.
+
+/**
+  Gets the value of a property on an object.  If the property is computed,
+  the function will be invoked.  If the property is not defined but the
+  object implements the unknownProperty() method then that will be invoked.
+
+  If you plan to run on IE8 and older browsers then you should use this
+  method anytime you want to retrieve a property on an object that you don't
+  know for sure is private.  (My convention only properties beginning with
+  an underscore '_' are considered private.)
+
+  On all newer browsers, you only need to use this method to retrieve
+  properties if the property might not be defined on the object and you want
+  to respect the unknownProperty() handler.  Otherwise you can ignore this
+  method.
+
+  Note that if the obj itself is null, this method will simply return
+  undefined.
+
+  @method get
+  @for Ember
+  @param {Object} obj The object to retrieve from.
+  @param {String} keyName The property key to retrieve
+  @return {Object} the property value or null.
+*/
+get = function get(obj, keyName) {
+  // Helpers that operate with 'this' within an #each
+  if (keyName === '') {
+    return obj;
+  }
+
+  if (!keyName && 'string'===typeof obj) {
+    keyName = obj;
+    obj = null;
+  }
+
+  if (!obj || keyName.indexOf('.') !== -1) {
+    return getPath(obj, keyName);
+  }
+
+  Ember.assert("You need to provide an object and key to `get`.", !!obj && keyName);
+
+  var meta = obj[META_KEY], desc = meta && meta.descs[keyName], ret;
+  if (desc) {
+    return desc.get(obj, keyName);
+  } else {
+    if (MANDATORY_SETTER && meta && meta.watching[keyName] > 0) {
+      ret = meta.values[keyName];
+    } else {
+      ret = obj[keyName];
+    }
+
+    if (ret === undefined &&
+        'object' === typeof obj && !(keyName in obj) && 'function' === typeof obj.unknownProperty) {
+      return obj.unknownProperty(keyName);
+    }
+
+    return ret;
+  }
+};
+
+/**
+  Sets the value of a property on an object, respecting computed properties
+  and notifying observers and other listeners of the change.  If the
+  property is not defined but the object implements the unknownProperty()
+  method then that will be invoked as well.
+
+  If you plan to run on IE8 and older browsers then you should use this
+  method anytime you want to set a property on an object that you don't
+  know for sure is private.  (My convention only properties beginning with
+  an underscore '_' are considered private.)
+
+  On all newer browsers, you only need to use this method to set
+  properties if the property might not be defined on the object and you want
+  to respect the unknownProperty() handler.  Otherwise you can ignore this
+  method.
+
+  @method set
+  @for Ember
+  @param {Object} obj The object to modify.
+  @param {String} keyName The property key to set
+  @param {Object} value The value to set
+  @return {Object} the passed value.
+*/
+set = function set(obj, keyName, value, tolerant) {
+  if (typeof obj === 'string') {
+    Ember.assert("Path '" + obj + "' must be global if no obj is given.", IS_GLOBAL.test(obj));
+    value = keyName;
+    keyName = obj;
+    obj = null;
+  }
+
+  if (!obj || keyName.indexOf('.') !== -1) {
+    return setPath(obj, keyName, value, tolerant);
+  }
+
+  Ember.assert("You need to provide an object and key to `set`.", !!obj && keyName !== undefined);
+  Ember.assert('calling set on destroyed object', !obj.isDestroyed);
+
+  var meta = obj[META_KEY], desc = meta && meta.descs[keyName],
+      isUnknown, currentValue;
+  if (desc) {
+    desc.set(obj, keyName, value);
+  }
+  else {
+    isUnknown = 'object' === typeof obj && !(keyName in obj);
+
+    // setUnknownProperty is called if `obj` is an object,
+    // the property does not already exist, and the
+    // `setUnknownProperty` method exists on the object
+    if (isUnknown && 'function' === typeof obj.setUnknownProperty) {
+      obj.setUnknownProperty(keyName, value);
+    } else if (meta && meta.watching[keyName] > 0) {
+      if (MANDATORY_SETTER) {
+        currentValue = meta.values[keyName];
+      } else {
+        currentValue = obj[keyName];
+      }
+      // only trigger a change if the value has changed
+      if (value !== currentValue) {
+        Ember.propertyWillChange(obj, keyName);
+        if (MANDATORY_SETTER) {
+          if (currentValue === undefined && !(keyName in obj)) {
+            Ember.defineProperty(obj, keyName, null, value); // setup mandatory setter
+          } else {
+            meta.values[keyName] = value;
+          }
+        } else {
+          obj[keyName] = value;
+        }
+        Ember.propertyDidChange(obj, keyName);
+      }
+    } else {
+      obj[keyName] = value;
+    }
+  }
+  return value;
+};
+
+// Currently used only by Ember Data tests
+if (Ember.config.overrideAccessors) {
+  Ember.get = get;
+  Ember.set = set;
+  Ember.config.overrideAccessors();
+  get = Ember.get;
+  set = Ember.set;
+}
+
+function firstKey(path) {
+  return path.match(FIRST_KEY)[0];
+}
+
+// assumes path is already normalized
+function normalizeTuple(target, path) {
+  var hasThis  = HAS_THIS.test(path),
+      isGlobal = !hasThis && IS_GLOBAL_PATH.test(path),
+      key;
+
+  if (!target || isGlobal) target = Ember.lookup;
+  if (hasThis) path = path.slice(5);
+
+  if (target === Ember.lookup) {
+    key = firstKey(path);
+    target = get(target, key);
+    path   = path.slice(key.length+1);
+  }
+
+  // must return some kind of path to be valid else other things will break.
+  if (!path || path.length===0) throw new Error('Invalid Path');
+
+  return [ target, path ];
+}
+
+function getPath(root, path) {
+  var hasThis, parts, tuple, idx, len;
+
+  // If there is no root and path is a key name, return that
+  // property from the global object.
+  // E.g. get('Ember') -> Ember
+  if (root === null && path.indexOf('.') === -1) { return get(Ember.lookup, path); }
+
+  // detect complicated paths and normalize them
+  hasThis  = HAS_THIS.test(path);
+
+  if (!root || hasThis) {
+    tuple = normalizeTuple(root, path);
+    root = tuple[0];
+    path = tuple[1];
+    tuple.length = 0;
+  }
+
+  parts = path.split(".");
+  len = parts.length;
+  for (idx=0; root && idx<len; idx++) {
+    root = get(root, parts[idx], true);
+    if (root && root.isDestroyed) { return undefined; }
+  }
+  return root;
+}
+
+function setPath(root, path, value, tolerant) {
+  var keyName;
+
+  // get the last part of the path
+  keyName = path.slice(path.lastIndexOf('.') + 1);
+
+  // get the first part of the part
+  path    = path.slice(0, path.length-(keyName.length+1));
+
+  // unless the path is this, look up the first part to
+  // get the root
+  if (path !== 'this') {
+    root = getPath(root, path);
+  }
+
+  if (!keyName || keyName.length === 0) {
+    throw new Error('You passed an empty path');
+  }
+
+  if (!root) {
+    if (tolerant) { return; }
+    else { throw new Error('Object in path '+path+' could not be found or was destroyed.'); }
+  }
+
+  return set(root, keyName, value);
+}
+
+/**
+  @private
+
+  Normalizes a target/path pair to reflect that actual target/path that should
+  be observed, etc.  This takes into account passing in global property
+  paths (i.e. a path beginning with a captial letter not defined on the
+  target) and * separators.
+
+  @method normalizeTuple
+  @for Ember
+  @param {Object} target The current target.  May be null.
+  @param {String} path A path on the target or a global property path.
+  @return {Array} a temporary array with the normalized target/path pair.
+*/
+Ember.normalizeTuple = function(target, path) {
+  return normalizeTuple(target, path);
+};
+
+Ember.getWithDefault = function(root, key, defaultValue) {
+  var value = get(root, key);
+
+  if (value === undefined) { return defaultValue; }
+  return value;
+};
+
+
+Ember.get = get;
+Ember.getPath = Ember.deprecateFunc('getPath is deprecated since get now supports paths', Ember.get);
+
+Ember.set = set;
+Ember.setPath = Ember.deprecateFunc('setPath is deprecated since set now supports paths', Ember.set);
+
+/**
+  Error-tolerant form of Ember.set. Will not blow up if any part of the
+  chain is undefined, null, or destroyed.
+
+  This is primarily used when syncing bindings, which may try to update after
+  an object has been destroyed.
+
+  @method trySet
+  @for Ember
+  @param {Object} obj The object to modify.
+  @param {String} keyName The property key to set
+  @param {Object} value The value to set
+*/
+Ember.trySet = function(root, path, value) {
+  return set(root, path, value, true);
+};
+Ember.trySetPath = Ember.deprecateFunc('trySetPath has been renamed to trySet', Ember.trySet);
+
+/**
+  Returns true if the provided path is global (e.g., "MyApp.fooController.bar")
+  instead of local ("foo.bar.baz").
+
+  @method isGlobalPath
+  @for Ember
+  @private
+  @param {String} path
+  @return Boolean
+*/
+Ember.isGlobalPath = function(path) {
+  return IS_GLOBAL.test(path);
+};
+
+
+})();
+
+
+
+(function() {
+/**
+@module ember-metal
+*/
+
+var GUID_KEY = Ember.GUID_KEY,
+    META_KEY = Ember.META_KEY,
+    EMPTY_META = Ember.EMPTY_META,
+    metaFor = Ember.meta,
+    o_create = Ember.create,
+    objectDefineProperty = Ember.platform.defineProperty;
+
+var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
+
+// ..........................................................
+// DESCRIPTOR
+//
+
+/**
+  Objects of this type can implement an interface to responds requests to
+  get and set.  The default implementation handles simple properties.
+
+  You generally won't need to create or subclass this directly.
+
+  @class Descriptor
+  @namespace Ember
+  @private
+  @constructor
+*/
+var Descriptor = Ember.Descriptor = function() {};
+
+// ..........................................................
+// DEFINING PROPERTIES API
+//
+
+/**
+  @private
+
+  NOTE: This is a low-level method used by other parts of the API.  You almost
+  never want to call this method directly.  Instead you should use Ember.mixin()
+  to define new properties.
+
+  Defines a property on an object.  This method works much like the ES5
+  Object.defineProperty() method except that it can also accept computed
+  properties and other special descriptors.
+
+  Normally this method takes only three parameters.  However if you pass an
+  instance of Ember.Descriptor as the third param then you can pass an optional
+  value as the fourth parameter.  This is often more efficient than creating
+  new descriptor hashes for each property.
+
+  ## Examples
+
+      // ES5 compatible mode
+      Ember.defineProperty(contact, 'firstName', {
+        writable: true,
+        configurable: false,
+        enumerable: true,
+        value: 'Charles'
+      });
+
+      // define a simple property
+      Ember.defineProperty(contact, 'lastName', undefined, 'Jolley');
+
+      // define a computed property
+      Ember.defineProperty(contact, 'fullName', Ember.computed(function() {
+        return this.firstName+' '+this.lastName;
+      }).property('firstName', 'lastName'));
+
+  @method defineProperty
+  @for Ember
+  @param {Object} obj the object to define this property on. This may be a prototype.
+  @param {String} keyName the name of the property
+  @param {Ember.Descriptor} [desc] an instance of Ember.Descriptor (typically a
+    computed property) or an ES5 descriptor.
+    You must provide this or `data` but not both.
+  @param {anything} [data] something other than a descriptor, that will
+    become the explicit value of this property.
+*/
+Ember.defineProperty = function(obj, keyName, desc, data, meta) {
+  var descs, existingDesc, watching, value;
+
+  if (!meta) meta = metaFor(obj);
+  descs = meta.descs;
+  existingDesc = meta.descs[keyName];
+  watching = meta.watching[keyName] > 0;
+
+  if (existingDesc instanceof Ember.Descriptor) {
+    existingDesc.teardown(obj, keyName);
+  }
+
+  if (desc instanceof Ember.Descriptor) {
+    value = desc;
+
+    descs[keyName] = desc;
+    if (MANDATORY_SETTER && watching) {
+      objectDefineProperty(obj, keyName, {
+        configurable: true,
+        enumerable: true,
+        writable: true,
+        value: undefined // make enumerable
+      });
+    } else {
+      obj[keyName] = undefined; // make enumerable
+    }
+    desc.setup(obj, keyName);
+  } else {
+    descs[keyName] = undefined; // shadow descriptor in proto
+    if (desc == null) {
+      value = data;
+
+      if (MANDATORY_SETTER && watching) {
+        meta.values[keyName] = data;
+        objectDefineProperty(obj, keyName, {
+          configurable: true,
+          enumerable: true,
+          set: function() {
+            Ember.assert('Must use Ember.set() to access this property', false);
+          },
+          get: function() {
+            var meta = this[META_KEY];
+            return meta && meta.values[keyName];
+          }
+        });
+      } else {
+        obj[keyName] = data;
+      }
+    } else {
+      value = desc;
+
+      // compatibility with ES5
+      objectDefineProperty(obj, keyName, desc);
+    }
+  }
+
+  // if key is being watched, override chains that
+  // were initialized with the prototype
+  if (watching) { Ember.overrideChains(obj, keyName, meta); }
+
+  // The `value` passed to the `didDefineProperty` hook is
+  // either the descriptor or data, whichever was passed.
+  if (obj.didDefineProperty) { obj.didDefineProperty(obj, keyName, value); }
+
+  return this;
+};
+
+
+})();
+
+
+
+(function() {
+/**
+@module ember-metal
+*/
+
+var AFTER_OBSERVERS = ':change';
+var BEFORE_OBSERVERS = ':before';
+
+var guidFor = Ember.guidFor;
+
+var deferred = 0;
+
+/*
+  this.observerSet = {
+    [senderGuid]: { // variable name: `keySet`
+      [keyName]: listIndex
+    }
+  },
+  this.observers = [
+    {
+      sender: obj,
+      keyName: keyName,
+      eventName: eventName,
+      listeners: {
+        [targetGuid]: {        // variable name: `actionSet`
+          [methodGuid]: {      // variable name: `action`
+            target: [Object object],
+            method: [Function function]
+          }
+        }
+      }
+    },
+    ...
+  ]
+*/
+function ObserverSet() {
+  this.clear();
+}
+
+ObserverSet.prototype.add = function(sender, keyName, eventName) {
+  var observerSet = this.observerSet,
+      observers = this.observers,
+      senderGuid = Ember.guidFor(sender),
+      keySet = observerSet[senderGuid],
+      index;
+
+  if (!keySet) {
+    observerSet[senderGuid] = keySet = {};
+  }
+  index = keySet[keyName];
+  if (index === undefined) {
+    index = observers.push({
+      sender: sender,
+      keyName: keyName,
+      eventName: eventName,
+      listeners: {}
+    }) - 1;
+    keySet[keyName] = index;
+  }
+  return observers[index].listeners;
+};
+
+ObserverSet.prototype.flush = function() {
+  var observers = this.observers, i, len, observer, sender;
+  this.clear();
+  for (i=0, len=observers.length; i < len; ++i) {
+    observer = observers[i];
+    sender = observer.sender;
+    if (sender.isDestroyed) { continue; }
+    Ember.sendEvent(sender, observer.eventName, [sender, observer.keyName], observer.listeners);
+  }
+};
+
+ObserverSet.prototype.clear = function() {
+  this.observerSet = {};
+  this.observers = [];
+};
+
+var beforeObserverSet = new ObserverSet(), observerSet = new ObserverSet();
+
+/**
+  @method beginPropertyChanges
+  @chainable
+*/
+Ember.beginPropertyChanges = function() {
+  deferred++;
+};
+
+/**
+  @method endPropertyChanges
+*/
+Ember.endPropertyChanges = function() {
+  deferred--;
+  if (deferred<=0) {
+    beforeObserverSet.clear();
+    observerSet.flush();
+  }
+};
+
+/**
+  Make a series of property changes together in an
+  exception-safe way.
+
+      Ember.changeProperties(function() {
+        obj1.set('foo', mayBlowUpWhenSet);
+        obj2.set('bar', baz);
+      });
+
+  @method changeProperties
+  @param {Function} callback
+  @param [binding]
+*/
+Ember.changeProperties = function(cb, binding){
+  Ember.beginPropertyChanges();
+  try {
+    cb.call(binding);
+  } finally {
+    Ember.endPropertyChanges();
+  }
+};
+
+/**
+  Set a list of properties on an object. These properties are set inside
+  a single `beginPropertyChanges` and `endPropertyChanges` batch, so
+  observers will be buffered.
+
+  @method setProperties
+  @param target
+  @param {Hash} properties
+  @return target
+*/
+Ember.setProperties = function(self, hash) {
+  Ember.changeProperties(function(){
+    for(var prop in hash) {
+      if (hash.hasOwnProperty(prop)) Ember.set(self, prop, hash[prop]);
+    }
+  });
+  return self;
+};
+
+
+function changeEvent(keyName) {
+  return keyName+AFTER_OBSERVERS;
+}
+
+function beforeEvent(keyName) {
+  return keyName+BEFORE_OBSERVERS;
+}
+
+/**
+  @method addObserver
+  @param obj
+  @param {String} path
+  @param {Object|Function} targetOrMethod
+  @param {Function|String} [method]
+*/
+Ember.addObserver = function(obj, path, target, method) {
+  Ember.addListener(obj, changeEvent(path), target, method);
+  Ember.watch(obj, path);
+  return this;
+};
+
+Ember.observersFor = function(obj, path) {
+  return Ember.listenersFor(obj, changeEvent(path));
+};
+
+/**
+  @method removeObserver
+  @param obj
+  @param {String} path
+  @param {Object|Function} targetOrMethod
+  @param {Function|String} [method]
+*/
+Ember.removeObserver = function(obj, path, target, method) {
+  Ember.unwatch(obj, path);
+  Ember.removeListener(obj, changeEvent(path), target, method);
+  return this;
+};
+
+/**
+  @method addBeforeObserver
+  @param obj
+  @param {String} path
+  @param {Object|Function} targetOrMethod
+  @param {Function|String} [method]
+*/
+Ember.addBeforeObserver = function(obj, path, target, method) {
+  Ember.addListener(obj, beforeEvent(path), target, method);
+  Ember.watch(obj, path);
+  return this;
+};
+
+// Suspend observer during callback.
+//
+// This should only be used by the target of the observer
+// while it is setting the observed path.
+Ember._suspendBeforeObserver = function(obj, path, target, method, callback) {
+  return Ember._suspendListener(obj, beforeEvent(path), target, method, callback);
+};
+
+Ember._suspendObserver = function(obj, path, target, method, callback) {
+  return Ember._suspendListener(obj, changeEvent(path), target, method, callback);
+};
+
+var map = Ember.ArrayPolyfills.map;
+
+Ember._suspendBeforeObservers = function(obj, paths, target, method, callback) {
+  var events = map.call(paths, beforeEvent);
+  return Ember._suspendListeners(obj, events, target, method, callback);
+};
+
+Ember._suspendObservers = function(obj, paths, target, method, callback) {
+  var events = map.call(paths, changeEvent);
+  return Ember._suspendListeners(obj, events, target, method, callback);
+};
+
+Ember.beforeObserversFor = function(obj, path) {
+  return Ember.listenersFor(obj, beforeEvent(path));
+};
+
+/**
+  @method removeBeforeObserver
+  @param obj
+  @param {String} path
+  @param {Object|Function} targetOrMethod
+  @param {Function|String} [method]
+*/
+Ember.removeBeforeObserver = function(obj, path, target, method) {
+  Ember.unwatch(obj, path);
+  Ember.removeListener(obj, beforeEvent(path), target, method);
+  return this;
+};
+
+Ember.notifyBeforeObservers = function(obj, keyName) {
+  if (obj.isDestroying) { return; }
+
+  var eventName = beforeEvent(keyName), listeners, listenersDiff;
+  if (deferred) {
+    listeners = beforeObserverSet.add(obj, keyName, eventName);
+    listenersDiff = Ember.listenersDiff(obj, eventName, listeners);
+    Ember.sendEvent(obj, eventName, [obj, keyName], listenersDiff);
+  } else {
+    Ember.sendEvent(obj, eventName, [obj, keyName]);
+  }
+};
+
+Ember.notifyObservers = function(obj, keyName) {
+  if (obj.isDestroying) { return; }
+
+  var eventName = changeEvent(keyName), listeners;
+  if (deferred) {
+    listeners = observerSet.add(obj, keyName, eventName);
+    Ember.listenersUnion(obj, eventName, listeners);
+  } else {
+    Ember.sendEvent(obj, eventName, [obj, keyName]);
+  }
+};
+
+})();
+
+
+
+(function() {
+/**
+@module ember-metal
+*/
+
+var guidFor = Ember.guidFor, // utils.js
+    metaFor = Ember.meta, // utils.js
+    get = Ember.get, // accessors.js
+    set = Ember.set, // accessors.js
+    normalizeTuple = Ember.normalizeTuple, // accessors.js
+    GUID_KEY = Ember.GUID_KEY, // utils.js
+    META_KEY = Ember.META_KEY, // utils.js
+    // circular reference observer depends on Ember.watch
+    // we should move change events to this file or its own property_events.js
+    notifyObservers = Ember.notifyObservers, // observer.js
+    forEach = Ember.ArrayPolyfills.forEach, // array.js
+    FIRST_KEY = /^([^\.\*]+)/,
+    IS_PATH = /[\.\*]/;
+
+var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER,
+o_defineProperty = Ember.platform.defineProperty;
+
+function firstKey(path) {
+  return path.match(FIRST_KEY)[0];
+}
+
+// returns true if the passed path is just a keyName
+function isKeyName(path) {
+  return path==='*' || !IS_PATH.test(path);
+}
+
+// ..........................................................
+// DEPENDENT KEYS
+//
+
+var DEP_SKIP = { __emberproto__: true }; // skip some keys and toString
+
+function iterDeps(method, obj, depKey, seen, meta) {
+
+  var guid = guidFor(obj);
+  if (!seen[guid]) seen[guid] = {};
+  if (seen[guid][depKey]) return;
+  seen[guid][depKey] = true;
+
+  var deps = meta.deps;
+  deps = deps && deps[depKey];
+  if (deps) {
+    for(var key in deps) {
+      if (DEP_SKIP[key]) continue;
+      var desc = meta.descs[key];
+      if (desc && desc._suspended === obj) continue;
+      method(obj, key);
+    }
+  }
+}
+
+
+var WILL_SEEN, DID_SEEN;
+
+// called whenever a property is about to change to clear the cache of any dependent keys (and notify those properties of changes, etc...)
+function dependentKeysWillChange(obj, depKey, meta) {
+  if (obj.isDestroying) { return; }
+
+  var seen = WILL_SEEN, top = !seen;
+  if (top) { seen = WILL_SEEN = {}; }
+  iterDeps(propertyWillChange, obj, depKey, seen, meta);
+  if (top) { WILL_SEEN = null; }
+}
+
+// called whenever a property has just changed to update dependent keys
+function dependentKeysDidChange(obj, depKey, meta) {
+  if (obj.isDestroying) { return; }
+
+  var seen = DID_SEEN, top = !seen;
+  if (top) { seen = DID_SEEN = {}; }
+  iterDeps(propertyDidChange, obj, depKey, seen, meta);
+  if (top) { DID_SEEN = null; }
+}
+
+// ..........................................................
+// CHAIN
+//
+
+function addChainWatcher(obj, keyName, node) {
+  if (!obj || ('object' !== typeof obj)) return; // nothing to do
+  var m = metaFor(obj);
+  var nodes = m.chainWatchers;
+  if (!nodes || nodes.__emberproto__ !== obj) {
+    nodes = m.chainWatchers = { __emberproto__: obj };
+  }
+
+  if (!nodes[keyName]) { nodes[keyName] = {}; }
+  nodes[keyName][guidFor(node)] = node;
+  Ember.watch(obj, keyName);
+}
+
+function removeChainWatcher(obj, keyName, node) {
+  if (!obj || 'object' !== typeof obj) { return; } // nothing to do
+  var m = metaFor(obj, false),
+      nodes = m.chainWatchers;
+  if (!nodes || nodes.__emberproto__ !== obj) { return; } //nothing to do
+  if (nodes[keyName]) { delete nodes[keyName][guidFor(node)]; }
+  Ember.unwatch(obj, keyName);
+}
+
+var pendingQueue = [];
+
+// attempts to add the pendingQueue chains again.  If some of them end up
+// back in the queue and reschedule is true, schedules a timeout to try
+// again.
+function flushPendingChains() {
+  if (pendingQueue.length === 0) { return; } // nothing to do
+
+  var queue = pendingQueue;
+  pendingQueue = [];
+
+  forEach.call(queue, function(q) { q[0].add(q[1]); });
+
+  Ember.warn('Watching an undefined global, Ember expects watched globals to be setup by the time the run loop is flushed, check for typos', pendingQueue.length === 0);
+}
+
+function isProto(pvalue) {
+  return metaFor(pvalue, false).proto === pvalue;
+}
+
+// A ChainNode watches a single key on an object.  If you provide a starting
+// value for the key then the node won't actually watch it.  For a root node
+// pass null for parent and key and object for value.
+var ChainNode = function(parent, key, value, separator) {
+  var obj;
+  this._parent = parent;
+  this._key    = key;
+
+  // _watching is true when calling get(this._parent, this._key) will
+  // return the value of this node.
+  //
+  // It is false for the root of a chain (because we have no parent)
+  // and for global paths (because the parent node is the object with
+  // the observer on it)
+  this._watching = value===undefined;
+
+  this._value  = value;
+  this._separator = separator || '.';
+  this._paths = {};
+  if (this._watching) {
+    this._object = parent.value();
+    if (this._object) { addChainWatcher(this._object, this._key, this); }
+  }
+
+  // Special-case: the EachProxy relies on immediate evaluation to
+  // establish its observers.
+  //
+  // TODO: Replace this with an efficient callback that the EachProxy
+  // can implement.
+  if (this._parent && this._parent._key === '@each') {
+    this.value();
+  }
+};
+
+var ChainNodePrototype = ChainNode.prototype;
+
+ChainNodePrototype.value = function() {
+  if (this._value === undefined && this._watching) {
+    var obj = this._parent.value();
+    this._value = (obj && !isProto(obj)) ? get(obj, this._key) : undefined;
+  }
+  return this._value;
+};
+
+ChainNodePrototype.destroy = function() {
+  if (this._watching) {
+    var obj = this._object;
+    if (obj) { removeChainWatcher(obj, this._key, this); }
+    this._watching = false; // so future calls do nothing
+  }
+};
+
+// copies a top level object only
+ChainNodePrototype.copy = function(obj) {
+  var ret = new ChainNode(null, null, obj, this._separator),
+      paths = this._paths, path;
+  for (path in paths) {
+    if (paths[path] <= 0) { continue; } // this check will also catch non-number vals.
+    ret.add(path);
+  }
+  return ret;
+};
+
+// called on the root node of a chain to setup watchers on the specified
+// path.
+ChainNodePrototype.add = function(path) {
+  var obj, tuple, key, src, separator, paths;
+
+  paths = this._paths;
+  paths[path] = (paths[path] || 0) + 1;
+
+  obj = this.value();
+  tuple = normalizeTuple(obj, path);
+
+  // the path was a local path
+  if (tuple[0] && tuple[0] === obj) {
+    path = tuple[1];
+    key  = firstKey(path);
+    path = path.slice(key.length+1);
+
+  // global path, but object does not exist yet.
+  // put into a queue and try to connect later.
+  } else if (!tuple[0]) {
+    pendingQueue.push([this, path]);
+    tuple.length = 0;
+    return;
+
+  // global path, and object already exists
+  } else {
+    src  = tuple[0];
+    key  = path.slice(0, 0-(tuple[1].length+1));
+    separator = path.slice(key.length, key.length+1);
+    path = tuple[1];
+  }
+
+  tuple.length = 0;
+  this.chain(key, path, src, separator);
+};
+
+// called on the root node of a chain to teardown watcher on the specified
+// path
+ChainNodePrototype.remove = function(path) {
+  var obj, tuple, key, src, paths;
+
+  paths = this._paths;
+  if (paths[path] > 0) { paths[path]--; }
+
+  obj = this.value();
+  tuple = normalizeTuple(obj, path);
+  if (tuple[0] === obj) {
+    path = tuple[1];
+    key  = firstKey(path);
+    path = path.slice(key.length+1);
+  } else {
+    src  = tuple[0];
+    key  = path.slice(0, 0-(tuple[1].length+1));
+    path = tuple[1];
+  }
+
+  tuple.length = 0;
+  this.unchain(key, path);
+};
+
+ChainNodePrototype.count = 0;
+
+ChainNodePrototype.chain = function(key, path, src, separator) {
+  var chains = this._chains, node;
+  if (!chains) { chains = this._chains = {}; }
+
+  node = chains[key];
+  if (!node) { node = chains[key] = new ChainNode(this, key, src, separator); }
+  node.count++; // count chains...
+
+  // chain rest of path if there is one
+  if (path && path.length>0) {
+    key = firstKey(path);
+    path = path.slice(key.length+1);
+    node.chain(key, path); // NOTE: no src means it will observe changes...
+  }
+};
+
+ChainNodePrototype.unchain = function(key, path) {
+  var chains = this._chains, node = chains[key];
+
+  // unchain rest of path first...
+  if (path && path.length>1) {
+    key  = firstKey(path);
+    path = path.slice(key.length+1);
+    node.unchain(key, path);
+  }
+
+  // delete node if needed.
+  node.count--;
+  if (node.count<=0) {
+    delete chains[node._key];
+    node.destroy();
+  }
+
+};
+
+ChainNodePrototype.willChange = function() {
+  var chains = this._chains;
+  if (chains) {
+    for(var key in chains) {
+      if (!chains.hasOwnProperty(key)) { continue; }
+      chains[key].willChange();
+    }
+  }
+
+  if (this._parent) { this._parent.chainWillChange(this, this._key, 1); }
+};
+
+ChainNodePrototype.chainWillChange = function(chain, path, depth) {
+  if (this._key) { path = this._key + this._separator + path; }
+
+  if (this._parent) {
+    this._parent.chainWillChange(this, path, depth+1);
+  } else {
+    if (depth > 1) { Ember.propertyWillChange(this.value(), path); }
+    path = 'this.' + path;
+    if (this._paths[path] > 0) { Ember.propertyWillChange(this.value(), path); }
+  }
+};
+
+ChainNodePrototype.chainDidChange = function(chain, path, depth) {
+  if (this._key) { path = this._key + this._separator + path; }
+  if (this._parent) {
+    this._parent.chainDidChange(this, path, depth+1);
+  } else {
+    if (depth > 1) { Ember.propertyDidChange(this.value(), path); }
+    path = 'this.' + path;
+    if (this._paths[path] > 0) { Ember.propertyDidChange(this.value(), path); }
+  }
+};
+
+ChainNodePrototype.didChange = function(suppressEvent) {
+  // invalidate my own value first.
+  if (this._watching) {
+    var obj = this._parent.value();
+    if (obj !== this._object) {
+      removeChainWatcher(this._object, this._key, this);
+      this._object = obj;
+      addChainWatcher(obj, this._key, this);
+    }
+    this._value  = undefined;
+
+    // Special-case: the EachProxy relies on immediate evaluation to
+    // establish its observers.
+    if (this._parent && this._parent._key === '@each')
+      this.value();
+  }
+
+  // then notify chains...
+  var chains = this._chains;
+  if (chains) {
+    for(var key in chains) {
+      if (!chains.hasOwnProperty(key)) { continue; }
+      chains[key].didChange(suppressEvent);
+    }
+  }
+
+  if (suppressEvent) { return; }
+
+  // and finally tell parent about my path changing...
+  if (this._parent) { this._parent.chainDidChange(this, this._key, 1); }
+};
+
+// get the chains for the current object.  If the current object has
+// chains inherited from the proto they will be cloned and reconfigured for
+// the current object.
+function chainsFor(obj) {
+  var m = metaFor(obj), ret = m.chains;
+  if (!ret) {
+    ret = m.chains = new ChainNode(null, null, obj);
+  } else if (ret.value() !== obj) {
+    ret = m.chains = ret.copy(obj);
+  }
+  return ret;
+}
+
+function notifyChains(obj, m, keyName, methodName, arg) {
+  var nodes = m.chainWatchers;
+
+  if (!nodes || nodes.__emberproto__ !== obj) { return; } // nothing to do
+
+  nodes = nodes[keyName];
+  if (!nodes) { return; }
+
+  for(var key in nodes) {
+    if (!nodes.hasOwnProperty(key)) { continue; }
+    nodes[key][methodName](arg);
+  }
+}
+
+Ember.overrideChains = function(obj, keyName, m) {
+  notifyChains(obj, m, keyName, 'didChange', true);
+};
+
+function chainsWillChange(obj, keyName, m) {
+  notifyChains(obj, m, keyName, 'willChange');
+}
+
+function chainsDidChange(obj, keyName, m) {
+  notifyChains(obj, m, keyName, 'didChange');
+}
+
+// ..........................................................
+// WATCH
+//
+
+/**
+  @private
+
+  Starts watching a property on an object.  Whenever the property changes,
+  invokes Ember.propertyWillChange and Ember.propertyDidChange.  This is the
+  primitive used by observers and dependent keys; usually you will never call
+  this method directly but instead use higher level methods like
+  Ember.addObserver().
+
+  @method watch
+  @for Ember
+  @param obj
+  @param {String} keyName
+*/
+Ember.watch = function(obj, keyName) {
+  // can't watch length on Array - it is special...
+  if (keyName === 'length' && Ember.typeOf(obj) === 'array') { return this; }
+
+  var m = metaFor(obj), watching = m.watching, desc;
+
+  // activate watching first time
+  if (!watching[keyName]) {
+    watching[keyName] = 1;
+    if (isKeyName(keyName)) {
+      desc = m.descs[keyName];
+      if (desc && desc.willWatch) { desc.willWatch(obj, keyName); }
+
+      if ('function' === typeof obj.willWatchProperty) {
+        obj.willWatchProperty(keyName);
+      }
+
+      if (MANDATORY_SETTER && keyName in obj) {
+        m.values[keyName] = obj[keyName];
+        o_defineProperty(obj, keyName, {
+          configurable: true,
+          enumerable: true,
+          set: function() {
+            Ember.assert('Must use Ember.set() to access this property', false);
+          },
+          get: function() {
+            var meta = this[META_KEY];
+            return meta && meta.values[keyName];
+          }
+        });
+      }
+    } else {
+      chainsFor(obj).add(keyName);
+    }
+
+  }  else {
+    watching[keyName] = (watching[keyName] || 0) + 1;
+  }
+  return this;
+};
+
+Ember.isWatching = function isWatching(obj, key) {
+  var meta = obj[META_KEY];
+  return (meta && meta.watching[key]) > 0;
+};
+
+Ember.watch.flushPending = flushPendingChains;
+
+Ember.unwatch = function(obj, keyName) {
+  // can't watch length on Array - it is special...
+  if (keyName === 'length' && Ember.typeOf(obj) === 'array') { return this; }
+
+  var m = metaFor(obj), watching = m.watching, desc;
+
+  if (watching[keyName] === 1) {
+    watching[keyName] = 0;
+
+    if (isKeyName(keyName)) {
+      desc = m.descs[keyName];
+      if (desc && desc.didUnwatch) { desc.didUnwatch(obj, keyName); }
+
+      if ('function' === typeof obj.didUnwatchProperty) {
+        obj.didUnwatchProperty(keyName);
+      }
+
+      if (MANDATORY_SETTER && keyName in obj) {
+        o_defineProperty(obj, keyName, {
+          configurable: true,
+          enumerable: true,
+          writable: true,
+          value: m.values[keyName]
+        });
+        delete m.values[keyName];
+      }
+    } else {
+      chainsFor(obj).remove(keyName);
+    }
+
+  } else if (watching[keyName]>1) {
+    watching[keyName]--;
+  }
+
+  return this;
+};
+
+/**
+  @private
+
+  Call on an object when you first beget it from another object.  This will
+  setup any chained watchers on the object instance as needed.  This method is
+  safe to call multiple times.
+
+  @method rewatch
+  @for Ember
+  @param obj
+*/
+Ember.rewatch = function(obj) {
+  var m = metaFor(obj, false), chains = m.chains;
+
+  // make sure the object has its own guid.
+  if (GUID_KEY in obj && !obj.hasOwnProperty(GUID_KEY)) {
+    Ember.generateGuid(obj, 'ember');
+  }
+
+  // make sure any chained watchers update.
+  if (chains && chains.value() !== obj) {
+    m.chains = chains.copy(obj);
+  }
+
+  return this;
+};
+
+Ember.finishChains = function(obj) {
+  var m = metaFor(obj, false), chains = m.chains;
+  if (chains) {
+    if (chains.value() !== obj) {
+      m.chains = chains = chains.copy(obj);
+    }
+    chains.didChange(true);
+  }
+};
+
+// ..........................................................
+// PROPERTY CHANGES
+//
+
+/**
+  This function is called just before an object property is about to change.
+  It will notify any before observers and prepare caches among other things.
+
+  Normally you will not need to call this method directly but if for some
+  reason you can't directly watch a property you can invoke this method
+  manually along with `Ember.propertyDidChange()` which you should call just
+  after the property value changes.
+
+  @method propertyWillChange
+  @for Ember
+  @param {Object} obj The object with the property that will change
+  @param {String} keyName The property key (or path) that will change.
+  @return {void}
+*/
+function propertyWillChange(obj, keyName, value) {
+  var m = metaFor(obj, false),
+      watching = m.watching[keyName] > 0 || keyName === 'length',
+      proto = m.proto,
+      desc = m.descs[keyName];
+
+  if (!watching) { return; }
+  if (proto === obj) { return; }
+  if (desc && desc.willChange) { desc.willChange(obj, keyName); }
+  dependentKeysWillChange(obj, keyName, m);
+  chainsWillChange(obj, keyName, m);
+  Ember.notifyBeforeObservers(obj, keyName);
+}
+
+Ember.propertyWillChange = propertyWillChange;
+
+/**
+  This function is called just after an object property has changed.
+  It will notify any observers and clear caches among other things.
+
+  Normally you will not need to call this method directly but if for some
+  reason you can't directly watch a property you can invoke this method
+  manually along with `Ember.propertyWilLChange()` which you should call just
+  before the property value changes.
+
+  @method propertyDidChange
+  @for Ember
+  @param {Object} obj The object with the property that will change
+  @param {String} keyName The property key (or path) that will change.
+  @return {void}
+*/
+function propertyDidChange(obj, keyName) {
+  var m = metaFor(obj, false),
+      watching = m.watching[keyName] > 0 || keyName === 'length',
+      proto = m.proto,
+      desc = m.descs[keyName];
+
+  if (proto === obj) { return; }
+
+  // shouldn't this mean that we're watching this key?
+  if (desc && desc.didChange) { desc.didChange(obj, keyName); }
+  if (!watching && keyName !== 'length') { return; }
+
+  dependentKeysDidChange(obj, keyName, m);
+  chainsDidChange(obj, keyName, m);
+  Ember.notifyObservers(obj, keyName);
+}
+
+Ember.propertyDidChange = propertyDidChange;
+
+var NODE_STACK = [];
+
+/**
+  Tears down the meta on an object so that it can be garbage collected.
+  Multiple calls will have no effect.
+
+  @method destroy
+  @for Ember
+  @param {Object} obj  the object to destroy
+  @return {void}
+*/
+Ember.destroy = function (obj) {
+  var meta = obj[META_KEY], node, nodes, key, nodeObject;
+  if (meta) {
+    obj[META_KEY] = null;
+    // remove chainWatchers to remove circular references that would prevent GC
+    node = meta.chains;
+    if (node) {
+      NODE_STACK.push(node);
+      // process tree
+      while (NODE_STACK.length > 0) {
+        node = NODE_STACK.pop();
+        // push children
+        nodes = node._chains;
+        if (nodes) {
+          for (key in nodes) {
+            if (nodes.hasOwnProperty(key)) {
+              NODE_STACK.push(nodes[key]);
+            }
+          }
+        }
+        // remove chainWatcher in node object
+        if (node._watching) {
+          nodeObject = node._object;
+          if (nodeObject) {
+            removeChainWatcher(nodeObject, node._key, node);
+          }
+        }
+      }
+    }
+  }
+};
+
+})();
+
+
+
+(function() {
+/**
+@module ember-metal
+*/
+
+Ember.warn("The CP_DEFAULT_CACHEABLE flag has been removed and computed properties are always cached by default. Use `volatile` if you don't want caching.", Ember.ENV.CP_DEFAULT_CACHEABLE !== false);
+
+
+var get = Ember.get,
+    metaFor = Ember.meta,
+    guidFor = Ember.guidFor,
+    a_slice = [].slice,
+    o_create = Ember.create,
+    META_KEY = Ember.META_KEY,
+    watch = Ember.watch,
+    unwatch = Ember.unwatch;
+
+// ..........................................................
+// DEPENDENT KEYS
+//
+
+// data structure:
+//  meta.deps = {
+//   'depKey': {
+//     'keyName': count,
+//     __emberproto__: SRC_OBJ [to detect clones]
+//     },
+//   __emberproto__: SRC_OBJ
+//  }
+
+/*
+  This function returns a map of unique dependencies for a
+  given object and key.
+*/
+function keysForDep(obj, depsMeta, depKey) {
+  var keys = depsMeta[depKey];
+  if (!keys) {
+    // if there are no dependencies yet for a the given key
+    // create a new empty list of dependencies for the key
+    keys = depsMeta[depKey] = { __emberproto__: obj };
+  } else if (keys.__emberproto__ !== obj) {
+    // otherwise if the dependency list is inherited from
+    // a superclass, clone the hash
+    keys = depsMeta[depKey] = o_create(keys);
+    keys.__emberproto__ = obj;
+  }
+  return keys;
+}
+
+/* return obj[META_KEY].deps */
+function metaForDeps(obj, meta) {
+  var deps = meta.deps;
+  // If the current object has no dependencies...
+  if (!deps) {
+    // initialize the dependencies with a pointer back to
+    // the current object
+    deps = meta.deps = { __emberproto__: obj };
+  } else if (deps.__emberproto__ !== obj) {
+    // otherwise if the dependencies are inherited from the
+    // object's superclass, clone the deps
+    deps = meta.deps = o_create(deps);
+    deps.__emberproto__ = obj;
+  }
+  return deps;
+}
+
+function addDependentKeys(desc, obj, keyName, meta) {
+  // the descriptor has a list of dependent keys, so
+  // add all of its dependent keys.
+  var depKeys = desc._dependentKeys, depsMeta, idx, len, depKey, keys;
+  if (!depKeys) return;
+
+  depsMeta = metaForDeps(obj, meta);
+
+  for(idx = 0, len = depKeys.length; idx < len; idx++) {
+    depKey = depKeys[idx];
+    // Lookup keys meta for depKey
+    keys = keysForDep(obj, depsMeta, depKey);
+    // Increment the number of times depKey depends on keyName.
+    keys[keyName] = (keys[keyName] || 0) + 1;
+    // Watch the depKey
+    watch(obj, depKey);
+  }
+}
+
+function removeDependentKeys(desc, obj, keyName, meta) {
+  // the descriptor has a list of dependent keys, so
+  // add all of its dependent keys.
+  var depKeys = desc._dependentKeys, depsMeta, idx, len, depKey, keys;
+  if (!depKeys) return;
+
+  depsMeta = metaForDeps(obj, meta);
+
+  for(idx = 0, len = depKeys.length; idx < len; idx++) {
+    depKey = depKeys[idx];
+    // Lookup keys meta for depKey
+    keys = keysForDep(obj, depsMeta, depKey);
+    // Increment the number of times depKey depends on keyName.
+    keys[keyName] = (keys[keyName] || 0) - 1;
+    // Watch the depKey
+    unwatch(obj, depKey);
+  }
+}
+
+// ..........................................................
+// COMPUTED PROPERTY
+//
+
+/**
+  @class ComputedProperty
+  @namespace Ember
+  @extends Ember.Descriptor
+  @constructor
+*/
+function ComputedProperty(func, opts) {
+  this.func = func;
+  this._cacheable = (opts && opts.cacheable !== undefined) ? opts.cacheable : true;
+  this._dependentKeys = opts && opts.dependentKeys;
+}
+
+Ember.ComputedProperty = ComputedProperty;
+ComputedProperty.prototype = new Ember.Descriptor();
+
+var ComputedPropertyPrototype = ComputedProperty.prototype;
+
+/**
+  Call on a computed property to set it into cacheable mode.  When in this
+  mode the computed property will automatically cache the return value of
+  your function until one of the dependent keys changes.
+
+      MyApp.president = Ember.Object.create({
+        fullName: function() {
+          return this.get('firstName') + ' ' + this.get('lastName');
+
+          // After calculating the value of this function, Ember.js will
+          // return that value without re-executing this function until
+          // one of the dependent properties change.
+        }.property('firstName', 'lastName')
+      });
+
+  Properties are cacheable by default.
+
+  @method cacheable
+  @param {Boolean} aFlag optional set to false to disable caching
+  @chainable
+*/
+ComputedPropertyPrototype.cacheable = function(aFlag) {
+  this._cacheable = aFlag !== false;
+  return this;
+};
+
+/**
+  Call on a computed property to set it into non-cached mode.  When in this
+  mode the computed property will not automatically cache the return value.
+
+      MyApp.outsideService = Ember.Object.create({
+        value: function() {
+          return OutsideService.getValue();
+        }.property().volatile()
+      });
+
+  @method volatile
+  @chainable
+*/
+ComputedPropertyPrototype.volatile = function() {
+  return this.cacheable(false);
+};
+
+/**
+  Sets the dependent keys on this computed property.  Pass any number of
+  arguments containing key paths that this computed property depends on.
+
+      MyApp.president = Ember.Object.create({
+        fullName: Ember.computed(function() {
+          return this.get('firstName') + ' ' + this.get('lastName');
+
+          // Tell Ember.js that this computed property depends on firstName
+          // and lastName
+        }).property('firstName', 'lastName')
+      });
+
+  @method property
+  @param {String} path* zero or more property paths
+  @chainable
+*/
+ComputedPropertyPrototype.property = function() {
+  var args = [];
+  for (var i = 0, l = arguments.length; i < l; i++) {
+    args.push(arguments[i]);
+  }
+  this._dependentKeys = args;
+  return this;
+};
+
+/**
+  In some cases, you may want to annotate computed properties with additional
+  metadata about how they function or what values they operate on. For example,
+  computed property functions may close over variables that are then no longer
+  available for introspection.
+
+  You can pass a hash of these values to a computed property like this:
+
+      person: function() {
+        var personId = this.get('personId');
+        return App.Person.create({ id: personId });
+      }.property().meta({ type: App.Person })
+
+  The hash that you pass to the `meta()` function will be saved on the
+  computed property descriptor under the `_meta` key. Ember runtime
+  exposes a public API for retrieving these values from classes,
+  via the `metaForProperty()` function.
+
+  @method meta
+  @param {Hash} meta
+  @chainable
+*/
+
+ComputedPropertyPrototype.meta = function(meta) {
+  if (arguments.length === 0) {
+    return this._meta || {};
+  } else {
+    this._meta = meta;
+    return this;
+  }
+};
+
+/* impl descriptor API */
+ComputedPropertyPrototype.willWatch = function(obj, keyName) {
+  // watch already creates meta for this instance
+  var meta = obj[META_KEY];
+  Ember.assert('watch should have setup meta to be writable', meta.source === obj);
+  if (!(keyName in meta.cache)) {
+    addDependentKeys(this, obj, keyName, meta);
+  }
+};
+
+ComputedPropertyPrototype.didUnwatch = function(obj, keyName) {
+  var meta = obj[META_KEY];
+  Ember.assert('unwatch should have setup meta to be writable', meta.source === obj);
+  if (!(keyName in meta.cache)) {
+    // unwatch already creates meta for this instance
+    removeDependentKeys(this, obj, keyName, meta);
+  }
+};
+
+/* impl descriptor API */
+ComputedPropertyPrototype.didChange = function(obj, keyName) {
+  // _suspended is set via a CP.set to ensure we don't clear
+  // the cached value set by the setter
+  if (this._cacheable && this._suspended !== obj) {
+    var meta = metaFor(obj);
+    if (keyName in meta.cache) {
+      delete meta.cache[keyName];
+      if (!meta.watching[keyName]) {
+        removeDependentKeys(this, obj, keyName, meta);
+      }
+    }
+  }
+};
+
+/* impl descriptor API */
+ComputedPropertyPrototype.get = function(obj, keyName) {
+  var ret, cache, meta;
+  if (this._cacheable) {
+    meta = metaFor(obj);
+    cache = meta.cache;
+    if (keyName in cache) { return cache[keyName]; }
+    ret = cache[keyName] = this.func.call(obj, keyName);
+    if (!meta.watching[keyName]) {
+      addDependentKeys(this, obj, keyName, meta);
+    }
+  } else {
+    ret = this.func.call(obj, keyName);
+  }
+  return ret;
+};
+
+/* impl descriptor API */
+ComputedPropertyPrototype.set = function(obj, keyName, value) {
+  var cacheable = this._cacheable,
+      meta = metaFor(obj, cacheable),
+      watched = meta.watching[keyName],
+      oldSuspended = this._suspended,
+      hadCachedValue = false,
+      ret;
+  this._suspended = obj;
+  try {
+    ret = this.func.call(obj, keyName, value);
+

[... 19933 lines stripped ...]


Mime
View raw message