| 123456789101112131415161718192021222324252627282930313233343536373839404142 | define(['./_setup', './isFunction', './_has'], function (_setup, isFunction, _has) {  // Internal helper to create a simple lookup structure.  // `collectNonEnumProps` used to depend on `_.contains`, but this led to  // circular imports. `emulatedSet` is a one-off solution that only works for  // arrays of strings.  function emulatedSet(keys) {    var hash = {};    for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;    return {      contains: function(key) { return hash[key] === true; },      push: function(key) {        hash[key] = true;        return keys.push(key);      }    };  }  // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't  // be iterated by `for key in ...` and thus missed. Extends `keys` in place if  // needed.  function collectNonEnumProps(obj, keys) {    keys = emulatedSet(keys);    var nonEnumIdx = _setup.nonEnumerableProps.length;    var constructor = obj.constructor;    var proto = isFunction(constructor) && constructor.prototype || _setup.ObjProto;    // Constructor is a special case.    var prop = 'constructor';    if (_has(obj, prop) && !keys.contains(prop)) keys.push(prop);    while (nonEnumIdx--) {      prop = _setup.nonEnumerableProps[nonEnumIdx];      if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {        keys.push(prop);      }    }  }  return collectNonEnumProps;});
 |