server/php/basic/public_html/static/lib/lodash/lodash.js
changeset 442 adb907bba956
child 456 a3bf10beb710
equal deleted inserted replaced
441:4732f078d0fe 442:adb907bba956
       
     1 /**
       
     2  * @license
       
     3  * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
       
     4  * Build: `lodash modern -o ./dist/lodash.js`
       
     5  * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
       
     6  * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
       
     7  * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
       
     8  * Available under MIT license <http://lodash.com/license>
       
     9  */
       
    10 ;(function() {
       
    11 
       
    12   /** Used as a safe reference for `undefined` in pre ES5 environments */
       
    13   var undefined;
       
    14 
       
    15   /** Used to pool arrays and objects used internally */
       
    16   var arrayPool = [],
       
    17       objectPool = [];
       
    18 
       
    19   /** Used to generate unique IDs */
       
    20   var idCounter = 0;
       
    21 
       
    22   /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
       
    23   var keyPrefix = +new Date + '';
       
    24 
       
    25   /** Used as the size when optimizations are enabled for large arrays */
       
    26   var largeArraySize = 75;
       
    27 
       
    28   /** Used as the max size of the `arrayPool` and `objectPool` */
       
    29   var maxPoolSize = 40;
       
    30 
       
    31   /** Used to detect and test whitespace */
       
    32   var whitespace = (
       
    33     // whitespace
       
    34     ' \t\x0B\f\xA0\ufeff' +
       
    35 
       
    36     // line terminators
       
    37     '\n\r\u2028\u2029' +
       
    38 
       
    39     // unicode category "Zs" space separators
       
    40     '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
       
    41   );
       
    42 
       
    43   /** Used to match empty string literals in compiled template source */
       
    44   var reEmptyStringLeading = /\b__p \+= '';/g,
       
    45       reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
       
    46       reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
       
    47 
       
    48   /**
       
    49    * Used to match ES6 template delimiters
       
    50    * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
       
    51    */
       
    52   var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
       
    53 
       
    54   /** Used to match regexp flags from their coerced string values */
       
    55   var reFlags = /\w*$/;
       
    56 
       
    57   /** Used to detected named functions */
       
    58   var reFuncName = /^\s*function[ \n\r\t]+\w/;
       
    59 
       
    60   /** Used to match "interpolate" template delimiters */
       
    61   var reInterpolate = /<%=([\s\S]+?)%>/g;
       
    62 
       
    63   /** Used to match leading whitespace and zeros to be removed */
       
    64   var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
       
    65 
       
    66   /** Used to ensure capturing order of template delimiters */
       
    67   var reNoMatch = /($^)/;
       
    68 
       
    69   /** Used to detect functions containing a `this` reference */
       
    70   var reThis = /\bthis\b/;
       
    71 
       
    72   /** Used to match unescaped characters in compiled string literals */
       
    73   var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
       
    74 
       
    75   /** Used to assign default `context` object properties */
       
    76   var contextProps = [
       
    77     'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object',
       
    78     'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
       
    79     'parseInt', 'setTimeout'
       
    80   ];
       
    81 
       
    82   /** Used to make template sourceURLs easier to identify */
       
    83   var templateCounter = 0;
       
    84 
       
    85   /** `Object#toString` result shortcuts */
       
    86   var argsClass = '[object Arguments]',
       
    87       arrayClass = '[object Array]',
       
    88       boolClass = '[object Boolean]',
       
    89       dateClass = '[object Date]',
       
    90       funcClass = '[object Function]',
       
    91       numberClass = '[object Number]',
       
    92       objectClass = '[object Object]',
       
    93       regexpClass = '[object RegExp]',
       
    94       stringClass = '[object String]';
       
    95 
       
    96   /** Used to identify object classifications that `_.clone` supports */
       
    97   var cloneableClasses = {};
       
    98   cloneableClasses[funcClass] = false;
       
    99   cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
       
   100   cloneableClasses[boolClass] = cloneableClasses[dateClass] =
       
   101   cloneableClasses[numberClass] = cloneableClasses[objectClass] =
       
   102   cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
       
   103 
       
   104   /** Used as an internal `_.debounce` options object */
       
   105   var debounceOptions = {
       
   106     'leading': false,
       
   107     'maxWait': 0,
       
   108     'trailing': false
       
   109   };
       
   110 
       
   111   /** Used as the property descriptor for `__bindData__` */
       
   112   var descriptor = {
       
   113     'configurable': false,
       
   114     'enumerable': false,
       
   115     'value': null,
       
   116     'writable': false
       
   117   };
       
   118 
       
   119   /** Used to determine if values are of the language type Object */
       
   120   var objectTypes = {
       
   121     'boolean': false,
       
   122     'function': true,
       
   123     'object': true,
       
   124     'number': false,
       
   125     'string': false,
       
   126     'undefined': false
       
   127   };
       
   128 
       
   129   /** Used to escape characters for inclusion in compiled string literals */
       
   130   var stringEscapes = {
       
   131     '\\': '\\',
       
   132     "'": "'",
       
   133     '\n': 'n',
       
   134     '\r': 'r',
       
   135     '\t': 't',
       
   136     '\u2028': 'u2028',
       
   137     '\u2029': 'u2029'
       
   138   };
       
   139 
       
   140   /** Used as a reference to the global object */
       
   141   var root = (objectTypes[typeof window] && window) || this;
       
   142 
       
   143   /** Detect free variable `exports` */
       
   144   var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
       
   145 
       
   146   /** Detect free variable `module` */
       
   147   var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
       
   148 
       
   149   /** Detect the popular CommonJS extension `module.exports` */
       
   150   var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
       
   151 
       
   152   /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
       
   153   var freeGlobal = objectTypes[typeof global] && global;
       
   154   if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
       
   155     root = freeGlobal;
       
   156   }
       
   157 
       
   158   /*--------------------------------------------------------------------------*/
       
   159 
       
   160   /**
       
   161    * The base implementation of `_.indexOf` without support for binary searches
       
   162    * or `fromIndex` constraints.
       
   163    *
       
   164    * @private
       
   165    * @param {Array} array The array to search.
       
   166    * @param {*} value The value to search for.
       
   167    * @param {number} [fromIndex=0] The index to search from.
       
   168    * @returns {number} Returns the index of the matched value or `-1`.
       
   169    */
       
   170   function baseIndexOf(array, value, fromIndex) {
       
   171     var index = (fromIndex || 0) - 1,
       
   172         length = array ? array.length : 0;
       
   173 
       
   174     while (++index < length) {
       
   175       if (array[index] === value) {
       
   176         return index;
       
   177       }
       
   178     }
       
   179     return -1;
       
   180   }
       
   181 
       
   182   /**
       
   183    * An implementation of `_.contains` for cache objects that mimics the return
       
   184    * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
       
   185    *
       
   186    * @private
       
   187    * @param {Object} cache The cache object to inspect.
       
   188    * @param {*} value The value to search for.
       
   189    * @returns {number} Returns `0` if `value` is found, else `-1`.
       
   190    */
       
   191   function cacheIndexOf(cache, value) {
       
   192     var type = typeof value;
       
   193     cache = cache.cache;
       
   194 
       
   195     if (type == 'boolean' || value == null) {
       
   196       return cache[value] ? 0 : -1;
       
   197     }
       
   198     if (type != 'number' && type != 'string') {
       
   199       type = 'object';
       
   200     }
       
   201     var key = type == 'number' ? value : keyPrefix + value;
       
   202     cache = (cache = cache[type]) && cache[key];
       
   203 
       
   204     return type == 'object'
       
   205       ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
       
   206       : (cache ? 0 : -1);
       
   207   }
       
   208 
       
   209   /**
       
   210    * Adds a given value to the corresponding cache object.
       
   211    *
       
   212    * @private
       
   213    * @param {*} value The value to add to the cache.
       
   214    */
       
   215   function cachePush(value) {
       
   216     var cache = this.cache,
       
   217         type = typeof value;
       
   218 
       
   219     if (type == 'boolean' || value == null) {
       
   220       cache[value] = true;
       
   221     } else {
       
   222       if (type != 'number' && type != 'string') {
       
   223         type = 'object';
       
   224       }
       
   225       var key = type == 'number' ? value : keyPrefix + value,
       
   226           typeCache = cache[type] || (cache[type] = {});
       
   227 
       
   228       if (type == 'object') {
       
   229         (typeCache[key] || (typeCache[key] = [])).push(value);
       
   230       } else {
       
   231         typeCache[key] = true;
       
   232       }
       
   233     }
       
   234   }
       
   235 
       
   236   /**
       
   237    * Used by `_.max` and `_.min` as the default callback when a given
       
   238    * collection is a string value.
       
   239    *
       
   240    * @private
       
   241    * @param {string} value The character to inspect.
       
   242    * @returns {number} Returns the code unit of given character.
       
   243    */
       
   244   function charAtCallback(value) {
       
   245     return value.charCodeAt(0);
       
   246   }
       
   247 
       
   248   /**
       
   249    * Used by `sortBy` to compare transformed `collection` elements, stable sorting
       
   250    * them in ascending order.
       
   251    *
       
   252    * @private
       
   253    * @param {Object} a The object to compare to `b`.
       
   254    * @param {Object} b The object to compare to `a`.
       
   255    * @returns {number} Returns the sort order indicator of `1` or `-1`.
       
   256    */
       
   257   function compareAscending(a, b) {
       
   258     var ac = a.criteria,
       
   259         bc = b.criteria,
       
   260         index = -1,
       
   261         length = ac.length;
       
   262 
       
   263     while (++index < length) {
       
   264       var value = ac[index],
       
   265           other = bc[index];
       
   266 
       
   267       if (value !== other) {
       
   268         if (value > other || typeof value == 'undefined') {
       
   269           return 1;
       
   270         }
       
   271         if (value < other || typeof other == 'undefined') {
       
   272           return -1;
       
   273         }
       
   274       }
       
   275     }
       
   276     // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
       
   277     // that causes it, under certain circumstances, to return the same value for
       
   278     // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
       
   279     //
       
   280     // This also ensures a stable sort in V8 and other engines.
       
   281     // See http://code.google.com/p/v8/issues/detail?id=90
       
   282     return a.index - b.index;
       
   283   }
       
   284 
       
   285   /**
       
   286    * Creates a cache object to optimize linear searches of large arrays.
       
   287    *
       
   288    * @private
       
   289    * @param {Array} [array=[]] The array to search.
       
   290    * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
       
   291    */
       
   292   function createCache(array) {
       
   293     var index = -1,
       
   294         length = array.length,
       
   295         first = array[0],
       
   296         mid = array[(length / 2) | 0],
       
   297         last = array[length - 1];
       
   298 
       
   299     if (first && typeof first == 'object' &&
       
   300         mid && typeof mid == 'object' && last && typeof last == 'object') {
       
   301       return false;
       
   302     }
       
   303     var cache = getObject();
       
   304     cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
       
   305 
       
   306     var result = getObject();
       
   307     result.array = array;
       
   308     result.cache = cache;
       
   309     result.push = cachePush;
       
   310 
       
   311     while (++index < length) {
       
   312       result.push(array[index]);
       
   313     }
       
   314     return result;
       
   315   }
       
   316 
       
   317   /**
       
   318    * Used by `template` to escape characters for inclusion in compiled
       
   319    * string literals.
       
   320    *
       
   321    * @private
       
   322    * @param {string} match The matched character to escape.
       
   323    * @returns {string} Returns the escaped character.
       
   324    */
       
   325   function escapeStringChar(match) {
       
   326     return '\\' + stringEscapes[match];
       
   327   }
       
   328 
       
   329   /**
       
   330    * Gets an array from the array pool or creates a new one if the pool is empty.
       
   331    *
       
   332    * @private
       
   333    * @returns {Array} The array from the pool.
       
   334    */
       
   335   function getArray() {
       
   336     return arrayPool.pop() || [];
       
   337   }
       
   338 
       
   339   /**
       
   340    * Gets an object from the object pool or creates a new one if the pool is empty.
       
   341    *
       
   342    * @private
       
   343    * @returns {Object} The object from the pool.
       
   344    */
       
   345   function getObject() {
       
   346     return objectPool.pop() || {
       
   347       'array': null,
       
   348       'cache': null,
       
   349       'criteria': null,
       
   350       'false': false,
       
   351       'index': 0,
       
   352       'null': false,
       
   353       'number': null,
       
   354       'object': null,
       
   355       'push': null,
       
   356       'string': null,
       
   357       'true': false,
       
   358       'undefined': false,
       
   359       'value': null
       
   360     };
       
   361   }
       
   362 
       
   363   /**
       
   364    * Releases the given array back to the array pool.
       
   365    *
       
   366    * @private
       
   367    * @param {Array} [array] The array to release.
       
   368    */
       
   369   function releaseArray(array) {
       
   370     array.length = 0;
       
   371     if (arrayPool.length < maxPoolSize) {
       
   372       arrayPool.push(array);
       
   373     }
       
   374   }
       
   375 
       
   376   /**
       
   377    * Releases the given object back to the object pool.
       
   378    *
       
   379    * @private
       
   380    * @param {Object} [object] The object to release.
       
   381    */
       
   382   function releaseObject(object) {
       
   383     var cache = object.cache;
       
   384     if (cache) {
       
   385       releaseObject(cache);
       
   386     }
       
   387     object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
       
   388     if (objectPool.length < maxPoolSize) {
       
   389       objectPool.push(object);
       
   390     }
       
   391   }
       
   392 
       
   393   /**
       
   394    * Slices the `collection` from the `start` index up to, but not including,
       
   395    * the `end` index.
       
   396    *
       
   397    * Note: This function is used instead of `Array#slice` to support node lists
       
   398    * in IE < 9 and to ensure dense arrays are returned.
       
   399    *
       
   400    * @private
       
   401    * @param {Array|Object|string} collection The collection to slice.
       
   402    * @param {number} start The start index.
       
   403    * @param {number} end The end index.
       
   404    * @returns {Array} Returns the new array.
       
   405    */
       
   406   function slice(array, start, end) {
       
   407     start || (start = 0);
       
   408     if (typeof end == 'undefined') {
       
   409       end = array ? array.length : 0;
       
   410     }
       
   411     var index = -1,
       
   412         length = end - start || 0,
       
   413         result = Array(length < 0 ? 0 : length);
       
   414 
       
   415     while (++index < length) {
       
   416       result[index] = array[start + index];
       
   417     }
       
   418     return result;
       
   419   }
       
   420 
       
   421   /*--------------------------------------------------------------------------*/
       
   422 
       
   423   /**
       
   424    * Create a new `lodash` function using the given context object.
       
   425    *
       
   426    * @static
       
   427    * @memberOf _
       
   428    * @category Utilities
       
   429    * @param {Object} [context=root] The context object.
       
   430    * @returns {Function} Returns the `lodash` function.
       
   431    */
       
   432   function runInContext(context) {
       
   433     // Avoid issues with some ES3 environments that attempt to use values, named
       
   434     // after built-in constructors like `Object`, for the creation of literals.
       
   435     // ES5 clears this up by stating that literals must use built-in constructors.
       
   436     // See http://es5.github.io/#x11.1.5.
       
   437     context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
       
   438 
       
   439     /** Native constructor references */
       
   440     var Array = context.Array,
       
   441         Boolean = context.Boolean,
       
   442         Date = context.Date,
       
   443         Function = context.Function,
       
   444         Math = context.Math,
       
   445         Number = context.Number,
       
   446         Object = context.Object,
       
   447         RegExp = context.RegExp,
       
   448         String = context.String,
       
   449         TypeError = context.TypeError;
       
   450 
       
   451     /**
       
   452      * Used for `Array` method references.
       
   453      *
       
   454      * Normally `Array.prototype` would suffice, however, using an array literal
       
   455      * avoids issues in Narwhal.
       
   456      */
       
   457     var arrayRef = [];
       
   458 
       
   459     /** Used for native method references */
       
   460     var objectProto = Object.prototype;
       
   461 
       
   462     /** Used to restore the original `_` reference in `noConflict` */
       
   463     var oldDash = context._;
       
   464 
       
   465     /** Used to resolve the internal [[Class]] of values */
       
   466     var toString = objectProto.toString;
       
   467 
       
   468     /** Used to detect if a method is native */
       
   469     var reNative = RegExp('^' +
       
   470       String(toString)
       
   471         .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
       
   472         .replace(/toString| for [^\]]+/g, '.*?') + '$'
       
   473     );
       
   474 
       
   475     /** Native method shortcuts */
       
   476     var ceil = Math.ceil,
       
   477         clearTimeout = context.clearTimeout,
       
   478         floor = Math.floor,
       
   479         fnToString = Function.prototype.toString,
       
   480         getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
       
   481         hasOwnProperty = objectProto.hasOwnProperty,
       
   482         push = arrayRef.push,
       
   483         setTimeout = context.setTimeout,
       
   484         splice = arrayRef.splice,
       
   485         unshift = arrayRef.unshift;
       
   486 
       
   487     /** Used to set meta data on functions */
       
   488     var defineProperty = (function() {
       
   489       // IE 8 only accepts DOM elements
       
   490       try {
       
   491         var o = {},
       
   492             func = isNative(func = Object.defineProperty) && func,
       
   493             result = func(o, o, o) && func;
       
   494       } catch(e) { }
       
   495       return result;
       
   496     }());
       
   497 
       
   498     /* Native method shortcuts for methods with the same name as other `lodash` methods */
       
   499     var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
       
   500         nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
       
   501         nativeIsFinite = context.isFinite,
       
   502         nativeIsNaN = context.isNaN,
       
   503         nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
       
   504         nativeMax = Math.max,
       
   505         nativeMin = Math.min,
       
   506         nativeParseInt = context.parseInt,
       
   507         nativeRandom = Math.random;
       
   508 
       
   509     /** Used to lookup a built-in constructor by [[Class]] */
       
   510     var ctorByClass = {};
       
   511     ctorByClass[arrayClass] = Array;
       
   512     ctorByClass[boolClass] = Boolean;
       
   513     ctorByClass[dateClass] = Date;
       
   514     ctorByClass[funcClass] = Function;
       
   515     ctorByClass[objectClass] = Object;
       
   516     ctorByClass[numberClass] = Number;
       
   517     ctorByClass[regexpClass] = RegExp;
       
   518     ctorByClass[stringClass] = String;
       
   519 
       
   520     /*--------------------------------------------------------------------------*/
       
   521 
       
   522     /**
       
   523      * Creates a `lodash` object which wraps the given value to enable intuitive
       
   524      * method chaining.
       
   525      *
       
   526      * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
       
   527      * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
       
   528      * and `unshift`
       
   529      *
       
   530      * Chaining is supported in custom builds as long as the `value` method is
       
   531      * implicitly or explicitly included in the build.
       
   532      *
       
   533      * The chainable wrapper functions are:
       
   534      * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
       
   535      * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
       
   536      * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
       
   537      * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
       
   538      * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
       
   539      * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
       
   540      * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
       
   541      * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
       
   542      * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
       
   543      * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
       
   544      * and `zip`
       
   545      *
       
   546      * The non-chainable wrapper functions are:
       
   547      * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
       
   548      * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
       
   549      * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
       
   550      * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
       
   551      * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
       
   552      * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
       
   553      * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
       
   554      * `template`, `unescape`, `uniqueId`, and `value`
       
   555      *
       
   556      * The wrapper functions `first` and `last` return wrapped values when `n` is
       
   557      * provided, otherwise they return unwrapped values.
       
   558      *
       
   559      * Explicit chaining can be enabled by using the `_.chain` method.
       
   560      *
       
   561      * @name _
       
   562      * @constructor
       
   563      * @category Chaining
       
   564      * @param {*} value The value to wrap in a `lodash` instance.
       
   565      * @returns {Object} Returns a `lodash` instance.
       
   566      * @example
       
   567      *
       
   568      * var wrapped = _([1, 2, 3]);
       
   569      *
       
   570      * // returns an unwrapped value
       
   571      * wrapped.reduce(function(sum, num) {
       
   572      *   return sum + num;
       
   573      * });
       
   574      * // => 6
       
   575      *
       
   576      * // returns a wrapped value
       
   577      * var squares = wrapped.map(function(num) {
       
   578      *   return num * num;
       
   579      * });
       
   580      *
       
   581      * _.isArray(squares);
       
   582      * // => false
       
   583      *
       
   584      * _.isArray(squares.value());
       
   585      * // => true
       
   586      */
       
   587     function lodash(value) {
       
   588       // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
       
   589       return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
       
   590        ? value
       
   591        : new lodashWrapper(value);
       
   592     }
       
   593 
       
   594     /**
       
   595      * A fast path for creating `lodash` wrapper objects.
       
   596      *
       
   597      * @private
       
   598      * @param {*} value The value to wrap in a `lodash` instance.
       
   599      * @param {boolean} chainAll A flag to enable chaining for all methods
       
   600      * @returns {Object} Returns a `lodash` instance.
       
   601      */
       
   602     function lodashWrapper(value, chainAll) {
       
   603       this.__chain__ = !!chainAll;
       
   604       this.__wrapped__ = value;
       
   605     }
       
   606     // ensure `new lodashWrapper` is an instance of `lodash`
       
   607     lodashWrapper.prototype = lodash.prototype;
       
   608 
       
   609     /**
       
   610      * An object used to flag environments features.
       
   611      *
       
   612      * @static
       
   613      * @memberOf _
       
   614      * @type Object
       
   615      */
       
   616     var support = lodash.support = {};
       
   617 
       
   618     /**
       
   619      * Detect if functions can be decompiled by `Function#toString`
       
   620      * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
       
   621      *
       
   622      * @memberOf _.support
       
   623      * @type boolean
       
   624      */
       
   625     support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
       
   626 
       
   627     /**
       
   628      * Detect if `Function#name` is supported (all but IE).
       
   629      *
       
   630      * @memberOf _.support
       
   631      * @type boolean
       
   632      */
       
   633     support.funcNames = typeof Function.name == 'string';
       
   634 
       
   635     /**
       
   636      * By default, the template delimiters used by Lo-Dash are similar to those in
       
   637      * embedded Ruby (ERB). Change the following template settings to use alternative
       
   638      * delimiters.
       
   639      *
       
   640      * @static
       
   641      * @memberOf _
       
   642      * @type Object
       
   643      */
       
   644     lodash.templateSettings = {
       
   645 
       
   646       /**
       
   647        * Used to detect `data` property values to be HTML-escaped.
       
   648        *
       
   649        * @memberOf _.templateSettings
       
   650        * @type RegExp
       
   651        */
       
   652       'escape': /<%-([\s\S]+?)%>/g,
       
   653 
       
   654       /**
       
   655        * Used to detect code to be evaluated.
       
   656        *
       
   657        * @memberOf _.templateSettings
       
   658        * @type RegExp
       
   659        */
       
   660       'evaluate': /<%([\s\S]+?)%>/g,
       
   661 
       
   662       /**
       
   663        * Used to detect `data` property values to inject.
       
   664        *
       
   665        * @memberOf _.templateSettings
       
   666        * @type RegExp
       
   667        */
       
   668       'interpolate': reInterpolate,
       
   669 
       
   670       /**
       
   671        * Used to reference the data object in the template text.
       
   672        *
       
   673        * @memberOf _.templateSettings
       
   674        * @type string
       
   675        */
       
   676       'variable': '',
       
   677 
       
   678       /**
       
   679        * Used to import variables into the compiled template.
       
   680        *
       
   681        * @memberOf _.templateSettings
       
   682        * @type Object
       
   683        */
       
   684       'imports': {
       
   685 
       
   686         /**
       
   687          * A reference to the `lodash` function.
       
   688          *
       
   689          * @memberOf _.templateSettings.imports
       
   690          * @type Function
       
   691          */
       
   692         '_': lodash
       
   693       }
       
   694     };
       
   695 
       
   696     /*--------------------------------------------------------------------------*/
       
   697 
       
   698     /**
       
   699      * The base implementation of `_.bind` that creates the bound function and
       
   700      * sets its meta data.
       
   701      *
       
   702      * @private
       
   703      * @param {Array} bindData The bind data array.
       
   704      * @returns {Function} Returns the new bound function.
       
   705      */
       
   706     function baseBind(bindData) {
       
   707       var func = bindData[0],
       
   708           partialArgs = bindData[2],
       
   709           thisArg = bindData[4];
       
   710 
       
   711       function bound() {
       
   712         // `Function#bind` spec
       
   713         // http://es5.github.io/#x15.3.4.5
       
   714         if (partialArgs) {
       
   715           // avoid `arguments` object deoptimizations by using `slice` instead
       
   716           // of `Array.prototype.slice.call` and not assigning `arguments` to a
       
   717           // variable as a ternary expression
       
   718           var args = slice(partialArgs);
       
   719           push.apply(args, arguments);
       
   720         }
       
   721         // mimic the constructor's `return` behavior
       
   722         // http://es5.github.io/#x13.2.2
       
   723         if (this instanceof bound) {
       
   724           // ensure `new bound` is an instance of `func`
       
   725           var thisBinding = baseCreate(func.prototype),
       
   726               result = func.apply(thisBinding, args || arguments);
       
   727           return isObject(result) ? result : thisBinding;
       
   728         }
       
   729         return func.apply(thisArg, args || arguments);
       
   730       }
       
   731       setBindData(bound, bindData);
       
   732       return bound;
       
   733     }
       
   734 
       
   735     /**
       
   736      * The base implementation of `_.clone` without argument juggling or support
       
   737      * for `thisArg` binding.
       
   738      *
       
   739      * @private
       
   740      * @param {*} value The value to clone.
       
   741      * @param {boolean} [isDeep=false] Specify a deep clone.
       
   742      * @param {Function} [callback] The function to customize cloning values.
       
   743      * @param {Array} [stackA=[]] Tracks traversed source objects.
       
   744      * @param {Array} [stackB=[]] Associates clones with source counterparts.
       
   745      * @returns {*} Returns the cloned value.
       
   746      */
       
   747     function baseClone(value, isDeep, callback, stackA, stackB) {
       
   748       if (callback) {
       
   749         var result = callback(value);
       
   750         if (typeof result != 'undefined') {
       
   751           return result;
       
   752         }
       
   753       }
       
   754       // inspect [[Class]]
       
   755       var isObj = isObject(value);
       
   756       if (isObj) {
       
   757         var className = toString.call(value);
       
   758         if (!cloneableClasses[className]) {
       
   759           return value;
       
   760         }
       
   761         var ctor = ctorByClass[className];
       
   762         switch (className) {
       
   763           case boolClass:
       
   764           case dateClass:
       
   765             return new ctor(+value);
       
   766 
       
   767           case numberClass:
       
   768           case stringClass:
       
   769             return new ctor(value);
       
   770 
       
   771           case regexpClass:
       
   772             result = ctor(value.source, reFlags.exec(value));
       
   773             result.lastIndex = value.lastIndex;
       
   774             return result;
       
   775         }
       
   776       } else {
       
   777         return value;
       
   778       }
       
   779       var isArr = isArray(value);
       
   780       if (isDeep) {
       
   781         // check for circular references and return corresponding clone
       
   782         var initedStack = !stackA;
       
   783         stackA || (stackA = getArray());
       
   784         stackB || (stackB = getArray());
       
   785 
       
   786         var length = stackA.length;
       
   787         while (length--) {
       
   788           if (stackA[length] == value) {
       
   789             return stackB[length];
       
   790           }
       
   791         }
       
   792         result = isArr ? ctor(value.length) : {};
       
   793       }
       
   794       else {
       
   795         result = isArr ? slice(value) : assign({}, value);
       
   796       }
       
   797       // add array properties assigned by `RegExp#exec`
       
   798       if (isArr) {
       
   799         if (hasOwnProperty.call(value, 'index')) {
       
   800           result.index = value.index;
       
   801         }
       
   802         if (hasOwnProperty.call(value, 'input')) {
       
   803           result.input = value.input;
       
   804         }
       
   805       }
       
   806       // exit for shallow clone
       
   807       if (!isDeep) {
       
   808         return result;
       
   809       }
       
   810       // add the source value to the stack of traversed objects
       
   811       // and associate it with its clone
       
   812       stackA.push(value);
       
   813       stackB.push(result);
       
   814 
       
   815       // recursively populate clone (susceptible to call stack limits)
       
   816       (isArr ? forEach : forOwn)(value, function(objValue, key) {
       
   817         result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
       
   818       });
       
   819 
       
   820       if (initedStack) {
       
   821         releaseArray(stackA);
       
   822         releaseArray(stackB);
       
   823       }
       
   824       return result;
       
   825     }
       
   826 
       
   827     /**
       
   828      * The base implementation of `_.create` without support for assigning
       
   829      * properties to the created object.
       
   830      *
       
   831      * @private
       
   832      * @param {Object} prototype The object to inherit from.
       
   833      * @returns {Object} Returns the new object.
       
   834      */
       
   835     function baseCreate(prototype, properties) {
       
   836       return isObject(prototype) ? nativeCreate(prototype) : {};
       
   837     }
       
   838     // fallback for browsers without `Object.create`
       
   839     if (!nativeCreate) {
       
   840       baseCreate = (function() {
       
   841         function Object() {}
       
   842         return function(prototype) {
       
   843           if (isObject(prototype)) {
       
   844             Object.prototype = prototype;
       
   845             var result = new Object;
       
   846             Object.prototype = null;
       
   847           }
       
   848           return result || context.Object();
       
   849         };
       
   850       }());
       
   851     }
       
   852 
       
   853     /**
       
   854      * The base implementation of `_.createCallback` without support for creating
       
   855      * "_.pluck" or "_.where" style callbacks.
       
   856      *
       
   857      * @private
       
   858      * @param {*} [func=identity] The value to convert to a callback.
       
   859      * @param {*} [thisArg] The `this` binding of the created callback.
       
   860      * @param {number} [argCount] The number of arguments the callback accepts.
       
   861      * @returns {Function} Returns a callback function.
       
   862      */
       
   863     function baseCreateCallback(func, thisArg, argCount) {
       
   864       if (typeof func != 'function') {
       
   865         return identity;
       
   866       }
       
   867       // exit early for no `thisArg` or already bound by `Function#bind`
       
   868       if (typeof thisArg == 'undefined' || !('prototype' in func)) {
       
   869         return func;
       
   870       }
       
   871       var bindData = func.__bindData__;
       
   872       if (typeof bindData == 'undefined') {
       
   873         if (support.funcNames) {
       
   874           bindData = !func.name;
       
   875         }
       
   876         bindData = bindData || !support.funcDecomp;
       
   877         if (!bindData) {
       
   878           var source = fnToString.call(func);
       
   879           if (!support.funcNames) {
       
   880             bindData = !reFuncName.test(source);
       
   881           }
       
   882           if (!bindData) {
       
   883             // checks if `func` references the `this` keyword and stores the result
       
   884             bindData = reThis.test(source);
       
   885             setBindData(func, bindData);
       
   886           }
       
   887         }
       
   888       }
       
   889       // exit early if there are no `this` references or `func` is bound
       
   890       if (bindData === false || (bindData !== true && bindData[1] & 1)) {
       
   891         return func;
       
   892       }
       
   893       switch (argCount) {
       
   894         case 1: return function(value) {
       
   895           return func.call(thisArg, value);
       
   896         };
       
   897         case 2: return function(a, b) {
       
   898           return func.call(thisArg, a, b);
       
   899         };
       
   900         case 3: return function(value, index, collection) {
       
   901           return func.call(thisArg, value, index, collection);
       
   902         };
       
   903         case 4: return function(accumulator, value, index, collection) {
       
   904           return func.call(thisArg, accumulator, value, index, collection);
       
   905         };
       
   906       }
       
   907       return bind(func, thisArg);
       
   908     }
       
   909 
       
   910     /**
       
   911      * The base implementation of `createWrapper` that creates the wrapper and
       
   912      * sets its meta data.
       
   913      *
       
   914      * @private
       
   915      * @param {Array} bindData The bind data array.
       
   916      * @returns {Function} Returns the new function.
       
   917      */
       
   918     function baseCreateWrapper(bindData) {
       
   919       var func = bindData[0],
       
   920           bitmask = bindData[1],
       
   921           partialArgs = bindData[2],
       
   922           partialRightArgs = bindData[3],
       
   923           thisArg = bindData[4],
       
   924           arity = bindData[5];
       
   925 
       
   926       var isBind = bitmask & 1,
       
   927           isBindKey = bitmask & 2,
       
   928           isCurry = bitmask & 4,
       
   929           isCurryBound = bitmask & 8,
       
   930           key = func;
       
   931 
       
   932       function bound() {
       
   933         var thisBinding = isBind ? thisArg : this;
       
   934         if (partialArgs) {
       
   935           var args = slice(partialArgs);
       
   936           push.apply(args, arguments);
       
   937         }
       
   938         if (partialRightArgs || isCurry) {
       
   939           args || (args = slice(arguments));
       
   940           if (partialRightArgs) {
       
   941             push.apply(args, partialRightArgs);
       
   942           }
       
   943           if (isCurry && args.length < arity) {
       
   944             bitmask |= 16 & ~32;
       
   945             return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
       
   946           }
       
   947         }
       
   948         args || (args = arguments);
       
   949         if (isBindKey) {
       
   950           func = thisBinding[key];
       
   951         }
       
   952         if (this instanceof bound) {
       
   953           thisBinding = baseCreate(func.prototype);
       
   954           var result = func.apply(thisBinding, args);
       
   955           return isObject(result) ? result : thisBinding;
       
   956         }
       
   957         return func.apply(thisBinding, args);
       
   958       }
       
   959       setBindData(bound, bindData);
       
   960       return bound;
       
   961     }
       
   962 
       
   963     /**
       
   964      * The base implementation of `_.difference` that accepts a single array
       
   965      * of values to exclude.
       
   966      *
       
   967      * @private
       
   968      * @param {Array} array The array to process.
       
   969      * @param {Array} [values] The array of values to exclude.
       
   970      * @returns {Array} Returns a new array of filtered values.
       
   971      */
       
   972     function baseDifference(array, values) {
       
   973       var index = -1,
       
   974           indexOf = getIndexOf(),
       
   975           length = array ? array.length : 0,
       
   976           isLarge = length >= largeArraySize && indexOf === baseIndexOf,
       
   977           result = [];
       
   978 
       
   979       if (isLarge) {
       
   980         var cache = createCache(values);
       
   981         if (cache) {
       
   982           indexOf = cacheIndexOf;
       
   983           values = cache;
       
   984         } else {
       
   985           isLarge = false;
       
   986         }
       
   987       }
       
   988       while (++index < length) {
       
   989         var value = array[index];
       
   990         if (indexOf(values, value) < 0) {
       
   991           result.push(value);
       
   992         }
       
   993       }
       
   994       if (isLarge) {
       
   995         releaseObject(values);
       
   996       }
       
   997       return result;
       
   998     }
       
   999 
       
  1000     /**
       
  1001      * The base implementation of `_.flatten` without support for callback
       
  1002      * shorthands or `thisArg` binding.
       
  1003      *
       
  1004      * @private
       
  1005      * @param {Array} array The array to flatten.
       
  1006      * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
       
  1007      * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
       
  1008      * @param {number} [fromIndex=0] The index to start from.
       
  1009      * @returns {Array} Returns a new flattened array.
       
  1010      */
       
  1011     function baseFlatten(array, isShallow, isStrict, fromIndex) {
       
  1012       var index = (fromIndex || 0) - 1,
       
  1013           length = array ? array.length : 0,
       
  1014           result = [];
       
  1015 
       
  1016       while (++index < length) {
       
  1017         var value = array[index];
       
  1018 
       
  1019         if (value && typeof value == 'object' && typeof value.length == 'number'
       
  1020             && (isArray(value) || isArguments(value))) {
       
  1021           // recursively flatten arrays (susceptible to call stack limits)
       
  1022           if (!isShallow) {
       
  1023             value = baseFlatten(value, isShallow, isStrict);
       
  1024           }
       
  1025           var valIndex = -1,
       
  1026               valLength = value.length,
       
  1027               resIndex = result.length;
       
  1028 
       
  1029           result.length += valLength;
       
  1030           while (++valIndex < valLength) {
       
  1031             result[resIndex++] = value[valIndex];
       
  1032           }
       
  1033         } else if (!isStrict) {
       
  1034           result.push(value);
       
  1035         }
       
  1036       }
       
  1037       return result;
       
  1038     }
       
  1039 
       
  1040     /**
       
  1041      * The base implementation of `_.isEqual`, without support for `thisArg` binding,
       
  1042      * that allows partial "_.where" style comparisons.
       
  1043      *
       
  1044      * @private
       
  1045      * @param {*} a The value to compare.
       
  1046      * @param {*} b The other value to compare.
       
  1047      * @param {Function} [callback] The function to customize comparing values.
       
  1048      * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
       
  1049      * @param {Array} [stackA=[]] Tracks traversed `a` objects.
       
  1050      * @param {Array} [stackB=[]] Tracks traversed `b` objects.
       
  1051      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
       
  1052      */
       
  1053     function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
       
  1054       // used to indicate that when comparing objects, `a` has at least the properties of `b`
       
  1055       if (callback) {
       
  1056         var result = callback(a, b);
       
  1057         if (typeof result != 'undefined') {
       
  1058           return !!result;
       
  1059         }
       
  1060       }
       
  1061       // exit early for identical values
       
  1062       if (a === b) {
       
  1063         // treat `+0` vs. `-0` as not equal
       
  1064         return a !== 0 || (1 / a == 1 / b);
       
  1065       }
       
  1066       var type = typeof a,
       
  1067           otherType = typeof b;
       
  1068 
       
  1069       // exit early for unlike primitive values
       
  1070       if (a === a &&
       
  1071           !(a && objectTypes[type]) &&
       
  1072           !(b && objectTypes[otherType])) {
       
  1073         return false;
       
  1074       }
       
  1075       // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
       
  1076       // http://es5.github.io/#x15.3.4.4
       
  1077       if (a == null || b == null) {
       
  1078         return a === b;
       
  1079       }
       
  1080       // compare [[Class]] names
       
  1081       var className = toString.call(a),
       
  1082           otherClass = toString.call(b);
       
  1083 
       
  1084       if (className == argsClass) {
       
  1085         className = objectClass;
       
  1086       }
       
  1087       if (otherClass == argsClass) {
       
  1088         otherClass = objectClass;
       
  1089       }
       
  1090       if (className != otherClass) {
       
  1091         return false;
       
  1092       }
       
  1093       switch (className) {
       
  1094         case boolClass:
       
  1095         case dateClass:
       
  1096           // coerce dates and booleans to numbers, dates to milliseconds and booleans
       
  1097           // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
       
  1098           return +a == +b;
       
  1099 
       
  1100         case numberClass:
       
  1101           // treat `NaN` vs. `NaN` as equal
       
  1102           return (a != +a)
       
  1103             ? b != +b
       
  1104             // but treat `+0` vs. `-0` as not equal
       
  1105             : (a == 0 ? (1 / a == 1 / b) : a == +b);
       
  1106 
       
  1107         case regexpClass:
       
  1108         case stringClass:
       
  1109           // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
       
  1110           // treat string primitives and their corresponding object instances as equal
       
  1111           return a == String(b);
       
  1112       }
       
  1113       var isArr = className == arrayClass;
       
  1114       if (!isArr) {
       
  1115         // unwrap any `lodash` wrapped values
       
  1116         var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
       
  1117             bWrapped = hasOwnProperty.call(b, '__wrapped__');
       
  1118 
       
  1119         if (aWrapped || bWrapped) {
       
  1120           return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
       
  1121         }
       
  1122         // exit for functions and DOM nodes
       
  1123         if (className != objectClass) {
       
  1124           return false;
       
  1125         }
       
  1126         // in older versions of Opera, `arguments` objects have `Array` constructors
       
  1127         var ctorA = a.constructor,
       
  1128             ctorB = b.constructor;
       
  1129 
       
  1130         // non `Object` object instances with different constructors are not equal
       
  1131         if (ctorA != ctorB &&
       
  1132               !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
       
  1133               ('constructor' in a && 'constructor' in b)
       
  1134             ) {
       
  1135           return false;
       
  1136         }
       
  1137       }
       
  1138       // assume cyclic structures are equal
       
  1139       // the algorithm for detecting cyclic structures is adapted from ES 5.1
       
  1140       // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
       
  1141       var initedStack = !stackA;
       
  1142       stackA || (stackA = getArray());
       
  1143       stackB || (stackB = getArray());
       
  1144 
       
  1145       var length = stackA.length;
       
  1146       while (length--) {
       
  1147         if (stackA[length] == a) {
       
  1148           return stackB[length] == b;
       
  1149         }
       
  1150       }
       
  1151       var size = 0;
       
  1152       result = true;
       
  1153 
       
  1154       // add `a` and `b` to the stack of traversed objects
       
  1155       stackA.push(a);
       
  1156       stackB.push(b);
       
  1157 
       
  1158       // recursively compare objects and arrays (susceptible to call stack limits)
       
  1159       if (isArr) {
       
  1160         // compare lengths to determine if a deep comparison is necessary
       
  1161         length = a.length;
       
  1162         size = b.length;
       
  1163         result = size == length;
       
  1164 
       
  1165         if (result || isWhere) {
       
  1166           // deep compare the contents, ignoring non-numeric properties
       
  1167           while (size--) {
       
  1168             var index = length,
       
  1169                 value = b[size];
       
  1170 
       
  1171             if (isWhere) {
       
  1172               while (index--) {
       
  1173                 if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
       
  1174                   break;
       
  1175                 }
       
  1176               }
       
  1177             } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
       
  1178               break;
       
  1179             }
       
  1180           }
       
  1181         }
       
  1182       }
       
  1183       else {
       
  1184         // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
       
  1185         // which, in this case, is more costly
       
  1186         forIn(b, function(value, key, b) {
       
  1187           if (hasOwnProperty.call(b, key)) {
       
  1188             // count the number of properties.
       
  1189             size++;
       
  1190             // deep compare each property value.
       
  1191             return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
       
  1192           }
       
  1193         });
       
  1194 
       
  1195         if (result && !isWhere) {
       
  1196           // ensure both objects have the same number of properties
       
  1197           forIn(a, function(value, key, a) {
       
  1198             if (hasOwnProperty.call(a, key)) {
       
  1199               // `size` will be `-1` if `a` has more properties than `b`
       
  1200               return (result = --size > -1);
       
  1201             }
       
  1202           });
       
  1203         }
       
  1204       }
       
  1205       stackA.pop();
       
  1206       stackB.pop();
       
  1207 
       
  1208       if (initedStack) {
       
  1209         releaseArray(stackA);
       
  1210         releaseArray(stackB);
       
  1211       }
       
  1212       return result;
       
  1213     }
       
  1214 
       
  1215     /**
       
  1216      * The base implementation of `_.merge` without argument juggling or support
       
  1217      * for `thisArg` binding.
       
  1218      *
       
  1219      * @private
       
  1220      * @param {Object} object The destination object.
       
  1221      * @param {Object} source The source object.
       
  1222      * @param {Function} [callback] The function to customize merging properties.
       
  1223      * @param {Array} [stackA=[]] Tracks traversed source objects.
       
  1224      * @param {Array} [stackB=[]] Associates values with source counterparts.
       
  1225      */
       
  1226     function baseMerge(object, source, callback, stackA, stackB) {
       
  1227       (isArray(source) ? forEach : forOwn)(source, function(source, key) {
       
  1228         var found,
       
  1229             isArr,
       
  1230             result = source,
       
  1231             value = object[key];
       
  1232 
       
  1233         if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
       
  1234           // avoid merging previously merged cyclic sources
       
  1235           var stackLength = stackA.length;
       
  1236           while (stackLength--) {
       
  1237             if ((found = stackA[stackLength] == source)) {
       
  1238               value = stackB[stackLength];
       
  1239               break;
       
  1240             }
       
  1241           }
       
  1242           if (!found) {
       
  1243             var isShallow;
       
  1244             if (callback) {
       
  1245               result = callback(value, source);
       
  1246               if ((isShallow = typeof result != 'undefined')) {
       
  1247                 value = result;
       
  1248               }
       
  1249             }
       
  1250             if (!isShallow) {
       
  1251               value = isArr
       
  1252                 ? (isArray(value) ? value : [])
       
  1253                 : (isPlainObject(value) ? value : {});
       
  1254             }
       
  1255             // add `source` and associated `value` to the stack of traversed objects
       
  1256             stackA.push(source);
       
  1257             stackB.push(value);
       
  1258 
       
  1259             // recursively merge objects and arrays (susceptible to call stack limits)
       
  1260             if (!isShallow) {
       
  1261               baseMerge(value, source, callback, stackA, stackB);
       
  1262             }
       
  1263           }
       
  1264         }
       
  1265         else {
       
  1266           if (callback) {
       
  1267             result = callback(value, source);
       
  1268             if (typeof result == 'undefined') {
       
  1269               result = source;
       
  1270             }
       
  1271           }
       
  1272           if (typeof result != 'undefined') {
       
  1273             value = result;
       
  1274           }
       
  1275         }
       
  1276         object[key] = value;
       
  1277       });
       
  1278     }
       
  1279 
       
  1280     /**
       
  1281      * The base implementation of `_.random` without argument juggling or support
       
  1282      * for returning floating-point numbers.
       
  1283      *
       
  1284      * @private
       
  1285      * @param {number} min The minimum possible value.
       
  1286      * @param {number} max The maximum possible value.
       
  1287      * @returns {number} Returns a random number.
       
  1288      */
       
  1289     function baseRandom(min, max) {
       
  1290       return min + floor(nativeRandom() * (max - min + 1));
       
  1291     }
       
  1292 
       
  1293     /**
       
  1294      * The base implementation of `_.uniq` without support for callback shorthands
       
  1295      * or `thisArg` binding.
       
  1296      *
       
  1297      * @private
       
  1298      * @param {Array} array The array to process.
       
  1299      * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
       
  1300      * @param {Function} [callback] The function called per iteration.
       
  1301      * @returns {Array} Returns a duplicate-value-free array.
       
  1302      */
       
  1303     function baseUniq(array, isSorted, callback) {
       
  1304       var index = -1,
       
  1305           indexOf = getIndexOf(),
       
  1306           length = array ? array.length : 0,
       
  1307           result = [];
       
  1308 
       
  1309       var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
       
  1310           seen = (callback || isLarge) ? getArray() : result;
       
  1311 
       
  1312       if (isLarge) {
       
  1313         var cache = createCache(seen);
       
  1314         indexOf = cacheIndexOf;
       
  1315         seen = cache;
       
  1316       }
       
  1317       while (++index < length) {
       
  1318         var value = array[index],
       
  1319             computed = callback ? callback(value, index, array) : value;
       
  1320 
       
  1321         if (isSorted
       
  1322               ? !index || seen[seen.length - 1] !== computed
       
  1323               : indexOf(seen, computed) < 0
       
  1324             ) {
       
  1325           if (callback || isLarge) {
       
  1326             seen.push(computed);
       
  1327           }
       
  1328           result.push(value);
       
  1329         }
       
  1330       }
       
  1331       if (isLarge) {
       
  1332         releaseArray(seen.array);
       
  1333         releaseObject(seen);
       
  1334       } else if (callback) {
       
  1335         releaseArray(seen);
       
  1336       }
       
  1337       return result;
       
  1338     }
       
  1339 
       
  1340     /**
       
  1341      * Creates a function that aggregates a collection, creating an object composed
       
  1342      * of keys generated from the results of running each element of the collection
       
  1343      * through a callback. The given `setter` function sets the keys and values
       
  1344      * of the composed object.
       
  1345      *
       
  1346      * @private
       
  1347      * @param {Function} setter The setter function.
       
  1348      * @returns {Function} Returns the new aggregator function.
       
  1349      */
       
  1350     function createAggregator(setter) {
       
  1351       return function(collection, callback, thisArg) {
       
  1352         var result = {};
       
  1353         callback = lodash.createCallback(callback, thisArg, 3);
       
  1354 
       
  1355         var index = -1,
       
  1356             length = collection ? collection.length : 0;
       
  1357 
       
  1358         if (typeof length == 'number') {
       
  1359           while (++index < length) {
       
  1360             var value = collection[index];
       
  1361             setter(result, value, callback(value, index, collection), collection);
       
  1362           }
       
  1363         } else {
       
  1364           forOwn(collection, function(value, key, collection) {
       
  1365             setter(result, value, callback(value, key, collection), collection);
       
  1366           });
       
  1367         }
       
  1368         return result;
       
  1369       };
       
  1370     }
       
  1371 
       
  1372     /**
       
  1373      * Creates a function that, when called, either curries or invokes `func`
       
  1374      * with an optional `this` binding and partially applied arguments.
       
  1375      *
       
  1376      * @private
       
  1377      * @param {Function|string} func The function or method name to reference.
       
  1378      * @param {number} bitmask The bitmask of method flags to compose.
       
  1379      *  The bitmask may be composed of the following flags:
       
  1380      *  1 - `_.bind`
       
  1381      *  2 - `_.bindKey`
       
  1382      *  4 - `_.curry`
       
  1383      *  8 - `_.curry` (bound)
       
  1384      *  16 - `_.partial`
       
  1385      *  32 - `_.partialRight`
       
  1386      * @param {Array} [partialArgs] An array of arguments to prepend to those
       
  1387      *  provided to the new function.
       
  1388      * @param {Array} [partialRightArgs] An array of arguments to append to those
       
  1389      *  provided to the new function.
       
  1390      * @param {*} [thisArg] The `this` binding of `func`.
       
  1391      * @param {number} [arity] The arity of `func`.
       
  1392      * @returns {Function} Returns the new function.
       
  1393      */
       
  1394     function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
       
  1395       var isBind = bitmask & 1,
       
  1396           isBindKey = bitmask & 2,
       
  1397           isCurry = bitmask & 4,
       
  1398           isCurryBound = bitmask & 8,
       
  1399           isPartial = bitmask & 16,
       
  1400           isPartialRight = bitmask & 32;
       
  1401 
       
  1402       if (!isBindKey && !isFunction(func)) {
       
  1403         throw new TypeError;
       
  1404       }
       
  1405       if (isPartial && !partialArgs.length) {
       
  1406         bitmask &= ~16;
       
  1407         isPartial = partialArgs = false;
       
  1408       }
       
  1409       if (isPartialRight && !partialRightArgs.length) {
       
  1410         bitmask &= ~32;
       
  1411         isPartialRight = partialRightArgs = false;
       
  1412       }
       
  1413       var bindData = func && func.__bindData__;
       
  1414       if (bindData && bindData !== true) {
       
  1415         // clone `bindData`
       
  1416         bindData = slice(bindData);
       
  1417         if (bindData[2]) {
       
  1418           bindData[2] = slice(bindData[2]);
       
  1419         }
       
  1420         if (bindData[3]) {
       
  1421           bindData[3] = slice(bindData[3]);
       
  1422         }
       
  1423         // set `thisBinding` is not previously bound
       
  1424         if (isBind && !(bindData[1] & 1)) {
       
  1425           bindData[4] = thisArg;
       
  1426         }
       
  1427         // set if previously bound but not currently (subsequent curried functions)
       
  1428         if (!isBind && bindData[1] & 1) {
       
  1429           bitmask |= 8;
       
  1430         }
       
  1431         // set curried arity if not yet set
       
  1432         if (isCurry && !(bindData[1] & 4)) {
       
  1433           bindData[5] = arity;
       
  1434         }
       
  1435         // append partial left arguments
       
  1436         if (isPartial) {
       
  1437           push.apply(bindData[2] || (bindData[2] = []), partialArgs);
       
  1438         }
       
  1439         // append partial right arguments
       
  1440         if (isPartialRight) {
       
  1441           unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
       
  1442         }
       
  1443         // merge flags
       
  1444         bindData[1] |= bitmask;
       
  1445         return createWrapper.apply(null, bindData);
       
  1446       }
       
  1447       // fast path for `_.bind`
       
  1448       var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
       
  1449       return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
       
  1450     }
       
  1451 
       
  1452     /**
       
  1453      * Used by `escape` to convert characters to HTML entities.
       
  1454      *
       
  1455      * @private
       
  1456      * @param {string} match The matched character to escape.
       
  1457      * @returns {string} Returns the escaped character.
       
  1458      */
       
  1459     function escapeHtmlChar(match) {
       
  1460       return htmlEscapes[match];
       
  1461     }
       
  1462 
       
  1463     /**
       
  1464      * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
       
  1465      * customized, this method returns the custom method, otherwise it returns
       
  1466      * the `baseIndexOf` function.
       
  1467      *
       
  1468      * @private
       
  1469      * @returns {Function} Returns the "indexOf" function.
       
  1470      */
       
  1471     function getIndexOf() {
       
  1472       var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
       
  1473       return result;
       
  1474     }
       
  1475 
       
  1476     /**
       
  1477      * Checks if `value` is a native function.
       
  1478      *
       
  1479      * @private
       
  1480      * @param {*} value The value to check.
       
  1481      * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
       
  1482      */
       
  1483     function isNative(value) {
       
  1484       return typeof value == 'function' && reNative.test(value);
       
  1485     }
       
  1486 
       
  1487     /**
       
  1488      * Sets `this` binding data on a given function.
       
  1489      *
       
  1490      * @private
       
  1491      * @param {Function} func The function to set data on.
       
  1492      * @param {Array} value The data array to set.
       
  1493      */
       
  1494     var setBindData = !defineProperty ? noop : function(func, value) {
       
  1495       descriptor.value = value;
       
  1496       defineProperty(func, '__bindData__', descriptor);
       
  1497     };
       
  1498 
       
  1499     /**
       
  1500      * A fallback implementation of `isPlainObject` which checks if a given value
       
  1501      * is an object created by the `Object` constructor, assuming objects created
       
  1502      * by the `Object` constructor have no inherited enumerable properties and that
       
  1503      * there are no `Object.prototype` extensions.
       
  1504      *
       
  1505      * @private
       
  1506      * @param {*} value The value to check.
       
  1507      * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
       
  1508      */
       
  1509     function shimIsPlainObject(value) {
       
  1510       var ctor,
       
  1511           result;
       
  1512 
       
  1513       // avoid non Object objects, `arguments` objects, and DOM elements
       
  1514       if (!(value && toString.call(value) == objectClass) ||
       
  1515           (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) {
       
  1516         return false;
       
  1517       }
       
  1518       // In most environments an object's own properties are iterated before
       
  1519       // its inherited properties. If the last iterated property is an object's
       
  1520       // own property then there are no inherited enumerable properties.
       
  1521       forIn(value, function(value, key) {
       
  1522         result = key;
       
  1523       });
       
  1524       return typeof result == 'undefined' || hasOwnProperty.call(value, result);
       
  1525     }
       
  1526 
       
  1527     /**
       
  1528      * Used by `unescape` to convert HTML entities to characters.
       
  1529      *
       
  1530      * @private
       
  1531      * @param {string} match The matched character to unescape.
       
  1532      * @returns {string} Returns the unescaped character.
       
  1533      */
       
  1534     function unescapeHtmlChar(match) {
       
  1535       return htmlUnescapes[match];
       
  1536     }
       
  1537 
       
  1538     /*--------------------------------------------------------------------------*/
       
  1539 
       
  1540     /**
       
  1541      * Checks if `value` is an `arguments` object.
       
  1542      *
       
  1543      * @static
       
  1544      * @memberOf _
       
  1545      * @category Objects
       
  1546      * @param {*} value The value to check.
       
  1547      * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
       
  1548      * @example
       
  1549      *
       
  1550      * (function() { return _.isArguments(arguments); })(1, 2, 3);
       
  1551      * // => true
       
  1552      *
       
  1553      * _.isArguments([1, 2, 3]);
       
  1554      * // => false
       
  1555      */
       
  1556     function isArguments(value) {
       
  1557       return value && typeof value == 'object' && typeof value.length == 'number' &&
       
  1558         toString.call(value) == argsClass || false;
       
  1559     }
       
  1560 
       
  1561     /**
       
  1562      * Checks if `value` is an array.
       
  1563      *
       
  1564      * @static
       
  1565      * @memberOf _
       
  1566      * @type Function
       
  1567      * @category Objects
       
  1568      * @param {*} value The value to check.
       
  1569      * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
       
  1570      * @example
       
  1571      *
       
  1572      * (function() { return _.isArray(arguments); })();
       
  1573      * // => false
       
  1574      *
       
  1575      * _.isArray([1, 2, 3]);
       
  1576      * // => true
       
  1577      */
       
  1578     var isArray = nativeIsArray || function(value) {
       
  1579       return value && typeof value == 'object' && typeof value.length == 'number' &&
       
  1580         toString.call(value) == arrayClass || false;
       
  1581     };
       
  1582 
       
  1583     /**
       
  1584      * A fallback implementation of `Object.keys` which produces an array of the
       
  1585      * given object's own enumerable property names.
       
  1586      *
       
  1587      * @private
       
  1588      * @type Function
       
  1589      * @param {Object} object The object to inspect.
       
  1590      * @returns {Array} Returns an array of property names.
       
  1591      */
       
  1592     var shimKeys = function(object) {
       
  1593       var index, iterable = object, result = [];
       
  1594       if (!iterable) return result;
       
  1595       if (!(objectTypes[typeof object])) return result;
       
  1596         for (index in iterable) {
       
  1597           if (hasOwnProperty.call(iterable, index)) {
       
  1598             result.push(index);
       
  1599           }
       
  1600         }
       
  1601       return result
       
  1602     };
       
  1603 
       
  1604     /**
       
  1605      * Creates an array composed of the own enumerable property names of an object.
       
  1606      *
       
  1607      * @static
       
  1608      * @memberOf _
       
  1609      * @category Objects
       
  1610      * @param {Object} object The object to inspect.
       
  1611      * @returns {Array} Returns an array of property names.
       
  1612      * @example
       
  1613      *
       
  1614      * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
       
  1615      * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
       
  1616      */
       
  1617     var keys = !nativeKeys ? shimKeys : function(object) {
       
  1618       if (!isObject(object)) {
       
  1619         return [];
       
  1620       }
       
  1621       return nativeKeys(object);
       
  1622     };
       
  1623 
       
  1624     /**
       
  1625      * Used to convert characters to HTML entities:
       
  1626      *
       
  1627      * Though the `>` character is escaped for symmetry, characters like `>` and `/`
       
  1628      * don't require escaping in HTML and have no special meaning unless they're part
       
  1629      * of a tag or an unquoted attribute value.
       
  1630      * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
       
  1631      */
       
  1632     var htmlEscapes = {
       
  1633       '&': '&amp;',
       
  1634       '<': '&lt;',
       
  1635       '>': '&gt;',
       
  1636       '"': '&quot;',
       
  1637       "'": '&#39;'
       
  1638     };
       
  1639 
       
  1640     /** Used to convert HTML entities to characters */
       
  1641     var htmlUnescapes = invert(htmlEscapes);
       
  1642 
       
  1643     /** Used to match HTML entities and HTML characters */
       
  1644     var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
       
  1645         reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
       
  1646 
       
  1647     /*--------------------------------------------------------------------------*/
       
  1648 
       
  1649     /**
       
  1650      * Assigns own enumerable properties of source object(s) to the destination
       
  1651      * object. Subsequent sources will overwrite property assignments of previous
       
  1652      * sources. If a callback is provided it will be executed to produce the
       
  1653      * assigned values. The callback is bound to `thisArg` and invoked with two
       
  1654      * arguments; (objectValue, sourceValue).
       
  1655      *
       
  1656      * @static
       
  1657      * @memberOf _
       
  1658      * @type Function
       
  1659      * @alias extend
       
  1660      * @category Objects
       
  1661      * @param {Object} object The destination object.
       
  1662      * @param {...Object} [source] The source objects.
       
  1663      * @param {Function} [callback] The function to customize assigning values.
       
  1664      * @param {*} [thisArg] The `this` binding of `callback`.
       
  1665      * @returns {Object} Returns the destination object.
       
  1666      * @example
       
  1667      *
       
  1668      * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
       
  1669      * // => { 'name': 'fred', 'employer': 'slate' }
       
  1670      *
       
  1671      * var defaults = _.partialRight(_.assign, function(a, b) {
       
  1672      *   return typeof a == 'undefined' ? b : a;
       
  1673      * });
       
  1674      *
       
  1675      * var object = { 'name': 'barney' };
       
  1676      * defaults(object, { 'name': 'fred', 'employer': 'slate' });
       
  1677      * // => { 'name': 'barney', 'employer': 'slate' }
       
  1678      */
       
  1679     var assign = function(object, source, guard) {
       
  1680       var index, iterable = object, result = iterable;
       
  1681       if (!iterable) return result;
       
  1682       var args = arguments,
       
  1683           argsIndex = 0,
       
  1684           argsLength = typeof guard == 'number' ? 2 : args.length;
       
  1685       if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {
       
  1686         var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);
       
  1687       } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {
       
  1688         callback = args[--argsLength];
       
  1689       }
       
  1690       while (++argsIndex < argsLength) {
       
  1691         iterable = args[argsIndex];
       
  1692         if (iterable && objectTypes[typeof iterable]) {
       
  1693         var ownIndex = -1,
       
  1694             ownProps = objectTypes[typeof iterable] && keys(iterable),
       
  1695             length = ownProps ? ownProps.length : 0;
       
  1696 
       
  1697         while (++ownIndex < length) {
       
  1698           index = ownProps[ownIndex];
       
  1699           result[index] = callback ? callback(result[index], iterable[index]) : iterable[index];
       
  1700         }
       
  1701         }
       
  1702       }
       
  1703       return result
       
  1704     };
       
  1705 
       
  1706     /**
       
  1707      * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
       
  1708      * be cloned, otherwise they will be assigned by reference. If a callback
       
  1709      * is provided it will be executed to produce the cloned values. If the
       
  1710      * callback returns `undefined` cloning will be handled by the method instead.
       
  1711      * The callback is bound to `thisArg` and invoked with one argument; (value).
       
  1712      *
       
  1713      * @static
       
  1714      * @memberOf _
       
  1715      * @category Objects
       
  1716      * @param {*} value The value to clone.
       
  1717      * @param {boolean} [isDeep=false] Specify a deep clone.
       
  1718      * @param {Function} [callback] The function to customize cloning values.
       
  1719      * @param {*} [thisArg] The `this` binding of `callback`.
       
  1720      * @returns {*} Returns the cloned value.
       
  1721      * @example
       
  1722      *
       
  1723      * var characters = [
       
  1724      *   { 'name': 'barney', 'age': 36 },
       
  1725      *   { 'name': 'fred',   'age': 40 }
       
  1726      * ];
       
  1727      *
       
  1728      * var shallow = _.clone(characters);
       
  1729      * shallow[0] === characters[0];
       
  1730      * // => true
       
  1731      *
       
  1732      * var deep = _.clone(characters, true);
       
  1733      * deep[0] === characters[0];
       
  1734      * // => false
       
  1735      *
       
  1736      * _.mixin({
       
  1737      *   'clone': _.partialRight(_.clone, function(value) {
       
  1738      *     return _.isElement(value) ? value.cloneNode(false) : undefined;
       
  1739      *   })
       
  1740      * });
       
  1741      *
       
  1742      * var clone = _.clone(document.body);
       
  1743      * clone.childNodes.length;
       
  1744      * // => 0
       
  1745      */
       
  1746     function clone(value, isDeep, callback, thisArg) {
       
  1747       // allows working with "Collections" methods without using their `index`
       
  1748       // and `collection` arguments for `isDeep` and `callback`
       
  1749       if (typeof isDeep != 'boolean' && isDeep != null) {
       
  1750         thisArg = callback;
       
  1751         callback = isDeep;
       
  1752         isDeep = false;
       
  1753       }
       
  1754       return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
       
  1755     }
       
  1756 
       
  1757     /**
       
  1758      * Creates a deep clone of `value`. If a callback is provided it will be
       
  1759      * executed to produce the cloned values. If the callback returns `undefined`
       
  1760      * cloning will be handled by the method instead. The callback is bound to
       
  1761      * `thisArg` and invoked with one argument; (value).
       
  1762      *
       
  1763      * Note: This method is loosely based on the structured clone algorithm. Functions
       
  1764      * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
       
  1765      * objects created by constructors other than `Object` are cloned to plain `Object` objects.
       
  1766      * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
       
  1767      *
       
  1768      * @static
       
  1769      * @memberOf _
       
  1770      * @category Objects
       
  1771      * @param {*} value The value to deep clone.
       
  1772      * @param {Function} [callback] The function to customize cloning values.
       
  1773      * @param {*} [thisArg] The `this` binding of `callback`.
       
  1774      * @returns {*} Returns the deep cloned value.
       
  1775      * @example
       
  1776      *
       
  1777      * var characters = [
       
  1778      *   { 'name': 'barney', 'age': 36 },
       
  1779      *   { 'name': 'fred',   'age': 40 }
       
  1780      * ];
       
  1781      *
       
  1782      * var deep = _.cloneDeep(characters);
       
  1783      * deep[0] === characters[0];
       
  1784      * // => false
       
  1785      *
       
  1786      * var view = {
       
  1787      *   'label': 'docs',
       
  1788      *   'node': element
       
  1789      * };
       
  1790      *
       
  1791      * var clone = _.cloneDeep(view, function(value) {
       
  1792      *   return _.isElement(value) ? value.cloneNode(true) : undefined;
       
  1793      * });
       
  1794      *
       
  1795      * clone.node == view.node;
       
  1796      * // => false
       
  1797      */
       
  1798     function cloneDeep(value, callback, thisArg) {
       
  1799       return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
       
  1800     }
       
  1801 
       
  1802     /**
       
  1803      * Creates an object that inherits from the given `prototype` object. If a
       
  1804      * `properties` object is provided its own enumerable properties are assigned
       
  1805      * to the created object.
       
  1806      *
       
  1807      * @static
       
  1808      * @memberOf _
       
  1809      * @category Objects
       
  1810      * @param {Object} prototype The object to inherit from.
       
  1811      * @param {Object} [properties] The properties to assign to the object.
       
  1812      * @returns {Object} Returns the new object.
       
  1813      * @example
       
  1814      *
       
  1815      * function Shape() {
       
  1816      *   this.x = 0;
       
  1817      *   this.y = 0;
       
  1818      * }
       
  1819      *
       
  1820      * function Circle() {
       
  1821      *   Shape.call(this);
       
  1822      * }
       
  1823      *
       
  1824      * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
       
  1825      *
       
  1826      * var circle = new Circle;
       
  1827      * circle instanceof Circle;
       
  1828      * // => true
       
  1829      *
       
  1830      * circle instanceof Shape;
       
  1831      * // => true
       
  1832      */
       
  1833     function create(prototype, properties) {
       
  1834       var result = baseCreate(prototype);
       
  1835       return properties ? assign(result, properties) : result;
       
  1836     }
       
  1837 
       
  1838     /**
       
  1839      * Assigns own enumerable properties of source object(s) to the destination
       
  1840      * object for all destination properties that resolve to `undefined`. Once a
       
  1841      * property is set, additional defaults of the same property will be ignored.
       
  1842      *
       
  1843      * @static
       
  1844      * @memberOf _
       
  1845      * @type Function
       
  1846      * @category Objects
       
  1847      * @param {Object} object The destination object.
       
  1848      * @param {...Object} [source] The source objects.
       
  1849      * @param- {Object} [guard] Allows working with `_.reduce` without using its
       
  1850      *  `key` and `object` arguments as sources.
       
  1851      * @returns {Object} Returns the destination object.
       
  1852      * @example
       
  1853      *
       
  1854      * var object = { 'name': 'barney' };
       
  1855      * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
       
  1856      * // => { 'name': 'barney', 'employer': 'slate' }
       
  1857      */
       
  1858     var defaults = function(object, source, guard) {
       
  1859       var index, iterable = object, result = iterable;
       
  1860       if (!iterable) return result;
       
  1861       var args = arguments,
       
  1862           argsIndex = 0,
       
  1863           argsLength = typeof guard == 'number' ? 2 : args.length;
       
  1864       while (++argsIndex < argsLength) {
       
  1865         iterable = args[argsIndex];
       
  1866         if (iterable && objectTypes[typeof iterable]) {
       
  1867         var ownIndex = -1,
       
  1868             ownProps = objectTypes[typeof iterable] && keys(iterable),
       
  1869             length = ownProps ? ownProps.length : 0;
       
  1870 
       
  1871         while (++ownIndex < length) {
       
  1872           index = ownProps[ownIndex];
       
  1873           if (typeof result[index] == 'undefined') result[index] = iterable[index];
       
  1874         }
       
  1875         }
       
  1876       }
       
  1877       return result
       
  1878     };
       
  1879 
       
  1880     /**
       
  1881      * This method is like `_.findIndex` except that it returns the key of the
       
  1882      * first element that passes the callback check, instead of the element itself.
       
  1883      *
       
  1884      * If a property name is provided for `callback` the created "_.pluck" style
       
  1885      * callback will return the property value of the given element.
       
  1886      *
       
  1887      * If an object is provided for `callback` the created "_.where" style callback
       
  1888      * will return `true` for elements that have the properties of the given object,
       
  1889      * else `false`.
       
  1890      *
       
  1891      * @static
       
  1892      * @memberOf _
       
  1893      * @category Objects
       
  1894      * @param {Object} object The object to search.
       
  1895      * @param {Function|Object|string} [callback=identity] The function called per
       
  1896      *  iteration. If a property name or object is provided it will be used to
       
  1897      *  create a "_.pluck" or "_.where" style callback, respectively.
       
  1898      * @param {*} [thisArg] The `this` binding of `callback`.
       
  1899      * @returns {string|undefined} Returns the key of the found element, else `undefined`.
       
  1900      * @example
       
  1901      *
       
  1902      * var characters = {
       
  1903      *   'barney': {  'age': 36, 'blocked': false },
       
  1904      *   'fred': {    'age': 40, 'blocked': true },
       
  1905      *   'pebbles': { 'age': 1,  'blocked': false }
       
  1906      * };
       
  1907      *
       
  1908      * _.findKey(characters, function(chr) {
       
  1909      *   return chr.age < 40;
       
  1910      * });
       
  1911      * // => 'barney' (property order is not guaranteed across environments)
       
  1912      *
       
  1913      * // using "_.where" callback shorthand
       
  1914      * _.findKey(characters, { 'age': 1 });
       
  1915      * // => 'pebbles'
       
  1916      *
       
  1917      * // using "_.pluck" callback shorthand
       
  1918      * _.findKey(characters, 'blocked');
       
  1919      * // => 'fred'
       
  1920      */
       
  1921     function findKey(object, callback, thisArg) {
       
  1922       var result;
       
  1923       callback = lodash.createCallback(callback, thisArg, 3);
       
  1924       forOwn(object, function(value, key, object) {
       
  1925         if (callback(value, key, object)) {
       
  1926           result = key;
       
  1927           return false;
       
  1928         }
       
  1929       });
       
  1930       return result;
       
  1931     }
       
  1932 
       
  1933     /**
       
  1934      * This method is like `_.findKey` except that it iterates over elements
       
  1935      * of a `collection` in the opposite order.
       
  1936      *
       
  1937      * If a property name is provided for `callback` the created "_.pluck" style
       
  1938      * callback will return the property value of the given element.
       
  1939      *
       
  1940      * If an object is provided for `callback` the created "_.where" style callback
       
  1941      * will return `true` for elements that have the properties of the given object,
       
  1942      * else `false`.
       
  1943      *
       
  1944      * @static
       
  1945      * @memberOf _
       
  1946      * @category Objects
       
  1947      * @param {Object} object The object to search.
       
  1948      * @param {Function|Object|string} [callback=identity] The function called per
       
  1949      *  iteration. If a property name or object is provided it will be used to
       
  1950      *  create a "_.pluck" or "_.where" style callback, respectively.
       
  1951      * @param {*} [thisArg] The `this` binding of `callback`.
       
  1952      * @returns {string|undefined} Returns the key of the found element, else `undefined`.
       
  1953      * @example
       
  1954      *
       
  1955      * var characters = {
       
  1956      *   'barney': {  'age': 36, 'blocked': true },
       
  1957      *   'fred': {    'age': 40, 'blocked': false },
       
  1958      *   'pebbles': { 'age': 1,  'blocked': true }
       
  1959      * };
       
  1960      *
       
  1961      * _.findLastKey(characters, function(chr) {
       
  1962      *   return chr.age < 40;
       
  1963      * });
       
  1964      * // => returns `pebbles`, assuming `_.findKey` returns `barney`
       
  1965      *
       
  1966      * // using "_.where" callback shorthand
       
  1967      * _.findLastKey(characters, { 'age': 40 });
       
  1968      * // => 'fred'
       
  1969      *
       
  1970      * // using "_.pluck" callback shorthand
       
  1971      * _.findLastKey(characters, 'blocked');
       
  1972      * // => 'pebbles'
       
  1973      */
       
  1974     function findLastKey(object, callback, thisArg) {
       
  1975       var result;
       
  1976       callback = lodash.createCallback(callback, thisArg, 3);
       
  1977       forOwnRight(object, function(value, key, object) {
       
  1978         if (callback(value, key, object)) {
       
  1979           result = key;
       
  1980           return false;
       
  1981         }
       
  1982       });
       
  1983       return result;
       
  1984     }
       
  1985 
       
  1986     /**
       
  1987      * Iterates over own and inherited enumerable properties of an object,
       
  1988      * executing the callback for each property. The callback is bound to `thisArg`
       
  1989      * and invoked with three arguments; (value, key, object). Callbacks may exit
       
  1990      * iteration early by explicitly returning `false`.
       
  1991      *
       
  1992      * @static
       
  1993      * @memberOf _
       
  1994      * @type Function
       
  1995      * @category Objects
       
  1996      * @param {Object} object The object to iterate over.
       
  1997      * @param {Function} [callback=identity] The function called per iteration.
       
  1998      * @param {*} [thisArg] The `this` binding of `callback`.
       
  1999      * @returns {Object} Returns `object`.
       
  2000      * @example
       
  2001      *
       
  2002      * function Shape() {
       
  2003      *   this.x = 0;
       
  2004      *   this.y = 0;
       
  2005      * }
       
  2006      *
       
  2007      * Shape.prototype.move = function(x, y) {
       
  2008      *   this.x += x;
       
  2009      *   this.y += y;
       
  2010      * };
       
  2011      *
       
  2012      * _.forIn(new Shape, function(value, key) {
       
  2013      *   console.log(key);
       
  2014      * });
       
  2015      * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
       
  2016      */
       
  2017     var forIn = function(collection, callback, thisArg) {
       
  2018       var index, iterable = collection, result = iterable;
       
  2019       if (!iterable) return result;
       
  2020       if (!objectTypes[typeof iterable]) return result;
       
  2021       callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
       
  2022         for (index in iterable) {
       
  2023           if (callback(iterable[index], index, collection) === false) return result;
       
  2024         }
       
  2025       return result
       
  2026     };
       
  2027 
       
  2028     /**
       
  2029      * This method is like `_.forIn` except that it iterates over elements
       
  2030      * of a `collection` in the opposite order.
       
  2031      *
       
  2032      * @static
       
  2033      * @memberOf _
       
  2034      * @category Objects
       
  2035      * @param {Object} object The object to iterate over.
       
  2036      * @param {Function} [callback=identity] The function called per iteration.
       
  2037      * @param {*} [thisArg] The `this` binding of `callback`.
       
  2038      * @returns {Object} Returns `object`.
       
  2039      * @example
       
  2040      *
       
  2041      * function Shape() {
       
  2042      *   this.x = 0;
       
  2043      *   this.y = 0;
       
  2044      * }
       
  2045      *
       
  2046      * Shape.prototype.move = function(x, y) {
       
  2047      *   this.x += x;
       
  2048      *   this.y += y;
       
  2049      * };
       
  2050      *
       
  2051      * _.forInRight(new Shape, function(value, key) {
       
  2052      *   console.log(key);
       
  2053      * });
       
  2054      * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
       
  2055      */
       
  2056     function forInRight(object, callback, thisArg) {
       
  2057       var pairs = [];
       
  2058 
       
  2059       forIn(object, function(value, key) {
       
  2060         pairs.push(key, value);
       
  2061       });
       
  2062 
       
  2063       var length = pairs.length;
       
  2064       callback = baseCreateCallback(callback, thisArg, 3);
       
  2065       while (length--) {
       
  2066         if (callback(pairs[length--], pairs[length], object) === false) {
       
  2067           break;
       
  2068         }
       
  2069       }
       
  2070       return object;
       
  2071     }
       
  2072 
       
  2073     /**
       
  2074      * Iterates over own enumerable properties of an object, executing the callback
       
  2075      * for each property. The callback is bound to `thisArg` and invoked with three
       
  2076      * arguments; (value, key, object). Callbacks may exit iteration early by
       
  2077      * explicitly returning `false`.
       
  2078      *
       
  2079      * @static
       
  2080      * @memberOf _
       
  2081      * @type Function
       
  2082      * @category Objects
       
  2083      * @param {Object} object The object to iterate over.
       
  2084      * @param {Function} [callback=identity] The function called per iteration.
       
  2085      * @param {*} [thisArg] The `this` binding of `callback`.
       
  2086      * @returns {Object} Returns `object`.
       
  2087      * @example
       
  2088      *
       
  2089      * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
       
  2090      *   console.log(key);
       
  2091      * });
       
  2092      * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
       
  2093      */
       
  2094     var forOwn = function(collection, callback, thisArg) {
       
  2095       var index, iterable = collection, result = iterable;
       
  2096       if (!iterable) return result;
       
  2097       if (!objectTypes[typeof iterable]) return result;
       
  2098       callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
       
  2099         var ownIndex = -1,
       
  2100             ownProps = objectTypes[typeof iterable] && keys(iterable),
       
  2101             length = ownProps ? ownProps.length : 0;
       
  2102 
       
  2103         while (++ownIndex < length) {
       
  2104           index = ownProps[ownIndex];
       
  2105           if (callback(iterable[index], index, collection) === false) return result;
       
  2106         }
       
  2107       return result
       
  2108     };
       
  2109 
       
  2110     /**
       
  2111      * This method is like `_.forOwn` except that it iterates over elements
       
  2112      * of a `collection` in the opposite order.
       
  2113      *
       
  2114      * @static
       
  2115      * @memberOf _
       
  2116      * @category Objects
       
  2117      * @param {Object} object The object to iterate over.
       
  2118      * @param {Function} [callback=identity] The function called per iteration.
       
  2119      * @param {*} [thisArg] The `this` binding of `callback`.
       
  2120      * @returns {Object} Returns `object`.
       
  2121      * @example
       
  2122      *
       
  2123      * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
       
  2124      *   console.log(key);
       
  2125      * });
       
  2126      * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
       
  2127      */
       
  2128     function forOwnRight(object, callback, thisArg) {
       
  2129       var props = keys(object),
       
  2130           length = props.length;
       
  2131 
       
  2132       callback = baseCreateCallback(callback, thisArg, 3);
       
  2133       while (length--) {
       
  2134         var key = props[length];
       
  2135         if (callback(object[key], key, object) === false) {
       
  2136           break;
       
  2137         }
       
  2138       }
       
  2139       return object;
       
  2140     }
       
  2141 
       
  2142     /**
       
  2143      * Creates a sorted array of property names of all enumerable properties,
       
  2144      * own and inherited, of `object` that have function values.
       
  2145      *
       
  2146      * @static
       
  2147      * @memberOf _
       
  2148      * @alias methods
       
  2149      * @category Objects
       
  2150      * @param {Object} object The object to inspect.
       
  2151      * @returns {Array} Returns an array of property names that have function values.
       
  2152      * @example
       
  2153      *
       
  2154      * _.functions(_);
       
  2155      * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
       
  2156      */
       
  2157     function functions(object) {
       
  2158       var result = [];
       
  2159       forIn(object, function(value, key) {
       
  2160         if (isFunction(value)) {
       
  2161           result.push(key);
       
  2162         }
       
  2163       });
       
  2164       return result.sort();
       
  2165     }
       
  2166 
       
  2167     /**
       
  2168      * Checks if the specified property name exists as a direct property of `object`,
       
  2169      * instead of an inherited property.
       
  2170      *
       
  2171      * @static
       
  2172      * @memberOf _
       
  2173      * @category Objects
       
  2174      * @param {Object} object The object to inspect.
       
  2175      * @param {string} key The name of the property to check.
       
  2176      * @returns {boolean} Returns `true` if key is a direct property, else `false`.
       
  2177      * @example
       
  2178      *
       
  2179      * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
       
  2180      * // => true
       
  2181      */
       
  2182     function has(object, key) {
       
  2183       return object ? hasOwnProperty.call(object, key) : false;
       
  2184     }
       
  2185 
       
  2186     /**
       
  2187      * Creates an object composed of the inverted keys and values of the given object.
       
  2188      *
       
  2189      * @static
       
  2190      * @memberOf _
       
  2191      * @category Objects
       
  2192      * @param {Object} object The object to invert.
       
  2193      * @returns {Object} Returns the created inverted object.
       
  2194      * @example
       
  2195      *
       
  2196      * _.invert({ 'first': 'fred', 'second': 'barney' });
       
  2197      * // => { 'fred': 'first', 'barney': 'second' }
       
  2198      */
       
  2199     function invert(object) {
       
  2200       var index = -1,
       
  2201           props = keys(object),
       
  2202           length = props.length,
       
  2203           result = {};
       
  2204 
       
  2205       while (++index < length) {
       
  2206         var key = props[index];
       
  2207         result[object[key]] = key;
       
  2208       }
       
  2209       return result;
       
  2210     }
       
  2211 
       
  2212     /**
       
  2213      * Checks if `value` is a boolean value.
       
  2214      *
       
  2215      * @static
       
  2216      * @memberOf _
       
  2217      * @category Objects
       
  2218      * @param {*} value The value to check.
       
  2219      * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
       
  2220      * @example
       
  2221      *
       
  2222      * _.isBoolean(null);
       
  2223      * // => false
       
  2224      */
       
  2225     function isBoolean(value) {
       
  2226       return value === true || value === false ||
       
  2227         value && typeof value == 'object' && toString.call(value) == boolClass || false;
       
  2228     }
       
  2229 
       
  2230     /**
       
  2231      * Checks if `value` is a date.
       
  2232      *
       
  2233      * @static
       
  2234      * @memberOf _
       
  2235      * @category Objects
       
  2236      * @param {*} value The value to check.
       
  2237      * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
       
  2238      * @example
       
  2239      *
       
  2240      * _.isDate(new Date);
       
  2241      * // => true
       
  2242      */
       
  2243     function isDate(value) {
       
  2244       return value && typeof value == 'object' && toString.call(value) == dateClass || false;
       
  2245     }
       
  2246 
       
  2247     /**
       
  2248      * Checks if `value` is a DOM element.
       
  2249      *
       
  2250      * @static
       
  2251      * @memberOf _
       
  2252      * @category Objects
       
  2253      * @param {*} value The value to check.
       
  2254      * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
       
  2255      * @example
       
  2256      *
       
  2257      * _.isElement(document.body);
       
  2258      * // => true
       
  2259      */
       
  2260     function isElement(value) {
       
  2261       return value && value.nodeType === 1 || false;
       
  2262     }
       
  2263 
       
  2264     /**
       
  2265      * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
       
  2266      * length of `0` and objects with no own enumerable properties are considered
       
  2267      * "empty".
       
  2268      *
       
  2269      * @static
       
  2270      * @memberOf _
       
  2271      * @category Objects
       
  2272      * @param {Array|Object|string} value The value to inspect.
       
  2273      * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
       
  2274      * @example
       
  2275      *
       
  2276      * _.isEmpty([1, 2, 3]);
       
  2277      * // => false
       
  2278      *
       
  2279      * _.isEmpty({});
       
  2280      * // => true
       
  2281      *
       
  2282      * _.isEmpty('');
       
  2283      * // => true
       
  2284      */
       
  2285     function isEmpty(value) {
       
  2286       var result = true;
       
  2287       if (!value) {
       
  2288         return result;
       
  2289       }
       
  2290       var className = toString.call(value),
       
  2291           length = value.length;
       
  2292 
       
  2293       if ((className == arrayClass || className == stringClass || className == argsClass ) ||
       
  2294           (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
       
  2295         return !length;
       
  2296       }
       
  2297       forOwn(value, function() {
       
  2298         return (result = false);
       
  2299       });
       
  2300       return result;
       
  2301     }
       
  2302 
       
  2303     /**
       
  2304      * Performs a deep comparison between two values to determine if they are
       
  2305      * equivalent to each other. If a callback is provided it will be executed
       
  2306      * to compare values. If the callback returns `undefined` comparisons will
       
  2307      * be handled by the method instead. The callback is bound to `thisArg` and
       
  2308      * invoked with two arguments; (a, b).
       
  2309      *
       
  2310      * @static
       
  2311      * @memberOf _
       
  2312      * @category Objects
       
  2313      * @param {*} a The value to compare.
       
  2314      * @param {*} b The other value to compare.
       
  2315      * @param {Function} [callback] The function to customize comparing values.
       
  2316      * @param {*} [thisArg] The `this` binding of `callback`.
       
  2317      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
       
  2318      * @example
       
  2319      *
       
  2320      * var object = { 'name': 'fred' };
       
  2321      * var copy = { 'name': 'fred' };
       
  2322      *
       
  2323      * object == copy;
       
  2324      * // => false
       
  2325      *
       
  2326      * _.isEqual(object, copy);
       
  2327      * // => true
       
  2328      *
       
  2329      * var words = ['hello', 'goodbye'];
       
  2330      * var otherWords = ['hi', 'goodbye'];
       
  2331      *
       
  2332      * _.isEqual(words, otherWords, function(a, b) {
       
  2333      *   var reGreet = /^(?:hello|hi)$/i,
       
  2334      *       aGreet = _.isString(a) && reGreet.test(a),
       
  2335      *       bGreet = _.isString(b) && reGreet.test(b);
       
  2336      *
       
  2337      *   return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
       
  2338      * });
       
  2339      * // => true
       
  2340      */
       
  2341     function isEqual(a, b, callback, thisArg) {
       
  2342       return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
       
  2343     }
       
  2344 
       
  2345     /**
       
  2346      * Checks if `value` is, or can be coerced to, a finite number.
       
  2347      *
       
  2348      * Note: This is not the same as native `isFinite` which will return true for
       
  2349      * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
       
  2350      *
       
  2351      * @static
       
  2352      * @memberOf _
       
  2353      * @category Objects
       
  2354      * @param {*} value The value to check.
       
  2355      * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
       
  2356      * @example
       
  2357      *
       
  2358      * _.isFinite(-101);
       
  2359      * // => true
       
  2360      *
       
  2361      * _.isFinite('10');
       
  2362      * // => true
       
  2363      *
       
  2364      * _.isFinite(true);
       
  2365      * // => false
       
  2366      *
       
  2367      * _.isFinite('');
       
  2368      * // => false
       
  2369      *
       
  2370      * _.isFinite(Infinity);
       
  2371      * // => false
       
  2372      */
       
  2373     function isFinite(value) {
       
  2374       return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
       
  2375     }
       
  2376 
       
  2377     /**
       
  2378      * Checks if `value` is a function.
       
  2379      *
       
  2380      * @static
       
  2381      * @memberOf _
       
  2382      * @category Objects
       
  2383      * @param {*} value The value to check.
       
  2384      * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
       
  2385      * @example
       
  2386      *
       
  2387      * _.isFunction(_);
       
  2388      * // => true
       
  2389      */
       
  2390     function isFunction(value) {
       
  2391       return typeof value == 'function';
       
  2392     }
       
  2393 
       
  2394     /**
       
  2395      * Checks if `value` is the language type of Object.
       
  2396      * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
       
  2397      *
       
  2398      * @static
       
  2399      * @memberOf _
       
  2400      * @category Objects
       
  2401      * @param {*} value The value to check.
       
  2402      * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
       
  2403      * @example
       
  2404      *
       
  2405      * _.isObject({});
       
  2406      * // => true
       
  2407      *
       
  2408      * _.isObject([1, 2, 3]);
       
  2409      * // => true
       
  2410      *
       
  2411      * _.isObject(1);
       
  2412      * // => false
       
  2413      */
       
  2414     function isObject(value) {
       
  2415       // check if the value is the ECMAScript language type of Object
       
  2416       // http://es5.github.io/#x8
       
  2417       // and avoid a V8 bug
       
  2418       // http://code.google.com/p/v8/issues/detail?id=2291
       
  2419       return !!(value && objectTypes[typeof value]);
       
  2420     }
       
  2421 
       
  2422     /**
       
  2423      * Checks if `value` is `NaN`.
       
  2424      *
       
  2425      * Note: This is not the same as native `isNaN` which will return `true` for
       
  2426      * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
       
  2427      *
       
  2428      * @static
       
  2429      * @memberOf _
       
  2430      * @category Objects
       
  2431      * @param {*} value The value to check.
       
  2432      * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
       
  2433      * @example
       
  2434      *
       
  2435      * _.isNaN(NaN);
       
  2436      * // => true
       
  2437      *
       
  2438      * _.isNaN(new Number(NaN));
       
  2439      * // => true
       
  2440      *
       
  2441      * isNaN(undefined);
       
  2442      * // => true
       
  2443      *
       
  2444      * _.isNaN(undefined);
       
  2445      * // => false
       
  2446      */
       
  2447     function isNaN(value) {
       
  2448       // `NaN` as a primitive is the only value that is not equal to itself
       
  2449       // (perform the [[Class]] check first to avoid errors with some host objects in IE)
       
  2450       return isNumber(value) && value != +value;
       
  2451     }
       
  2452 
       
  2453     /**
       
  2454      * Checks if `value` is `null`.
       
  2455      *
       
  2456      * @static
       
  2457      * @memberOf _
       
  2458      * @category Objects
       
  2459      * @param {*} value The value to check.
       
  2460      * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
       
  2461      * @example
       
  2462      *
       
  2463      * _.isNull(null);
       
  2464      * // => true
       
  2465      *
       
  2466      * _.isNull(undefined);
       
  2467      * // => false
       
  2468      */
       
  2469     function isNull(value) {
       
  2470       return value === null;
       
  2471     }
       
  2472 
       
  2473     /**
       
  2474      * Checks if `value` is a number.
       
  2475      *
       
  2476      * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
       
  2477      *
       
  2478      * @static
       
  2479      * @memberOf _
       
  2480      * @category Objects
       
  2481      * @param {*} value The value to check.
       
  2482      * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
       
  2483      * @example
       
  2484      *
       
  2485      * _.isNumber(8.4 * 5);
       
  2486      * // => true
       
  2487      */
       
  2488     function isNumber(value) {
       
  2489       return typeof value == 'number' ||
       
  2490         value && typeof value == 'object' && toString.call(value) == numberClass || false;
       
  2491     }
       
  2492 
       
  2493     /**
       
  2494      * Checks if `value` is an object created by the `Object` constructor.
       
  2495      *
       
  2496      * @static
       
  2497      * @memberOf _
       
  2498      * @category Objects
       
  2499      * @param {*} value The value to check.
       
  2500      * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
       
  2501      * @example
       
  2502      *
       
  2503      * function Shape() {
       
  2504      *   this.x = 0;
       
  2505      *   this.y = 0;
       
  2506      * }
       
  2507      *
       
  2508      * _.isPlainObject(new Shape);
       
  2509      * // => false
       
  2510      *
       
  2511      * _.isPlainObject([1, 2, 3]);
       
  2512      * // => false
       
  2513      *
       
  2514      * _.isPlainObject({ 'x': 0, 'y': 0 });
       
  2515      * // => true
       
  2516      */
       
  2517     var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
       
  2518       if (!(value && toString.call(value) == objectClass)) {
       
  2519         return false;
       
  2520       }
       
  2521       var valueOf = value.valueOf,
       
  2522           objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
       
  2523 
       
  2524       return objProto
       
  2525         ? (value == objProto || getPrototypeOf(value) == objProto)
       
  2526         : shimIsPlainObject(value);
       
  2527     };
       
  2528 
       
  2529     /**
       
  2530      * Checks if `value` is a regular expression.
       
  2531      *
       
  2532      * @static
       
  2533      * @memberOf _
       
  2534      * @category Objects
       
  2535      * @param {*} value The value to check.
       
  2536      * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
       
  2537      * @example
       
  2538      *
       
  2539      * _.isRegExp(/fred/);
       
  2540      * // => true
       
  2541      */
       
  2542     function isRegExp(value) {
       
  2543       return value && typeof value == 'object' && toString.call(value) == regexpClass || false;
       
  2544     }
       
  2545 
       
  2546     /**
       
  2547      * Checks if `value` is a string.
       
  2548      *
       
  2549      * @static
       
  2550      * @memberOf _
       
  2551      * @category Objects
       
  2552      * @param {*} value The value to check.
       
  2553      * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
       
  2554      * @example
       
  2555      *
       
  2556      * _.isString('fred');
       
  2557      * // => true
       
  2558      */
       
  2559     function isString(value) {
       
  2560       return typeof value == 'string' ||
       
  2561         value && typeof value == 'object' && toString.call(value) == stringClass || false;
       
  2562     }
       
  2563 
       
  2564     /**
       
  2565      * Checks if `value` is `undefined`.
       
  2566      *
       
  2567      * @static
       
  2568      * @memberOf _
       
  2569      * @category Objects
       
  2570      * @param {*} value The value to check.
       
  2571      * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
       
  2572      * @example
       
  2573      *
       
  2574      * _.isUndefined(void 0);
       
  2575      * // => true
       
  2576      */
       
  2577     function isUndefined(value) {
       
  2578       return typeof value == 'undefined';
       
  2579     }
       
  2580 
       
  2581     /**
       
  2582      * Creates an object with the same keys as `object` and values generated by
       
  2583      * running each own enumerable property of `object` through the callback.
       
  2584      * The callback is bound to `thisArg` and invoked with three arguments;
       
  2585      * (value, key, object).
       
  2586      *
       
  2587      * If a property name is provided for `callback` the created "_.pluck" style
       
  2588      * callback will return the property value of the given element.
       
  2589      *
       
  2590      * If an object is provided for `callback` the created "_.where" style callback
       
  2591      * will return `true` for elements that have the properties of the given object,
       
  2592      * else `false`.
       
  2593      *
       
  2594      * @static
       
  2595      * @memberOf _
       
  2596      * @category Objects
       
  2597      * @param {Object} object The object to iterate over.
       
  2598      * @param {Function|Object|string} [callback=identity] The function called
       
  2599      *  per iteration. If a property name or object is provided it will be used
       
  2600      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  2601      * @param {*} [thisArg] The `this` binding of `callback`.
       
  2602      * @returns {Array} Returns a new object with values of the results of each `callback` execution.
       
  2603      * @example
       
  2604      *
       
  2605      * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
       
  2606      * // => { 'a': 3, 'b': 6, 'c': 9 }
       
  2607      *
       
  2608      * var characters = {
       
  2609      *   'fred': { 'name': 'fred', 'age': 40 },
       
  2610      *   'pebbles': { 'name': 'pebbles', 'age': 1 }
       
  2611      * };
       
  2612      *
       
  2613      * // using "_.pluck" callback shorthand
       
  2614      * _.mapValues(characters, 'age');
       
  2615      * // => { 'fred': 40, 'pebbles': 1 }
       
  2616      */
       
  2617     function mapValues(object, callback, thisArg) {
       
  2618       var result = {};
       
  2619       callback = lodash.createCallback(callback, thisArg, 3);
       
  2620 
       
  2621       forOwn(object, function(value, key, object) {
       
  2622         result[key] = callback(value, key, object);
       
  2623       });
       
  2624       return result;
       
  2625     }
       
  2626 
       
  2627     /**
       
  2628      * Recursively merges own enumerable properties of the source object(s), that
       
  2629      * don't resolve to `undefined` into the destination object. Subsequent sources
       
  2630      * will overwrite property assignments of previous sources. If a callback is
       
  2631      * provided it will be executed to produce the merged values of the destination
       
  2632      * and source properties. If the callback returns `undefined` merging will
       
  2633      * be handled by the method instead. The callback is bound to `thisArg` and
       
  2634      * invoked with two arguments; (objectValue, sourceValue).
       
  2635      *
       
  2636      * @static
       
  2637      * @memberOf _
       
  2638      * @category Objects
       
  2639      * @param {Object} object The destination object.
       
  2640      * @param {...Object} [source] The source objects.
       
  2641      * @param {Function} [callback] The function to customize merging properties.
       
  2642      * @param {*} [thisArg] The `this` binding of `callback`.
       
  2643      * @returns {Object} Returns the destination object.
       
  2644      * @example
       
  2645      *
       
  2646      * var names = {
       
  2647      *   'characters': [
       
  2648      *     { 'name': 'barney' },
       
  2649      *     { 'name': 'fred' }
       
  2650      *   ]
       
  2651      * };
       
  2652      *
       
  2653      * var ages = {
       
  2654      *   'characters': [
       
  2655      *     { 'age': 36 },
       
  2656      *     { 'age': 40 }
       
  2657      *   ]
       
  2658      * };
       
  2659      *
       
  2660      * _.merge(names, ages);
       
  2661      * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
       
  2662      *
       
  2663      * var food = {
       
  2664      *   'fruits': ['apple'],
       
  2665      *   'vegetables': ['beet']
       
  2666      * };
       
  2667      *
       
  2668      * var otherFood = {
       
  2669      *   'fruits': ['banana'],
       
  2670      *   'vegetables': ['carrot']
       
  2671      * };
       
  2672      *
       
  2673      * _.merge(food, otherFood, function(a, b) {
       
  2674      *   return _.isArray(a) ? a.concat(b) : undefined;
       
  2675      * });
       
  2676      * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
       
  2677      */
       
  2678     function merge(object) {
       
  2679       var args = arguments,
       
  2680           length = 2;
       
  2681 
       
  2682       if (!isObject(object)) {
       
  2683         return object;
       
  2684       }
       
  2685       // allows working with `_.reduce` and `_.reduceRight` without using
       
  2686       // their `index` and `collection` arguments
       
  2687       if (typeof args[2] != 'number') {
       
  2688         length = args.length;
       
  2689       }
       
  2690       if (length > 3 && typeof args[length - 2] == 'function') {
       
  2691         var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
       
  2692       } else if (length > 2 && typeof args[length - 1] == 'function') {
       
  2693         callback = args[--length];
       
  2694       }
       
  2695       var sources = slice(arguments, 1, length),
       
  2696           index = -1,
       
  2697           stackA = getArray(),
       
  2698           stackB = getArray();
       
  2699 
       
  2700       while (++index < length) {
       
  2701         baseMerge(object, sources[index], callback, stackA, stackB);
       
  2702       }
       
  2703       releaseArray(stackA);
       
  2704       releaseArray(stackB);
       
  2705       return object;
       
  2706     }
       
  2707 
       
  2708     /**
       
  2709      * Creates a shallow clone of `object` excluding the specified properties.
       
  2710      * Property names may be specified as individual arguments or as arrays of
       
  2711      * property names. If a callback is provided it will be executed for each
       
  2712      * property of `object` omitting the properties the callback returns truey
       
  2713      * for. The callback is bound to `thisArg` and invoked with three arguments;
       
  2714      * (value, key, object).
       
  2715      *
       
  2716      * @static
       
  2717      * @memberOf _
       
  2718      * @category Objects
       
  2719      * @param {Object} object The source object.
       
  2720      * @param {Function|...string|string[]} [callback] The properties to omit or the
       
  2721      *  function called per iteration.
       
  2722      * @param {*} [thisArg] The `this` binding of `callback`.
       
  2723      * @returns {Object} Returns an object without the omitted properties.
       
  2724      * @example
       
  2725      *
       
  2726      * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
       
  2727      * // => { 'name': 'fred' }
       
  2728      *
       
  2729      * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
       
  2730      *   return typeof value == 'number';
       
  2731      * });
       
  2732      * // => { 'name': 'fred' }
       
  2733      */
       
  2734     function omit(object, callback, thisArg) {
       
  2735       var result = {};
       
  2736       if (typeof callback != 'function') {
       
  2737         var props = [];
       
  2738         forIn(object, function(value, key) {
       
  2739           props.push(key);
       
  2740         });
       
  2741         props = baseDifference(props, baseFlatten(arguments, true, false, 1));
       
  2742 
       
  2743         var index = -1,
       
  2744             length = props.length;
       
  2745 
       
  2746         while (++index < length) {
       
  2747           var key = props[index];
       
  2748           result[key] = object[key];
       
  2749         }
       
  2750       } else {
       
  2751         callback = lodash.createCallback(callback, thisArg, 3);
       
  2752         forIn(object, function(value, key, object) {
       
  2753           if (!callback(value, key, object)) {
       
  2754             result[key] = value;
       
  2755           }
       
  2756         });
       
  2757       }
       
  2758       return result;
       
  2759     }
       
  2760 
       
  2761     /**
       
  2762      * Creates a two dimensional array of an object's key-value pairs,
       
  2763      * i.e. `[[key1, value1], [key2, value2]]`.
       
  2764      *
       
  2765      * @static
       
  2766      * @memberOf _
       
  2767      * @category Objects
       
  2768      * @param {Object} object The object to inspect.
       
  2769      * @returns {Array} Returns new array of key-value pairs.
       
  2770      * @example
       
  2771      *
       
  2772      * _.pairs({ 'barney': 36, 'fred': 40 });
       
  2773      * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
       
  2774      */
       
  2775     function pairs(object) {
       
  2776       var index = -1,
       
  2777           props = keys(object),
       
  2778           length = props.length,
       
  2779           result = Array(length);
       
  2780 
       
  2781       while (++index < length) {
       
  2782         var key = props[index];
       
  2783         result[index] = [key, object[key]];
       
  2784       }
       
  2785       return result;
       
  2786     }
       
  2787 
       
  2788     /**
       
  2789      * Creates a shallow clone of `object` composed of the specified properties.
       
  2790      * Property names may be specified as individual arguments or as arrays of
       
  2791      * property names. If a callback is provided it will be executed for each
       
  2792      * property of `object` picking the properties the callback returns truey
       
  2793      * for. The callback is bound to `thisArg` and invoked with three arguments;
       
  2794      * (value, key, object).
       
  2795      *
       
  2796      * @static
       
  2797      * @memberOf _
       
  2798      * @category Objects
       
  2799      * @param {Object} object The source object.
       
  2800      * @param {Function|...string|string[]} [callback] The function called per
       
  2801      *  iteration or property names to pick, specified as individual property
       
  2802      *  names or arrays of property names.
       
  2803      * @param {*} [thisArg] The `this` binding of `callback`.
       
  2804      * @returns {Object} Returns an object composed of the picked properties.
       
  2805      * @example
       
  2806      *
       
  2807      * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
       
  2808      * // => { 'name': 'fred' }
       
  2809      *
       
  2810      * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
       
  2811      *   return key.charAt(0) != '_';
       
  2812      * });
       
  2813      * // => { 'name': 'fred' }
       
  2814      */
       
  2815     function pick(object, callback, thisArg) {
       
  2816       var result = {};
       
  2817       if (typeof callback != 'function') {
       
  2818         var index = -1,
       
  2819             props = baseFlatten(arguments, true, false, 1),
       
  2820             length = isObject(object) ? props.length : 0;
       
  2821 
       
  2822         while (++index < length) {
       
  2823           var key = props[index];
       
  2824           if (key in object) {
       
  2825             result[key] = object[key];
       
  2826           }
       
  2827         }
       
  2828       } else {
       
  2829         callback = lodash.createCallback(callback, thisArg, 3);
       
  2830         forIn(object, function(value, key, object) {
       
  2831           if (callback(value, key, object)) {
       
  2832             result[key] = value;
       
  2833           }
       
  2834         });
       
  2835       }
       
  2836       return result;
       
  2837     }
       
  2838 
       
  2839     /**
       
  2840      * An alternative to `_.reduce` this method transforms `object` to a new
       
  2841      * `accumulator` object which is the result of running each of its own
       
  2842      * enumerable properties through a callback, with each callback execution
       
  2843      * potentially mutating the `accumulator` object. The callback is bound to
       
  2844      * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
       
  2845      * Callbacks may exit iteration early by explicitly returning `false`.
       
  2846      *
       
  2847      * @static
       
  2848      * @memberOf _
       
  2849      * @category Objects
       
  2850      * @param {Array|Object} object The object to iterate over.
       
  2851      * @param {Function} [callback=identity] The function called per iteration.
       
  2852      * @param {*} [accumulator] The custom accumulator value.
       
  2853      * @param {*} [thisArg] The `this` binding of `callback`.
       
  2854      * @returns {*} Returns the accumulated value.
       
  2855      * @example
       
  2856      *
       
  2857      * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
       
  2858      *   num *= num;
       
  2859      *   if (num % 2) {
       
  2860      *     return result.push(num) < 3;
       
  2861      *   }
       
  2862      * });
       
  2863      * // => [1, 9, 25]
       
  2864      *
       
  2865      * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
       
  2866      *   result[key] = num * 3;
       
  2867      * });
       
  2868      * // => { 'a': 3, 'b': 6, 'c': 9 }
       
  2869      */
       
  2870     function transform(object, callback, accumulator, thisArg) {
       
  2871       var isArr = isArray(object);
       
  2872       if (accumulator == null) {
       
  2873         if (isArr) {
       
  2874           accumulator = [];
       
  2875         } else {
       
  2876           var ctor = object && object.constructor,
       
  2877               proto = ctor && ctor.prototype;
       
  2878 
       
  2879           accumulator = baseCreate(proto);
       
  2880         }
       
  2881       }
       
  2882       if (callback) {
       
  2883         callback = lodash.createCallback(callback, thisArg, 4);
       
  2884         (isArr ? forEach : forOwn)(object, function(value, index, object) {
       
  2885           return callback(accumulator, value, index, object);
       
  2886         });
       
  2887       }
       
  2888       return accumulator;
       
  2889     }
       
  2890 
       
  2891     /**
       
  2892      * Creates an array composed of the own enumerable property values of `object`.
       
  2893      *
       
  2894      * @static
       
  2895      * @memberOf _
       
  2896      * @category Objects
       
  2897      * @param {Object} object The object to inspect.
       
  2898      * @returns {Array} Returns an array of property values.
       
  2899      * @example
       
  2900      *
       
  2901      * _.values({ 'one': 1, 'two': 2, 'three': 3 });
       
  2902      * // => [1, 2, 3] (property order is not guaranteed across environments)
       
  2903      */
       
  2904     function values(object) {
       
  2905       var index = -1,
       
  2906           props = keys(object),
       
  2907           length = props.length,
       
  2908           result = Array(length);
       
  2909 
       
  2910       while (++index < length) {
       
  2911         result[index] = object[props[index]];
       
  2912       }
       
  2913       return result;
       
  2914     }
       
  2915 
       
  2916     /*--------------------------------------------------------------------------*/
       
  2917 
       
  2918     /**
       
  2919      * Creates an array of elements from the specified indexes, or keys, of the
       
  2920      * `collection`. Indexes may be specified as individual arguments or as arrays
       
  2921      * of indexes.
       
  2922      *
       
  2923      * @static
       
  2924      * @memberOf _
       
  2925      * @category Collections
       
  2926      * @param {Array|Object|string} collection The collection to iterate over.
       
  2927      * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
       
  2928      *   to retrieve, specified as individual indexes or arrays of indexes.
       
  2929      * @returns {Array} Returns a new array of elements corresponding to the
       
  2930      *  provided indexes.
       
  2931      * @example
       
  2932      *
       
  2933      * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
       
  2934      * // => ['a', 'c', 'e']
       
  2935      *
       
  2936      * _.at(['fred', 'barney', 'pebbles'], 0, 2);
       
  2937      * // => ['fred', 'pebbles']
       
  2938      */
       
  2939     function at(collection) {
       
  2940       var args = arguments,
       
  2941           index = -1,
       
  2942           props = baseFlatten(args, true, false, 1),
       
  2943           length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
       
  2944           result = Array(length);
       
  2945 
       
  2946       while(++index < length) {
       
  2947         result[index] = collection[props[index]];
       
  2948       }
       
  2949       return result;
       
  2950     }
       
  2951 
       
  2952     /**
       
  2953      * Checks if a given value is present in a collection using strict equality
       
  2954      * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
       
  2955      * offset from the end of the collection.
       
  2956      *
       
  2957      * @static
       
  2958      * @memberOf _
       
  2959      * @alias include
       
  2960      * @category Collections
       
  2961      * @param {Array|Object|string} collection The collection to iterate over.
       
  2962      * @param {*} target The value to check for.
       
  2963      * @param {number} [fromIndex=0] The index to search from.
       
  2964      * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
       
  2965      * @example
       
  2966      *
       
  2967      * _.contains([1, 2, 3], 1);
       
  2968      * // => true
       
  2969      *
       
  2970      * _.contains([1, 2, 3], 1, 2);
       
  2971      * // => false
       
  2972      *
       
  2973      * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
       
  2974      * // => true
       
  2975      *
       
  2976      * _.contains('pebbles', 'eb');
       
  2977      * // => true
       
  2978      */
       
  2979     function contains(collection, target, fromIndex) {
       
  2980       var index = -1,
       
  2981           indexOf = getIndexOf(),
       
  2982           length = collection ? collection.length : 0,
       
  2983           result = false;
       
  2984 
       
  2985       fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
       
  2986       if (isArray(collection)) {
       
  2987         result = indexOf(collection, target, fromIndex) > -1;
       
  2988       } else if (typeof length == 'number') {
       
  2989         result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
       
  2990       } else {
       
  2991         forOwn(collection, function(value) {
       
  2992           if (++index >= fromIndex) {
       
  2993             return !(result = value === target);
       
  2994           }
       
  2995         });
       
  2996       }
       
  2997       return result;
       
  2998     }
       
  2999 
       
  3000     /**
       
  3001      * Creates an object composed of keys generated from the results of running
       
  3002      * each element of `collection` through the callback. The corresponding value
       
  3003      * of each key is the number of times the key was returned by the callback.
       
  3004      * The callback is bound to `thisArg` and invoked with three arguments;
       
  3005      * (value, index|key, collection).
       
  3006      *
       
  3007      * If a property name is provided for `callback` the created "_.pluck" style
       
  3008      * callback will return the property value of the given element.
       
  3009      *
       
  3010      * If an object is provided for `callback` the created "_.where" style callback
       
  3011      * will return `true` for elements that have the properties of the given object,
       
  3012      * else `false`.
       
  3013      *
       
  3014      * @static
       
  3015      * @memberOf _
       
  3016      * @category Collections
       
  3017      * @param {Array|Object|string} collection The collection to iterate over.
       
  3018      * @param {Function|Object|string} [callback=identity] The function called
       
  3019      *  per iteration. If a property name or object is provided it will be used
       
  3020      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3021      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3022      * @returns {Object} Returns the composed aggregate object.
       
  3023      * @example
       
  3024      *
       
  3025      * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
       
  3026      * // => { '4': 1, '6': 2 }
       
  3027      *
       
  3028      * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
       
  3029      * // => { '4': 1, '6': 2 }
       
  3030      *
       
  3031      * _.countBy(['one', 'two', 'three'], 'length');
       
  3032      * // => { '3': 2, '5': 1 }
       
  3033      */
       
  3034     var countBy = createAggregator(function(result, value, key) {
       
  3035       (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
       
  3036     });
       
  3037 
       
  3038     /**
       
  3039      * Checks if the given callback returns truey value for **all** elements of
       
  3040      * a collection. The callback is bound to `thisArg` and invoked with three
       
  3041      * arguments; (value, index|key, collection).
       
  3042      *
       
  3043      * If a property name is provided for `callback` the created "_.pluck" style
       
  3044      * callback will return the property value of the given element.
       
  3045      *
       
  3046      * If an object is provided for `callback` the created "_.where" style callback
       
  3047      * will return `true` for elements that have the properties of the given object,
       
  3048      * else `false`.
       
  3049      *
       
  3050      * @static
       
  3051      * @memberOf _
       
  3052      * @alias all
       
  3053      * @category Collections
       
  3054      * @param {Array|Object|string} collection The collection to iterate over.
       
  3055      * @param {Function|Object|string} [callback=identity] The function called
       
  3056      *  per iteration. If a property name or object is provided it will be used
       
  3057      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3058      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3059      * @returns {boolean} Returns `true` if all elements passed the callback check,
       
  3060      *  else `false`.
       
  3061      * @example
       
  3062      *
       
  3063      * _.every([true, 1, null, 'yes']);
       
  3064      * // => false
       
  3065      *
       
  3066      * var characters = [
       
  3067      *   { 'name': 'barney', 'age': 36 },
       
  3068      *   { 'name': 'fred',   'age': 40 }
       
  3069      * ];
       
  3070      *
       
  3071      * // using "_.pluck" callback shorthand
       
  3072      * _.every(characters, 'age');
       
  3073      * // => true
       
  3074      *
       
  3075      * // using "_.where" callback shorthand
       
  3076      * _.every(characters, { 'age': 36 });
       
  3077      * // => false
       
  3078      */
       
  3079     function every(collection, callback, thisArg) {
       
  3080       var result = true;
       
  3081       callback = lodash.createCallback(callback, thisArg, 3);
       
  3082 
       
  3083       var index = -1,
       
  3084           length = collection ? collection.length : 0;
       
  3085 
       
  3086       if (typeof length == 'number') {
       
  3087         while (++index < length) {
       
  3088           if (!(result = !!callback(collection[index], index, collection))) {
       
  3089             break;
       
  3090           }
       
  3091         }
       
  3092       } else {
       
  3093         forOwn(collection, function(value, index, collection) {
       
  3094           return (result = !!callback(value, index, collection));
       
  3095         });
       
  3096       }
       
  3097       return result;
       
  3098     }
       
  3099 
       
  3100     /**
       
  3101      * Iterates over elements of a collection, returning an array of all elements
       
  3102      * the callback returns truey for. The callback is bound to `thisArg` and
       
  3103      * invoked with three arguments; (value, index|key, collection).
       
  3104      *
       
  3105      * If a property name is provided for `callback` the created "_.pluck" style
       
  3106      * callback will return the property value of the given element.
       
  3107      *
       
  3108      * If an object is provided for `callback` the created "_.where" style callback
       
  3109      * will return `true` for elements that have the properties of the given object,
       
  3110      * else `false`.
       
  3111      *
       
  3112      * @static
       
  3113      * @memberOf _
       
  3114      * @alias select
       
  3115      * @category Collections
       
  3116      * @param {Array|Object|string} collection The collection to iterate over.
       
  3117      * @param {Function|Object|string} [callback=identity] The function called
       
  3118      *  per iteration. If a property name or object is provided it will be used
       
  3119      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3120      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3121      * @returns {Array} Returns a new array of elements that passed the callback check.
       
  3122      * @example
       
  3123      *
       
  3124      * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
       
  3125      * // => [2, 4, 6]
       
  3126      *
       
  3127      * var characters = [
       
  3128      *   { 'name': 'barney', 'age': 36, 'blocked': false },
       
  3129      *   { 'name': 'fred',   'age': 40, 'blocked': true }
       
  3130      * ];
       
  3131      *
       
  3132      * // using "_.pluck" callback shorthand
       
  3133      * _.filter(characters, 'blocked');
       
  3134      * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
       
  3135      *
       
  3136      * // using "_.where" callback shorthand
       
  3137      * _.filter(characters, { 'age': 36 });
       
  3138      * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
       
  3139      */
       
  3140     function filter(collection, callback, thisArg) {
       
  3141       var result = [];
       
  3142       callback = lodash.createCallback(callback, thisArg, 3);
       
  3143 
       
  3144       var index = -1,
       
  3145           length = collection ? collection.length : 0;
       
  3146 
       
  3147       if (typeof length == 'number') {
       
  3148         while (++index < length) {
       
  3149           var value = collection[index];
       
  3150           if (callback(value, index, collection)) {
       
  3151             result.push(value);
       
  3152           }
       
  3153         }
       
  3154       } else {
       
  3155         forOwn(collection, function(value, index, collection) {
       
  3156           if (callback(value, index, collection)) {
       
  3157             result.push(value);
       
  3158           }
       
  3159         });
       
  3160       }
       
  3161       return result;
       
  3162     }
       
  3163 
       
  3164     /**
       
  3165      * Iterates over elements of a collection, returning the first element that
       
  3166      * the callback returns truey for. The callback is bound to `thisArg` and
       
  3167      * invoked with three arguments; (value, index|key, collection).
       
  3168      *
       
  3169      * If a property name is provided for `callback` the created "_.pluck" style
       
  3170      * callback will return the property value of the given element.
       
  3171      *
       
  3172      * If an object is provided for `callback` the created "_.where" style callback
       
  3173      * will return `true` for elements that have the properties of the given object,
       
  3174      * else `false`.
       
  3175      *
       
  3176      * @static
       
  3177      * @memberOf _
       
  3178      * @alias detect, findWhere
       
  3179      * @category Collections
       
  3180      * @param {Array|Object|string} collection The collection to iterate over.
       
  3181      * @param {Function|Object|string} [callback=identity] The function called
       
  3182      *  per iteration. If a property name or object is provided it will be used
       
  3183      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3184      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3185      * @returns {*} Returns the found element, else `undefined`.
       
  3186      * @example
       
  3187      *
       
  3188      * var characters = [
       
  3189      *   { 'name': 'barney',  'age': 36, 'blocked': false },
       
  3190      *   { 'name': 'fred',    'age': 40, 'blocked': true },
       
  3191      *   { 'name': 'pebbles', 'age': 1,  'blocked': false }
       
  3192      * ];
       
  3193      *
       
  3194      * _.find(characters, function(chr) {
       
  3195      *   return chr.age < 40;
       
  3196      * });
       
  3197      * // => { 'name': 'barney', 'age': 36, 'blocked': false }
       
  3198      *
       
  3199      * // using "_.where" callback shorthand
       
  3200      * _.find(characters, { 'age': 1 });
       
  3201      * // =>  { 'name': 'pebbles', 'age': 1, 'blocked': false }
       
  3202      *
       
  3203      * // using "_.pluck" callback shorthand
       
  3204      * _.find(characters, 'blocked');
       
  3205      * // => { 'name': 'fred', 'age': 40, 'blocked': true }
       
  3206      */
       
  3207     function find(collection, callback, thisArg) {
       
  3208       callback = lodash.createCallback(callback, thisArg, 3);
       
  3209 
       
  3210       var index = -1,
       
  3211           length = collection ? collection.length : 0;
       
  3212 
       
  3213       if (typeof length == 'number') {
       
  3214         while (++index < length) {
       
  3215           var value = collection[index];
       
  3216           if (callback(value, index, collection)) {
       
  3217             return value;
       
  3218           }
       
  3219         }
       
  3220       } else {
       
  3221         var result;
       
  3222         forOwn(collection, function(value, index, collection) {
       
  3223           if (callback(value, index, collection)) {
       
  3224             result = value;
       
  3225             return false;
       
  3226           }
       
  3227         });
       
  3228         return result;
       
  3229       }
       
  3230     }
       
  3231 
       
  3232     /**
       
  3233      * This method is like `_.find` except that it iterates over elements
       
  3234      * of a `collection` from right to left.
       
  3235      *
       
  3236      * @static
       
  3237      * @memberOf _
       
  3238      * @category Collections
       
  3239      * @param {Array|Object|string} collection The collection to iterate over.
       
  3240      * @param {Function|Object|string} [callback=identity] The function called
       
  3241      *  per iteration. If a property name or object is provided it will be used
       
  3242      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3243      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3244      * @returns {*} Returns the found element, else `undefined`.
       
  3245      * @example
       
  3246      *
       
  3247      * _.findLast([1, 2, 3, 4], function(num) {
       
  3248      *   return num % 2 == 1;
       
  3249      * });
       
  3250      * // => 3
       
  3251      */
       
  3252     function findLast(collection, callback, thisArg) {
       
  3253       var result;
       
  3254       callback = lodash.createCallback(callback, thisArg, 3);
       
  3255       forEachRight(collection, function(value, index, collection) {
       
  3256         if (callback(value, index, collection)) {
       
  3257           result = value;
       
  3258           return false;
       
  3259         }
       
  3260       });
       
  3261       return result;
       
  3262     }
       
  3263 
       
  3264     /**
       
  3265      * Iterates over elements of a collection, executing the callback for each
       
  3266      * element. The callback is bound to `thisArg` and invoked with three arguments;
       
  3267      * (value, index|key, collection). Callbacks may exit iteration early by
       
  3268      * explicitly returning `false`.
       
  3269      *
       
  3270      * Note: As with other "Collections" methods, objects with a `length` property
       
  3271      * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
       
  3272      * may be used for object iteration.
       
  3273      *
       
  3274      * @static
       
  3275      * @memberOf _
       
  3276      * @alias each
       
  3277      * @category Collections
       
  3278      * @param {Array|Object|string} collection The collection to iterate over.
       
  3279      * @param {Function} [callback=identity] The function called per iteration.
       
  3280      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3281      * @returns {Array|Object|string} Returns `collection`.
       
  3282      * @example
       
  3283      *
       
  3284      * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
       
  3285      * // => logs each number and returns '1,2,3'
       
  3286      *
       
  3287      * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
       
  3288      * // => logs each number and returns the object (property order is not guaranteed across environments)
       
  3289      */
       
  3290     function forEach(collection, callback, thisArg) {
       
  3291       var index = -1,
       
  3292           length = collection ? collection.length : 0;
       
  3293 
       
  3294       callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
       
  3295       if (typeof length == 'number') {
       
  3296         while (++index < length) {
       
  3297           if (callback(collection[index], index, collection) === false) {
       
  3298             break;
       
  3299           }
       
  3300         }
       
  3301       } else {
       
  3302         forOwn(collection, callback);
       
  3303       }
       
  3304       return collection;
       
  3305     }
       
  3306 
       
  3307     /**
       
  3308      * This method is like `_.forEach` except that it iterates over elements
       
  3309      * of a `collection` from right to left.
       
  3310      *
       
  3311      * @static
       
  3312      * @memberOf _
       
  3313      * @alias eachRight
       
  3314      * @category Collections
       
  3315      * @param {Array|Object|string} collection The collection to iterate over.
       
  3316      * @param {Function} [callback=identity] The function called per iteration.
       
  3317      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3318      * @returns {Array|Object|string} Returns `collection`.
       
  3319      * @example
       
  3320      *
       
  3321      * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
       
  3322      * // => logs each number from right to left and returns '3,2,1'
       
  3323      */
       
  3324     function forEachRight(collection, callback, thisArg) {
       
  3325       var length = collection ? collection.length : 0;
       
  3326       callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
       
  3327       if (typeof length == 'number') {
       
  3328         while (length--) {
       
  3329           if (callback(collection[length], length, collection) === false) {
       
  3330             break;
       
  3331           }
       
  3332         }
       
  3333       } else {
       
  3334         var props = keys(collection);
       
  3335         length = props.length;
       
  3336         forOwn(collection, function(value, key, collection) {
       
  3337           key = props ? props[--length] : --length;
       
  3338           return callback(collection[key], key, collection);
       
  3339         });
       
  3340       }
       
  3341       return collection;
       
  3342     }
       
  3343 
       
  3344     /**
       
  3345      * Creates an object composed of keys generated from the results of running
       
  3346      * each element of a collection through the callback. The corresponding value
       
  3347      * of each key is an array of the elements responsible for generating the key.
       
  3348      * The callback is bound to `thisArg` and invoked with three arguments;
       
  3349      * (value, index|key, collection).
       
  3350      *
       
  3351      * If a property name is provided for `callback` the created "_.pluck" style
       
  3352      * callback will return the property value of the given element.
       
  3353      *
       
  3354      * If an object is provided for `callback` the created "_.where" style callback
       
  3355      * will return `true` for elements that have the properties of the given object,
       
  3356      * else `false`
       
  3357      *
       
  3358      * @static
       
  3359      * @memberOf _
       
  3360      * @category Collections
       
  3361      * @param {Array|Object|string} collection The collection to iterate over.
       
  3362      * @param {Function|Object|string} [callback=identity] The function called
       
  3363      *  per iteration. If a property name or object is provided it will be used
       
  3364      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3365      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3366      * @returns {Object} Returns the composed aggregate object.
       
  3367      * @example
       
  3368      *
       
  3369      * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
       
  3370      * // => { '4': [4.2], '6': [6.1, 6.4] }
       
  3371      *
       
  3372      * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
       
  3373      * // => { '4': [4.2], '6': [6.1, 6.4] }
       
  3374      *
       
  3375      * // using "_.pluck" callback shorthand
       
  3376      * _.groupBy(['one', 'two', 'three'], 'length');
       
  3377      * // => { '3': ['one', 'two'], '5': ['three'] }
       
  3378      */
       
  3379     var groupBy = createAggregator(function(result, value, key) {
       
  3380       (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
       
  3381     });
       
  3382 
       
  3383     /**
       
  3384      * Creates an object composed of keys generated from the results of running
       
  3385      * each element of the collection through the given callback. The corresponding
       
  3386      * value of each key is the last element responsible for generating the key.
       
  3387      * The callback is bound to `thisArg` and invoked with three arguments;
       
  3388      * (value, index|key, collection).
       
  3389      *
       
  3390      * If a property name is provided for `callback` the created "_.pluck" style
       
  3391      * callback will return the property value of the given element.
       
  3392      *
       
  3393      * If an object is provided for `callback` the created "_.where" style callback
       
  3394      * will return `true` for elements that have the properties of the given object,
       
  3395      * else `false`.
       
  3396      *
       
  3397      * @static
       
  3398      * @memberOf _
       
  3399      * @category Collections
       
  3400      * @param {Array|Object|string} collection The collection to iterate over.
       
  3401      * @param {Function|Object|string} [callback=identity] The function called
       
  3402      *  per iteration. If a property name or object is provided it will be used
       
  3403      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3404      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3405      * @returns {Object} Returns the composed aggregate object.
       
  3406      * @example
       
  3407      *
       
  3408      * var keys = [
       
  3409      *   { 'dir': 'left', 'code': 97 },
       
  3410      *   { 'dir': 'right', 'code': 100 }
       
  3411      * ];
       
  3412      *
       
  3413      * _.indexBy(keys, 'dir');
       
  3414      * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
       
  3415      *
       
  3416      * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
       
  3417      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
       
  3418      *
       
  3419      * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
       
  3420      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
       
  3421      */
       
  3422     var indexBy = createAggregator(function(result, value, key) {
       
  3423       result[key] = value;
       
  3424     });
       
  3425 
       
  3426     /**
       
  3427      * Invokes the method named by `methodName` on each element in the `collection`
       
  3428      * returning an array of the results of each invoked method. Additional arguments
       
  3429      * will be provided to each invoked method. If `methodName` is a function it
       
  3430      * will be invoked for, and `this` bound to, each element in the `collection`.
       
  3431      *
       
  3432      * @static
       
  3433      * @memberOf _
       
  3434      * @category Collections
       
  3435      * @param {Array|Object|string} collection The collection to iterate over.
       
  3436      * @param {Function|string} methodName The name of the method to invoke or
       
  3437      *  the function invoked per iteration.
       
  3438      * @param {...*} [arg] Arguments to invoke the method with.
       
  3439      * @returns {Array} Returns a new array of the results of each invoked method.
       
  3440      * @example
       
  3441      *
       
  3442      * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
       
  3443      * // => [[1, 5, 7], [1, 2, 3]]
       
  3444      *
       
  3445      * _.invoke([123, 456], String.prototype.split, '');
       
  3446      * // => [['1', '2', '3'], ['4', '5', '6']]
       
  3447      */
       
  3448     function invoke(collection, methodName) {
       
  3449       var args = slice(arguments, 2),
       
  3450           index = -1,
       
  3451           isFunc = typeof methodName == 'function',
       
  3452           length = collection ? collection.length : 0,
       
  3453           result = Array(typeof length == 'number' ? length : 0);
       
  3454 
       
  3455       forEach(collection, function(value) {
       
  3456         result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
       
  3457       });
       
  3458       return result;
       
  3459     }
       
  3460 
       
  3461     /**
       
  3462      * Creates an array of values by running each element in the collection
       
  3463      * through the callback. The callback is bound to `thisArg` and invoked with
       
  3464      * three arguments; (value, index|key, collection).
       
  3465      *
       
  3466      * If a property name is provided for `callback` the created "_.pluck" style
       
  3467      * callback will return the property value of the given element.
       
  3468      *
       
  3469      * If an object is provided for `callback` the created "_.where" style callback
       
  3470      * will return `true` for elements that have the properties of the given object,
       
  3471      * else `false`.
       
  3472      *
       
  3473      * @static
       
  3474      * @memberOf _
       
  3475      * @alias collect
       
  3476      * @category Collections
       
  3477      * @param {Array|Object|string} collection The collection to iterate over.
       
  3478      * @param {Function|Object|string} [callback=identity] The function called
       
  3479      *  per iteration. If a property name or object is provided it will be used
       
  3480      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3481      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3482      * @returns {Array} Returns a new array of the results of each `callback` execution.
       
  3483      * @example
       
  3484      *
       
  3485      * _.map([1, 2, 3], function(num) { return num * 3; });
       
  3486      * // => [3, 6, 9]
       
  3487      *
       
  3488      * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
       
  3489      * // => [3, 6, 9] (property order is not guaranteed across environments)
       
  3490      *
       
  3491      * var characters = [
       
  3492      *   { 'name': 'barney', 'age': 36 },
       
  3493      *   { 'name': 'fred',   'age': 40 }
       
  3494      * ];
       
  3495      *
       
  3496      * // using "_.pluck" callback shorthand
       
  3497      * _.map(characters, 'name');
       
  3498      * // => ['barney', 'fred']
       
  3499      */
       
  3500     function map(collection, callback, thisArg) {
       
  3501       var index = -1,
       
  3502           length = collection ? collection.length : 0;
       
  3503 
       
  3504       callback = lodash.createCallback(callback, thisArg, 3);
       
  3505       if (typeof length == 'number') {
       
  3506         var result = Array(length);
       
  3507         while (++index < length) {
       
  3508           result[index] = callback(collection[index], index, collection);
       
  3509         }
       
  3510       } else {
       
  3511         result = [];
       
  3512         forOwn(collection, function(value, key, collection) {
       
  3513           result[++index] = callback(value, key, collection);
       
  3514         });
       
  3515       }
       
  3516       return result;
       
  3517     }
       
  3518 
       
  3519     /**
       
  3520      * Retrieves the maximum value of a collection. If the collection is empty or
       
  3521      * falsey `-Infinity` is returned. If a callback is provided it will be executed
       
  3522      * for each value in the collection to generate the criterion by which the value
       
  3523      * is ranked. The callback is bound to `thisArg` and invoked with three
       
  3524      * arguments; (value, index, collection).
       
  3525      *
       
  3526      * If a property name is provided for `callback` the created "_.pluck" style
       
  3527      * callback will return the property value of the given element.
       
  3528      *
       
  3529      * If an object is provided for `callback` the created "_.where" style callback
       
  3530      * will return `true` for elements that have the properties of the given object,
       
  3531      * else `false`.
       
  3532      *
       
  3533      * @static
       
  3534      * @memberOf _
       
  3535      * @category Collections
       
  3536      * @param {Array|Object|string} collection The collection to iterate over.
       
  3537      * @param {Function|Object|string} [callback=identity] The function called
       
  3538      *  per iteration. If a property name or object is provided it will be used
       
  3539      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3540      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3541      * @returns {*} Returns the maximum value.
       
  3542      * @example
       
  3543      *
       
  3544      * _.max([4, 2, 8, 6]);
       
  3545      * // => 8
       
  3546      *
       
  3547      * var characters = [
       
  3548      *   { 'name': 'barney', 'age': 36 },
       
  3549      *   { 'name': 'fred',   'age': 40 }
       
  3550      * ];
       
  3551      *
       
  3552      * _.max(characters, function(chr) { return chr.age; });
       
  3553      * // => { 'name': 'fred', 'age': 40 };
       
  3554      *
       
  3555      * // using "_.pluck" callback shorthand
       
  3556      * _.max(characters, 'age');
       
  3557      * // => { 'name': 'fred', 'age': 40 };
       
  3558      */
       
  3559     function max(collection, callback, thisArg) {
       
  3560       var computed = -Infinity,
       
  3561           result = computed;
       
  3562 
       
  3563       // allows working with functions like `_.map` without using
       
  3564       // their `index` argument as a callback
       
  3565       if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
       
  3566         callback = null;
       
  3567       }
       
  3568       if (callback == null && isArray(collection)) {
       
  3569         var index = -1,
       
  3570             length = collection.length;
       
  3571 
       
  3572         while (++index < length) {
       
  3573           var value = collection[index];
       
  3574           if (value > result) {
       
  3575             result = value;
       
  3576           }
       
  3577         }
       
  3578       } else {
       
  3579         callback = (callback == null && isString(collection))
       
  3580           ? charAtCallback
       
  3581           : lodash.createCallback(callback, thisArg, 3);
       
  3582 
       
  3583         forEach(collection, function(value, index, collection) {
       
  3584           var current = callback(value, index, collection);
       
  3585           if (current > computed) {
       
  3586             computed = current;
       
  3587             result = value;
       
  3588           }
       
  3589         });
       
  3590       }
       
  3591       return result;
       
  3592     }
       
  3593 
       
  3594     /**
       
  3595      * Retrieves the minimum value of a collection. If the collection is empty or
       
  3596      * falsey `Infinity` is returned. If a callback is provided it will be executed
       
  3597      * for each value in the collection to generate the criterion by which the value
       
  3598      * is ranked. The callback is bound to `thisArg` and invoked with three
       
  3599      * arguments; (value, index, collection).
       
  3600      *
       
  3601      * If a property name is provided for `callback` the created "_.pluck" style
       
  3602      * callback will return the property value of the given element.
       
  3603      *
       
  3604      * If an object is provided for `callback` the created "_.where" style callback
       
  3605      * will return `true` for elements that have the properties of the given object,
       
  3606      * else `false`.
       
  3607      *
       
  3608      * @static
       
  3609      * @memberOf _
       
  3610      * @category Collections
       
  3611      * @param {Array|Object|string} collection The collection to iterate over.
       
  3612      * @param {Function|Object|string} [callback=identity] The function called
       
  3613      *  per iteration. If a property name or object is provided it will be used
       
  3614      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3615      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3616      * @returns {*} Returns the minimum value.
       
  3617      * @example
       
  3618      *
       
  3619      * _.min([4, 2, 8, 6]);
       
  3620      * // => 2
       
  3621      *
       
  3622      * var characters = [
       
  3623      *   { 'name': 'barney', 'age': 36 },
       
  3624      *   { 'name': 'fred',   'age': 40 }
       
  3625      * ];
       
  3626      *
       
  3627      * _.min(characters, function(chr) { return chr.age; });
       
  3628      * // => { 'name': 'barney', 'age': 36 };
       
  3629      *
       
  3630      * // using "_.pluck" callback shorthand
       
  3631      * _.min(characters, 'age');
       
  3632      * // => { 'name': 'barney', 'age': 36 };
       
  3633      */
       
  3634     function min(collection, callback, thisArg) {
       
  3635       var computed = Infinity,
       
  3636           result = computed;
       
  3637 
       
  3638       // allows working with functions like `_.map` without using
       
  3639       // their `index` argument as a callback
       
  3640       if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
       
  3641         callback = null;
       
  3642       }
       
  3643       if (callback == null && isArray(collection)) {
       
  3644         var index = -1,
       
  3645             length = collection.length;
       
  3646 
       
  3647         while (++index < length) {
       
  3648           var value = collection[index];
       
  3649           if (value < result) {
       
  3650             result = value;
       
  3651           }
       
  3652         }
       
  3653       } else {
       
  3654         callback = (callback == null && isString(collection))
       
  3655           ? charAtCallback
       
  3656           : lodash.createCallback(callback, thisArg, 3);
       
  3657 
       
  3658         forEach(collection, function(value, index, collection) {
       
  3659           var current = callback(value, index, collection);
       
  3660           if (current < computed) {
       
  3661             computed = current;
       
  3662             result = value;
       
  3663           }
       
  3664         });
       
  3665       }
       
  3666       return result;
       
  3667     }
       
  3668 
       
  3669     /**
       
  3670      * Retrieves the value of a specified property from all elements in the collection.
       
  3671      *
       
  3672      * @static
       
  3673      * @memberOf _
       
  3674      * @type Function
       
  3675      * @category Collections
       
  3676      * @param {Array|Object|string} collection The collection to iterate over.
       
  3677      * @param {string} property The name of the property to pluck.
       
  3678      * @returns {Array} Returns a new array of property values.
       
  3679      * @example
       
  3680      *
       
  3681      * var characters = [
       
  3682      *   { 'name': 'barney', 'age': 36 },
       
  3683      *   { 'name': 'fred',   'age': 40 }
       
  3684      * ];
       
  3685      *
       
  3686      * _.pluck(characters, 'name');
       
  3687      * // => ['barney', 'fred']
       
  3688      */
       
  3689     var pluck = map;
       
  3690 
       
  3691     /**
       
  3692      * Reduces a collection to a value which is the accumulated result of running
       
  3693      * each element in the collection through the callback, where each successive
       
  3694      * callback execution consumes the return value of the previous execution. If
       
  3695      * `accumulator` is not provided the first element of the collection will be
       
  3696      * used as the initial `accumulator` value. The callback is bound to `thisArg`
       
  3697      * and invoked with four arguments; (accumulator, value, index|key, collection).
       
  3698      *
       
  3699      * @static
       
  3700      * @memberOf _
       
  3701      * @alias foldl, inject
       
  3702      * @category Collections
       
  3703      * @param {Array|Object|string} collection The collection to iterate over.
       
  3704      * @param {Function} [callback=identity] The function called per iteration.
       
  3705      * @param {*} [accumulator] Initial value of the accumulator.
       
  3706      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3707      * @returns {*} Returns the accumulated value.
       
  3708      * @example
       
  3709      *
       
  3710      * var sum = _.reduce([1, 2, 3], function(sum, num) {
       
  3711      *   return sum + num;
       
  3712      * });
       
  3713      * // => 6
       
  3714      *
       
  3715      * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
       
  3716      *   result[key] = num * 3;
       
  3717      *   return result;
       
  3718      * }, {});
       
  3719      * // => { 'a': 3, 'b': 6, 'c': 9 }
       
  3720      */
       
  3721     function reduce(collection, callback, accumulator, thisArg) {
       
  3722       if (!collection) return accumulator;
       
  3723       var noaccum = arguments.length < 3;
       
  3724       callback = lodash.createCallback(callback, thisArg, 4);
       
  3725 
       
  3726       var index = -1,
       
  3727           length = collection.length;
       
  3728 
       
  3729       if (typeof length == 'number') {
       
  3730         if (noaccum) {
       
  3731           accumulator = collection[++index];
       
  3732         }
       
  3733         while (++index < length) {
       
  3734           accumulator = callback(accumulator, collection[index], index, collection);
       
  3735         }
       
  3736       } else {
       
  3737         forOwn(collection, function(value, index, collection) {
       
  3738           accumulator = noaccum
       
  3739             ? (noaccum = false, value)
       
  3740             : callback(accumulator, value, index, collection)
       
  3741         });
       
  3742       }
       
  3743       return accumulator;
       
  3744     }
       
  3745 
       
  3746     /**
       
  3747      * This method is like `_.reduce` except that it iterates over elements
       
  3748      * of a `collection` from right to left.
       
  3749      *
       
  3750      * @static
       
  3751      * @memberOf _
       
  3752      * @alias foldr
       
  3753      * @category Collections
       
  3754      * @param {Array|Object|string} collection The collection to iterate over.
       
  3755      * @param {Function} [callback=identity] The function called per iteration.
       
  3756      * @param {*} [accumulator] Initial value of the accumulator.
       
  3757      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3758      * @returns {*} Returns the accumulated value.
       
  3759      * @example
       
  3760      *
       
  3761      * var list = [[0, 1], [2, 3], [4, 5]];
       
  3762      * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
       
  3763      * // => [4, 5, 2, 3, 0, 1]
       
  3764      */
       
  3765     function reduceRight(collection, callback, accumulator, thisArg) {
       
  3766       var noaccum = arguments.length < 3;
       
  3767       callback = lodash.createCallback(callback, thisArg, 4);
       
  3768       forEachRight(collection, function(value, index, collection) {
       
  3769         accumulator = noaccum
       
  3770           ? (noaccum = false, value)
       
  3771           : callback(accumulator, value, index, collection);
       
  3772       });
       
  3773       return accumulator;
       
  3774     }
       
  3775 
       
  3776     /**
       
  3777      * The opposite of `_.filter` this method returns the elements of a
       
  3778      * collection that the callback does **not** return truey for.
       
  3779      *
       
  3780      * If a property name is provided for `callback` the created "_.pluck" style
       
  3781      * callback will return the property value of the given element.
       
  3782      *
       
  3783      * If an object is provided for `callback` the created "_.where" style callback
       
  3784      * will return `true` for elements that have the properties of the given object,
       
  3785      * else `false`.
       
  3786      *
       
  3787      * @static
       
  3788      * @memberOf _
       
  3789      * @category Collections
       
  3790      * @param {Array|Object|string} collection The collection to iterate over.
       
  3791      * @param {Function|Object|string} [callback=identity] The function called
       
  3792      *  per iteration. If a property name or object is provided it will be used
       
  3793      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3794      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3795      * @returns {Array} Returns a new array of elements that failed the callback check.
       
  3796      * @example
       
  3797      *
       
  3798      * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
       
  3799      * // => [1, 3, 5]
       
  3800      *
       
  3801      * var characters = [
       
  3802      *   { 'name': 'barney', 'age': 36, 'blocked': false },
       
  3803      *   { 'name': 'fred',   'age': 40, 'blocked': true }
       
  3804      * ];
       
  3805      *
       
  3806      * // using "_.pluck" callback shorthand
       
  3807      * _.reject(characters, 'blocked');
       
  3808      * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
       
  3809      *
       
  3810      * // using "_.where" callback shorthand
       
  3811      * _.reject(characters, { 'age': 36 });
       
  3812      * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
       
  3813      */
       
  3814     function reject(collection, callback, thisArg) {
       
  3815       callback = lodash.createCallback(callback, thisArg, 3);
       
  3816       return filter(collection, function(value, index, collection) {
       
  3817         return !callback(value, index, collection);
       
  3818       });
       
  3819     }
       
  3820 
       
  3821     /**
       
  3822      * Retrieves a random element or `n` random elements from a collection.
       
  3823      *
       
  3824      * @static
       
  3825      * @memberOf _
       
  3826      * @category Collections
       
  3827      * @param {Array|Object|string} collection The collection to sample.
       
  3828      * @param {number} [n] The number of elements to sample.
       
  3829      * @param- {Object} [guard] Allows working with functions like `_.map`
       
  3830      *  without using their `index` arguments as `n`.
       
  3831      * @returns {Array} Returns the random sample(s) of `collection`.
       
  3832      * @example
       
  3833      *
       
  3834      * _.sample([1, 2, 3, 4]);
       
  3835      * // => 2
       
  3836      *
       
  3837      * _.sample([1, 2, 3, 4], 2);
       
  3838      * // => [3, 1]
       
  3839      */
       
  3840     function sample(collection, n, guard) {
       
  3841       if (collection && typeof collection.length != 'number') {
       
  3842         collection = values(collection);
       
  3843       }
       
  3844       if (n == null || guard) {
       
  3845         return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
       
  3846       }
       
  3847       var result = shuffle(collection);
       
  3848       result.length = nativeMin(nativeMax(0, n), result.length);
       
  3849       return result;
       
  3850     }
       
  3851 
       
  3852     /**
       
  3853      * Creates an array of shuffled values, using a version of the Fisher-Yates
       
  3854      * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
       
  3855      *
       
  3856      * @static
       
  3857      * @memberOf _
       
  3858      * @category Collections
       
  3859      * @param {Array|Object|string} collection The collection to shuffle.
       
  3860      * @returns {Array} Returns a new shuffled collection.
       
  3861      * @example
       
  3862      *
       
  3863      * _.shuffle([1, 2, 3, 4, 5, 6]);
       
  3864      * // => [4, 1, 6, 3, 5, 2]
       
  3865      */
       
  3866     function shuffle(collection) {
       
  3867       var index = -1,
       
  3868           length = collection ? collection.length : 0,
       
  3869           result = Array(typeof length == 'number' ? length : 0);
       
  3870 
       
  3871       forEach(collection, function(value) {
       
  3872         var rand = baseRandom(0, ++index);
       
  3873         result[index] = result[rand];
       
  3874         result[rand] = value;
       
  3875       });
       
  3876       return result;
       
  3877     }
       
  3878 
       
  3879     /**
       
  3880      * Gets the size of the `collection` by returning `collection.length` for arrays
       
  3881      * and array-like objects or the number of own enumerable properties for objects.
       
  3882      *
       
  3883      * @static
       
  3884      * @memberOf _
       
  3885      * @category Collections
       
  3886      * @param {Array|Object|string} collection The collection to inspect.
       
  3887      * @returns {number} Returns `collection.length` or number of own enumerable properties.
       
  3888      * @example
       
  3889      *
       
  3890      * _.size([1, 2]);
       
  3891      * // => 2
       
  3892      *
       
  3893      * _.size({ 'one': 1, 'two': 2, 'three': 3 });
       
  3894      * // => 3
       
  3895      *
       
  3896      * _.size('pebbles');
       
  3897      * // => 7
       
  3898      */
       
  3899     function size(collection) {
       
  3900       var length = collection ? collection.length : 0;
       
  3901       return typeof length == 'number' ? length : keys(collection).length;
       
  3902     }
       
  3903 
       
  3904     /**
       
  3905      * Checks if the callback returns a truey value for **any** element of a
       
  3906      * collection. The function returns as soon as it finds a passing value and
       
  3907      * does not iterate over the entire collection. The callback is bound to
       
  3908      * `thisArg` and invoked with three arguments; (value, index|key, collection).
       
  3909      *
       
  3910      * If a property name is provided for `callback` the created "_.pluck" style
       
  3911      * callback will return the property value of the given element.
       
  3912      *
       
  3913      * If an object is provided for `callback` the created "_.where" style callback
       
  3914      * will return `true` for elements that have the properties of the given object,
       
  3915      * else `false`.
       
  3916      *
       
  3917      * @static
       
  3918      * @memberOf _
       
  3919      * @alias any
       
  3920      * @category Collections
       
  3921      * @param {Array|Object|string} collection The collection to iterate over.
       
  3922      * @param {Function|Object|string} [callback=identity] The function called
       
  3923      *  per iteration. If a property name or object is provided it will be used
       
  3924      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3925      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3926      * @returns {boolean} Returns `true` if any element passed the callback check,
       
  3927      *  else `false`.
       
  3928      * @example
       
  3929      *
       
  3930      * _.some([null, 0, 'yes', false], Boolean);
       
  3931      * // => true
       
  3932      *
       
  3933      * var characters = [
       
  3934      *   { 'name': 'barney', 'age': 36, 'blocked': false },
       
  3935      *   { 'name': 'fred',   'age': 40, 'blocked': true }
       
  3936      * ];
       
  3937      *
       
  3938      * // using "_.pluck" callback shorthand
       
  3939      * _.some(characters, 'blocked');
       
  3940      * // => true
       
  3941      *
       
  3942      * // using "_.where" callback shorthand
       
  3943      * _.some(characters, { 'age': 1 });
       
  3944      * // => false
       
  3945      */
       
  3946     function some(collection, callback, thisArg) {
       
  3947       var result;
       
  3948       callback = lodash.createCallback(callback, thisArg, 3);
       
  3949 
       
  3950       var index = -1,
       
  3951           length = collection ? collection.length : 0;
       
  3952 
       
  3953       if (typeof length == 'number') {
       
  3954         while (++index < length) {
       
  3955           if ((result = callback(collection[index], index, collection))) {
       
  3956             break;
       
  3957           }
       
  3958         }
       
  3959       } else {
       
  3960         forOwn(collection, function(value, index, collection) {
       
  3961           return !(result = callback(value, index, collection));
       
  3962         });
       
  3963       }
       
  3964       return !!result;
       
  3965     }
       
  3966 
       
  3967     /**
       
  3968      * Creates an array of elements, sorted in ascending order by the results of
       
  3969      * running each element in a collection through the callback. This method
       
  3970      * performs a stable sort, that is, it will preserve the original sort order
       
  3971      * of equal elements. The callback is bound to `thisArg` and invoked with
       
  3972      * three arguments; (value, index|key, collection).
       
  3973      *
       
  3974      * If a property name is provided for `callback` the created "_.pluck" style
       
  3975      * callback will return the property value of the given element.
       
  3976      *
       
  3977      * If an array of property names is provided for `callback` the collection
       
  3978      * will be sorted by each property value.
       
  3979      *
       
  3980      * If an object is provided for `callback` the created "_.where" style callback
       
  3981      * will return `true` for elements that have the properties of the given object,
       
  3982      * else `false`.
       
  3983      *
       
  3984      * @static
       
  3985      * @memberOf _
       
  3986      * @category Collections
       
  3987      * @param {Array|Object|string} collection The collection to iterate over.
       
  3988      * @param {Array|Function|Object|string} [callback=identity] The function called
       
  3989      *  per iteration. If a property name or object is provided it will be used
       
  3990      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  3991      * @param {*} [thisArg] The `this` binding of `callback`.
       
  3992      * @returns {Array} Returns a new array of sorted elements.
       
  3993      * @example
       
  3994      *
       
  3995      * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
       
  3996      * // => [3, 1, 2]
       
  3997      *
       
  3998      * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
       
  3999      * // => [3, 1, 2]
       
  4000      *
       
  4001      * var characters = [
       
  4002      *   { 'name': 'barney',  'age': 36 },
       
  4003      *   { 'name': 'fred',    'age': 40 },
       
  4004      *   { 'name': 'barney',  'age': 26 },
       
  4005      *   { 'name': 'fred',    'age': 30 }
       
  4006      * ];
       
  4007      *
       
  4008      * // using "_.pluck" callback shorthand
       
  4009      * _.map(_.sortBy(characters, 'age'), _.values);
       
  4010      * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
       
  4011      *
       
  4012      * // sorting by multiple properties
       
  4013      * _.map(_.sortBy(characters, ['name', 'age']), _.values);
       
  4014      * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
       
  4015      */
       
  4016     function sortBy(collection, callback, thisArg) {
       
  4017       var index = -1,
       
  4018           isArr = isArray(callback),
       
  4019           length = collection ? collection.length : 0,
       
  4020           result = Array(typeof length == 'number' ? length : 0);
       
  4021 
       
  4022       if (!isArr) {
       
  4023         callback = lodash.createCallback(callback, thisArg, 3);
       
  4024       }
       
  4025       forEach(collection, function(value, key, collection) {
       
  4026         var object = result[++index] = getObject();
       
  4027         if (isArr) {
       
  4028           object.criteria = map(callback, function(key) { return value[key]; });
       
  4029         } else {
       
  4030           (object.criteria = getArray())[0] = callback(value, key, collection);
       
  4031         }
       
  4032         object.index = index;
       
  4033         object.value = value;
       
  4034       });
       
  4035 
       
  4036       length = result.length;
       
  4037       result.sort(compareAscending);
       
  4038       while (length--) {
       
  4039         var object = result[length];
       
  4040         result[length] = object.value;
       
  4041         if (!isArr) {
       
  4042           releaseArray(object.criteria);
       
  4043         }
       
  4044         releaseObject(object);
       
  4045       }
       
  4046       return result;
       
  4047     }
       
  4048 
       
  4049     /**
       
  4050      * Converts the `collection` to an array.
       
  4051      *
       
  4052      * @static
       
  4053      * @memberOf _
       
  4054      * @category Collections
       
  4055      * @param {Array|Object|string} collection The collection to convert.
       
  4056      * @returns {Array} Returns the new converted array.
       
  4057      * @example
       
  4058      *
       
  4059      * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
       
  4060      * // => [2, 3, 4]
       
  4061      */
       
  4062     function toArray(collection) {
       
  4063       if (collection && typeof collection.length == 'number') {
       
  4064         return slice(collection);
       
  4065       }
       
  4066       return values(collection);
       
  4067     }
       
  4068 
       
  4069     /**
       
  4070      * Performs a deep comparison of each element in a `collection` to the given
       
  4071      * `properties` object, returning an array of all elements that have equivalent
       
  4072      * property values.
       
  4073      *
       
  4074      * @static
       
  4075      * @memberOf _
       
  4076      * @type Function
       
  4077      * @category Collections
       
  4078      * @param {Array|Object|string} collection The collection to iterate over.
       
  4079      * @param {Object} props The object of property values to filter by.
       
  4080      * @returns {Array} Returns a new array of elements that have the given properties.
       
  4081      * @example
       
  4082      *
       
  4083      * var characters = [
       
  4084      *   { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
       
  4085      *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
       
  4086      * ];
       
  4087      *
       
  4088      * _.where(characters, { 'age': 36 });
       
  4089      * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
       
  4090      *
       
  4091      * _.where(characters, { 'pets': ['dino'] });
       
  4092      * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
       
  4093      */
       
  4094     var where = filter;
       
  4095 
       
  4096     /*--------------------------------------------------------------------------*/
       
  4097 
       
  4098     /**
       
  4099      * Creates an array with all falsey values removed. The values `false`, `null`,
       
  4100      * `0`, `""`, `undefined`, and `NaN` are all falsey.
       
  4101      *
       
  4102      * @static
       
  4103      * @memberOf _
       
  4104      * @category Arrays
       
  4105      * @param {Array} array The array to compact.
       
  4106      * @returns {Array} Returns a new array of filtered values.
       
  4107      * @example
       
  4108      *
       
  4109      * _.compact([0, 1, false, 2, '', 3]);
       
  4110      * // => [1, 2, 3]
       
  4111      */
       
  4112     function compact(array) {
       
  4113       var index = -1,
       
  4114           length = array ? array.length : 0,
       
  4115           result = [];
       
  4116 
       
  4117       while (++index < length) {
       
  4118         var value = array[index];
       
  4119         if (value) {
       
  4120           result.push(value);
       
  4121         }
       
  4122       }
       
  4123       return result;
       
  4124     }
       
  4125 
       
  4126     /**
       
  4127      * Creates an array excluding all values of the provided arrays using strict
       
  4128      * equality for comparisons, i.e. `===`.
       
  4129      *
       
  4130      * @static
       
  4131      * @memberOf _
       
  4132      * @category Arrays
       
  4133      * @param {Array} array The array to process.
       
  4134      * @param {...Array} [values] The arrays of values to exclude.
       
  4135      * @returns {Array} Returns a new array of filtered values.
       
  4136      * @example
       
  4137      *
       
  4138      * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
       
  4139      * // => [1, 3, 4]
       
  4140      */
       
  4141     function difference(array) {
       
  4142       return baseDifference(array, baseFlatten(arguments, true, true, 1));
       
  4143     }
       
  4144 
       
  4145     /**
       
  4146      * This method is like `_.find` except that it returns the index of the first
       
  4147      * element that passes the callback check, instead of the element itself.
       
  4148      *
       
  4149      * If a property name is provided for `callback` the created "_.pluck" style
       
  4150      * callback will return the property value of the given element.
       
  4151      *
       
  4152      * If an object is provided for `callback` the created "_.where" style callback
       
  4153      * will return `true` for elements that have the properties of the given object,
       
  4154      * else `false`.
       
  4155      *
       
  4156      * @static
       
  4157      * @memberOf _
       
  4158      * @category Arrays
       
  4159      * @param {Array} array The array to search.
       
  4160      * @param {Function|Object|string} [callback=identity] The function called
       
  4161      *  per iteration. If a property name or object is provided it will be used
       
  4162      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  4163      * @param {*} [thisArg] The `this` binding of `callback`.
       
  4164      * @returns {number} Returns the index of the found element, else `-1`.
       
  4165      * @example
       
  4166      *
       
  4167      * var characters = [
       
  4168      *   { 'name': 'barney',  'age': 36, 'blocked': false },
       
  4169      *   { 'name': 'fred',    'age': 40, 'blocked': true },
       
  4170      *   { 'name': 'pebbles', 'age': 1,  'blocked': false }
       
  4171      * ];
       
  4172      *
       
  4173      * _.findIndex(characters, function(chr) {
       
  4174      *   return chr.age < 20;
       
  4175      * });
       
  4176      * // => 2
       
  4177      *
       
  4178      * // using "_.where" callback shorthand
       
  4179      * _.findIndex(characters, { 'age': 36 });
       
  4180      * // => 0
       
  4181      *
       
  4182      * // using "_.pluck" callback shorthand
       
  4183      * _.findIndex(characters, 'blocked');
       
  4184      * // => 1
       
  4185      */
       
  4186     function findIndex(array, callback, thisArg) {
       
  4187       var index = -1,
       
  4188           length = array ? array.length : 0;
       
  4189 
       
  4190       callback = lodash.createCallback(callback, thisArg, 3);
       
  4191       while (++index < length) {
       
  4192         if (callback(array[index], index, array)) {
       
  4193           return index;
       
  4194         }
       
  4195       }
       
  4196       return -1;
       
  4197     }
       
  4198 
       
  4199     /**
       
  4200      * This method is like `_.findIndex` except that it iterates over elements
       
  4201      * of a `collection` from right to left.
       
  4202      *
       
  4203      * If a property name is provided for `callback` the created "_.pluck" style
       
  4204      * callback will return the property value of the given element.
       
  4205      *
       
  4206      * If an object is provided for `callback` the created "_.where" style callback
       
  4207      * will return `true` for elements that have the properties of the given object,
       
  4208      * else `false`.
       
  4209      *
       
  4210      * @static
       
  4211      * @memberOf _
       
  4212      * @category Arrays
       
  4213      * @param {Array} array The array to search.
       
  4214      * @param {Function|Object|string} [callback=identity] The function called
       
  4215      *  per iteration. If a property name or object is provided it will be used
       
  4216      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  4217      * @param {*} [thisArg] The `this` binding of `callback`.
       
  4218      * @returns {number} Returns the index of the found element, else `-1`.
       
  4219      * @example
       
  4220      *
       
  4221      * var characters = [
       
  4222      *   { 'name': 'barney',  'age': 36, 'blocked': true },
       
  4223      *   { 'name': 'fred',    'age': 40, 'blocked': false },
       
  4224      *   { 'name': 'pebbles', 'age': 1,  'blocked': true }
       
  4225      * ];
       
  4226      *
       
  4227      * _.findLastIndex(characters, function(chr) {
       
  4228      *   return chr.age > 30;
       
  4229      * });
       
  4230      * // => 1
       
  4231      *
       
  4232      * // using "_.where" callback shorthand
       
  4233      * _.findLastIndex(characters, { 'age': 36 });
       
  4234      * // => 0
       
  4235      *
       
  4236      * // using "_.pluck" callback shorthand
       
  4237      * _.findLastIndex(characters, 'blocked');
       
  4238      * // => 2
       
  4239      */
       
  4240     function findLastIndex(array, callback, thisArg) {
       
  4241       var length = array ? array.length : 0;
       
  4242       callback = lodash.createCallback(callback, thisArg, 3);
       
  4243       while (length--) {
       
  4244         if (callback(array[length], length, array)) {
       
  4245           return length;
       
  4246         }
       
  4247       }
       
  4248       return -1;
       
  4249     }
       
  4250 
       
  4251     /**
       
  4252      * Gets the first element or first `n` elements of an array. If a callback
       
  4253      * is provided elements at the beginning of the array are returned as long
       
  4254      * as the callback returns truey. The callback is bound to `thisArg` and
       
  4255      * invoked with three arguments; (value, index, array).
       
  4256      *
       
  4257      * If a property name is provided for `callback` the created "_.pluck" style
       
  4258      * callback will return the property value of the given element.
       
  4259      *
       
  4260      * If an object is provided for `callback` the created "_.where" style callback
       
  4261      * will return `true` for elements that have the properties of the given object,
       
  4262      * else `false`.
       
  4263      *
       
  4264      * @static
       
  4265      * @memberOf _
       
  4266      * @alias head, take
       
  4267      * @category Arrays
       
  4268      * @param {Array} array The array to query.
       
  4269      * @param {Function|Object|number|string} [callback] The function called
       
  4270      *  per element or the number of elements to return. If a property name or
       
  4271      *  object is provided it will be used to create a "_.pluck" or "_.where"
       
  4272      *  style callback, respectively.
       
  4273      * @param {*} [thisArg] The `this` binding of `callback`.
       
  4274      * @returns {*} Returns the first element(s) of `array`.
       
  4275      * @example
       
  4276      *
       
  4277      * _.first([1, 2, 3]);
       
  4278      * // => 1
       
  4279      *
       
  4280      * _.first([1, 2, 3], 2);
       
  4281      * // => [1, 2]
       
  4282      *
       
  4283      * _.first([1, 2, 3], function(num) {
       
  4284      *   return num < 3;
       
  4285      * });
       
  4286      * // => [1, 2]
       
  4287      *
       
  4288      * var characters = [
       
  4289      *   { 'name': 'barney',  'blocked': true,  'employer': 'slate' },
       
  4290      *   { 'name': 'fred',    'blocked': false, 'employer': 'slate' },
       
  4291      *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
       
  4292      * ];
       
  4293      *
       
  4294      * // using "_.pluck" callback shorthand
       
  4295      * _.first(characters, 'blocked');
       
  4296      * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
       
  4297      *
       
  4298      * // using "_.where" callback shorthand
       
  4299      * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
       
  4300      * // => ['barney', 'fred']
       
  4301      */
       
  4302     function first(array, callback, thisArg) {
       
  4303       var n = 0,
       
  4304           length = array ? array.length : 0;
       
  4305 
       
  4306       if (typeof callback != 'number' && callback != null) {
       
  4307         var index = -1;
       
  4308         callback = lodash.createCallback(callback, thisArg, 3);
       
  4309         while (++index < length && callback(array[index], index, array)) {
       
  4310           n++;
       
  4311         }
       
  4312       } else {
       
  4313         n = callback;
       
  4314         if (n == null || thisArg) {
       
  4315           return array ? array[0] : undefined;
       
  4316         }
       
  4317       }
       
  4318       return slice(array, 0, nativeMin(nativeMax(0, n), length));
       
  4319     }
       
  4320 
       
  4321     /**
       
  4322      * Flattens a nested array (the nesting can be to any depth). If `isShallow`
       
  4323      * is truey, the array will only be flattened a single level. If a callback
       
  4324      * is provided each element of the array is passed through the callback before
       
  4325      * flattening. The callback is bound to `thisArg` and invoked with three
       
  4326      * arguments; (value, index, array).
       
  4327      *
       
  4328      * If a property name is provided for `callback` the created "_.pluck" style
       
  4329      * callback will return the property value of the given element.
       
  4330      *
       
  4331      * If an object is provided for `callback` the created "_.where" style callback
       
  4332      * will return `true` for elements that have the properties of the given object,
       
  4333      * else `false`.
       
  4334      *
       
  4335      * @static
       
  4336      * @memberOf _
       
  4337      * @category Arrays
       
  4338      * @param {Array} array The array to flatten.
       
  4339      * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
       
  4340      * @param {Function|Object|string} [callback=identity] The function called
       
  4341      *  per iteration. If a property name or object is provided it will be used
       
  4342      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  4343      * @param {*} [thisArg] The `this` binding of `callback`.
       
  4344      * @returns {Array} Returns a new flattened array.
       
  4345      * @example
       
  4346      *
       
  4347      * _.flatten([1, [2], [3, [[4]]]]);
       
  4348      * // => [1, 2, 3, 4];
       
  4349      *
       
  4350      * _.flatten([1, [2], [3, [[4]]]], true);
       
  4351      * // => [1, 2, 3, [[4]]];
       
  4352      *
       
  4353      * var characters = [
       
  4354      *   { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
       
  4355      *   { 'name': 'fred',   'age': 40, 'pets': ['baby puss', 'dino'] }
       
  4356      * ];
       
  4357      *
       
  4358      * // using "_.pluck" callback shorthand
       
  4359      * _.flatten(characters, 'pets');
       
  4360      * // => ['hoppy', 'baby puss', 'dino']
       
  4361      */
       
  4362     function flatten(array, isShallow, callback, thisArg) {
       
  4363       // juggle arguments
       
  4364       if (typeof isShallow != 'boolean' && isShallow != null) {
       
  4365         thisArg = callback;
       
  4366         callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
       
  4367         isShallow = false;
       
  4368       }
       
  4369       if (callback != null) {
       
  4370         array = map(array, callback, thisArg);
       
  4371       }
       
  4372       return baseFlatten(array, isShallow);
       
  4373     }
       
  4374 
       
  4375     /**
       
  4376      * Gets the index at which the first occurrence of `value` is found using
       
  4377      * strict equality for comparisons, i.e. `===`. If the array is already sorted
       
  4378      * providing `true` for `fromIndex` will run a faster binary search.
       
  4379      *
       
  4380      * @static
       
  4381      * @memberOf _
       
  4382      * @category Arrays
       
  4383      * @param {Array} array The array to search.
       
  4384      * @param {*} value The value to search for.
       
  4385      * @param {boolean|number} [fromIndex=0] The index to search from or `true`
       
  4386      *  to perform a binary search on a sorted array.
       
  4387      * @returns {number} Returns the index of the matched value or `-1`.
       
  4388      * @example
       
  4389      *
       
  4390      * _.indexOf([1, 2, 3, 1, 2, 3], 2);
       
  4391      * // => 1
       
  4392      *
       
  4393      * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
       
  4394      * // => 4
       
  4395      *
       
  4396      * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
       
  4397      * // => 2
       
  4398      */
       
  4399     function indexOf(array, value, fromIndex) {
       
  4400       if (typeof fromIndex == 'number') {
       
  4401         var length = array ? array.length : 0;
       
  4402         fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
       
  4403       } else if (fromIndex) {
       
  4404         var index = sortedIndex(array, value);
       
  4405         return array[index] === value ? index : -1;
       
  4406       }
       
  4407       return baseIndexOf(array, value, fromIndex);
       
  4408     }
       
  4409 
       
  4410     /**
       
  4411      * Gets all but the last element or last `n` elements of an array. If a
       
  4412      * callback is provided elements at the end of the array are excluded from
       
  4413      * the result as long as the callback returns truey. The callback is bound
       
  4414      * to `thisArg` and invoked with three arguments; (value, index, array).
       
  4415      *
       
  4416      * If a property name is provided for `callback` the created "_.pluck" style
       
  4417      * callback will return the property value of the given element.
       
  4418      *
       
  4419      * If an object is provided for `callback` the created "_.where" style callback
       
  4420      * will return `true` for elements that have the properties of the given object,
       
  4421      * else `false`.
       
  4422      *
       
  4423      * @static
       
  4424      * @memberOf _
       
  4425      * @category Arrays
       
  4426      * @param {Array} array The array to query.
       
  4427      * @param {Function|Object|number|string} [callback=1] The function called
       
  4428      *  per element or the number of elements to exclude. If a property name or
       
  4429      *  object is provided it will be used to create a "_.pluck" or "_.where"
       
  4430      *  style callback, respectively.
       
  4431      * @param {*} [thisArg] The `this` binding of `callback`.
       
  4432      * @returns {Array} Returns a slice of `array`.
       
  4433      * @example
       
  4434      *
       
  4435      * _.initial([1, 2, 3]);
       
  4436      * // => [1, 2]
       
  4437      *
       
  4438      * _.initial([1, 2, 3], 2);
       
  4439      * // => [1]
       
  4440      *
       
  4441      * _.initial([1, 2, 3], function(num) {
       
  4442      *   return num > 1;
       
  4443      * });
       
  4444      * // => [1]
       
  4445      *
       
  4446      * var characters = [
       
  4447      *   { 'name': 'barney',  'blocked': false, 'employer': 'slate' },
       
  4448      *   { 'name': 'fred',    'blocked': true,  'employer': 'slate' },
       
  4449      *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
       
  4450      * ];
       
  4451      *
       
  4452      * // using "_.pluck" callback shorthand
       
  4453      * _.initial(characters, 'blocked');
       
  4454      * // => [{ 'name': 'barney',  'blocked': false, 'employer': 'slate' }]
       
  4455      *
       
  4456      * // using "_.where" callback shorthand
       
  4457      * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
       
  4458      * // => ['barney', 'fred']
       
  4459      */
       
  4460     function initial(array, callback, thisArg) {
       
  4461       var n = 0,
       
  4462           length = array ? array.length : 0;
       
  4463 
       
  4464       if (typeof callback != 'number' && callback != null) {
       
  4465         var index = length;
       
  4466         callback = lodash.createCallback(callback, thisArg, 3);
       
  4467         while (index-- && callback(array[index], index, array)) {
       
  4468           n++;
       
  4469         }
       
  4470       } else {
       
  4471         n = (callback == null || thisArg) ? 1 : callback || n;
       
  4472       }
       
  4473       return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
       
  4474     }
       
  4475 
       
  4476     /**
       
  4477      * Creates an array of unique values present in all provided arrays using
       
  4478      * strict equality for comparisons, i.e. `===`.
       
  4479      *
       
  4480      * @static
       
  4481      * @memberOf _
       
  4482      * @category Arrays
       
  4483      * @param {...Array} [array] The arrays to inspect.
       
  4484      * @returns {Array} Returns an array of shared values.
       
  4485      * @example
       
  4486      *
       
  4487      * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
       
  4488      * // => [1, 2]
       
  4489      */
       
  4490     function intersection() {
       
  4491       var args = [],
       
  4492           argsIndex = -1,
       
  4493           argsLength = arguments.length,
       
  4494           caches = getArray(),
       
  4495           indexOf = getIndexOf(),
       
  4496           trustIndexOf = indexOf === baseIndexOf,
       
  4497           seen = getArray();
       
  4498 
       
  4499       while (++argsIndex < argsLength) {
       
  4500         var value = arguments[argsIndex];
       
  4501         if (isArray(value) || isArguments(value)) {
       
  4502           args.push(value);
       
  4503           caches.push(trustIndexOf && value.length >= largeArraySize &&
       
  4504             createCache(argsIndex ? args[argsIndex] : seen));
       
  4505         }
       
  4506       }
       
  4507       var array = args[0],
       
  4508           index = -1,
       
  4509           length = array ? array.length : 0,
       
  4510           result = [];
       
  4511 
       
  4512       outer:
       
  4513       while (++index < length) {
       
  4514         var cache = caches[0];
       
  4515         value = array[index];
       
  4516 
       
  4517         if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
       
  4518           argsIndex = argsLength;
       
  4519           (cache || seen).push(value);
       
  4520           while (--argsIndex) {
       
  4521             cache = caches[argsIndex];
       
  4522             if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
       
  4523               continue outer;
       
  4524             }
       
  4525           }
       
  4526           result.push(value);
       
  4527         }
       
  4528       }
       
  4529       while (argsLength--) {
       
  4530         cache = caches[argsLength];
       
  4531         if (cache) {
       
  4532           releaseObject(cache);
       
  4533         }
       
  4534       }
       
  4535       releaseArray(caches);
       
  4536       releaseArray(seen);
       
  4537       return result;
       
  4538     }
       
  4539 
       
  4540     /**
       
  4541      * Gets the last element or last `n` elements of an array. If a callback is
       
  4542      * provided elements at the end of the array are returned as long as the
       
  4543      * callback returns truey. The callback is bound to `thisArg` and invoked
       
  4544      * with three arguments; (value, index, array).
       
  4545      *
       
  4546      * If a property name is provided for `callback` the created "_.pluck" style
       
  4547      * callback will return the property value of the given element.
       
  4548      *
       
  4549      * If an object is provided for `callback` the created "_.where" style callback
       
  4550      * will return `true` for elements that have the properties of the given object,
       
  4551      * else `false`.
       
  4552      *
       
  4553      * @static
       
  4554      * @memberOf _
       
  4555      * @category Arrays
       
  4556      * @param {Array} array The array to query.
       
  4557      * @param {Function|Object|number|string} [callback] The function called
       
  4558      *  per element or the number of elements to return. If a property name or
       
  4559      *  object is provided it will be used to create a "_.pluck" or "_.where"
       
  4560      *  style callback, respectively.
       
  4561      * @param {*} [thisArg] The `this` binding of `callback`.
       
  4562      * @returns {*} Returns the last element(s) of `array`.
       
  4563      * @example
       
  4564      *
       
  4565      * _.last([1, 2, 3]);
       
  4566      * // => 3
       
  4567      *
       
  4568      * _.last([1, 2, 3], 2);
       
  4569      * // => [2, 3]
       
  4570      *
       
  4571      * _.last([1, 2, 3], function(num) {
       
  4572      *   return num > 1;
       
  4573      * });
       
  4574      * // => [2, 3]
       
  4575      *
       
  4576      * var characters = [
       
  4577      *   { 'name': 'barney',  'blocked': false, 'employer': 'slate' },
       
  4578      *   { 'name': 'fred',    'blocked': true,  'employer': 'slate' },
       
  4579      *   { 'name': 'pebbles', 'blocked': true,  'employer': 'na' }
       
  4580      * ];
       
  4581      *
       
  4582      * // using "_.pluck" callback shorthand
       
  4583      * _.pluck(_.last(characters, 'blocked'), 'name');
       
  4584      * // => ['fred', 'pebbles']
       
  4585      *
       
  4586      * // using "_.where" callback shorthand
       
  4587      * _.last(characters, { 'employer': 'na' });
       
  4588      * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
       
  4589      */
       
  4590     function last(array, callback, thisArg) {
       
  4591       var n = 0,
       
  4592           length = array ? array.length : 0;
       
  4593 
       
  4594       if (typeof callback != 'number' && callback != null) {
       
  4595         var index = length;
       
  4596         callback = lodash.createCallback(callback, thisArg, 3);
       
  4597         while (index-- && callback(array[index], index, array)) {
       
  4598           n++;
       
  4599         }
       
  4600       } else {
       
  4601         n = callback;
       
  4602         if (n == null || thisArg) {
       
  4603           return array ? array[length - 1] : undefined;
       
  4604         }
       
  4605       }
       
  4606       return slice(array, nativeMax(0, length - n));
       
  4607     }
       
  4608 
       
  4609     /**
       
  4610      * Gets the index at which the last occurrence of `value` is found using strict
       
  4611      * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
       
  4612      * as the offset from the end of the collection.
       
  4613      *
       
  4614      * If a property name is provided for `callback` the created "_.pluck" style
       
  4615      * callback will return the property value of the given element.
       
  4616      *
       
  4617      * If an object is provided for `callback` the created "_.where" style callback
       
  4618      * will return `true` for elements that have the properties of the given object,
       
  4619      * else `false`.
       
  4620      *
       
  4621      * @static
       
  4622      * @memberOf _
       
  4623      * @category Arrays
       
  4624      * @param {Array} array The array to search.
       
  4625      * @param {*} value The value to search for.
       
  4626      * @param {number} [fromIndex=array.length-1] The index to search from.
       
  4627      * @returns {number} Returns the index of the matched value or `-1`.
       
  4628      * @example
       
  4629      *
       
  4630      * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
       
  4631      * // => 4
       
  4632      *
       
  4633      * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
       
  4634      * // => 1
       
  4635      */
       
  4636     function lastIndexOf(array, value, fromIndex) {
       
  4637       var index = array ? array.length : 0;
       
  4638       if (typeof fromIndex == 'number') {
       
  4639         index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
       
  4640       }
       
  4641       while (index--) {
       
  4642         if (array[index] === value) {
       
  4643           return index;
       
  4644         }
       
  4645       }
       
  4646       return -1;
       
  4647     }
       
  4648 
       
  4649     /**
       
  4650      * Removes all provided values from the given array using strict equality for
       
  4651      * comparisons, i.e. `===`.
       
  4652      *
       
  4653      * @static
       
  4654      * @memberOf _
       
  4655      * @category Arrays
       
  4656      * @param {Array} array The array to modify.
       
  4657      * @param {...*} [value] The values to remove.
       
  4658      * @returns {Array} Returns `array`.
       
  4659      * @example
       
  4660      *
       
  4661      * var array = [1, 2, 3, 1, 2, 3];
       
  4662      * _.pull(array, 2, 3);
       
  4663      * console.log(array);
       
  4664      * // => [1, 1]
       
  4665      */
       
  4666     function pull(array) {
       
  4667       var args = arguments,
       
  4668           argsIndex = 0,
       
  4669           argsLength = args.length,
       
  4670           length = array ? array.length : 0;
       
  4671 
       
  4672       while (++argsIndex < argsLength) {
       
  4673         var index = -1,
       
  4674             value = args[argsIndex];
       
  4675         while (++index < length) {
       
  4676           if (array[index] === value) {
       
  4677             splice.call(array, index--, 1);
       
  4678             length--;
       
  4679           }
       
  4680         }
       
  4681       }
       
  4682       return array;
       
  4683     }
       
  4684 
       
  4685     /**
       
  4686      * Creates an array of numbers (positive and/or negative) progressing from
       
  4687      * `start` up to but not including `end`. If `start` is less than `stop` a
       
  4688      * zero-length range is created unless a negative `step` is specified.
       
  4689      *
       
  4690      * @static
       
  4691      * @memberOf _
       
  4692      * @category Arrays
       
  4693      * @param {number} [start=0] The start of the range.
       
  4694      * @param {number} end The end of the range.
       
  4695      * @param {number} [step=1] The value to increment or decrement by.
       
  4696      * @returns {Array} Returns a new range array.
       
  4697      * @example
       
  4698      *
       
  4699      * _.range(4);
       
  4700      * // => [0, 1, 2, 3]
       
  4701      *
       
  4702      * _.range(1, 5);
       
  4703      * // => [1, 2, 3, 4]
       
  4704      *
       
  4705      * _.range(0, 20, 5);
       
  4706      * // => [0, 5, 10, 15]
       
  4707      *
       
  4708      * _.range(0, -4, -1);
       
  4709      * // => [0, -1, -2, -3]
       
  4710      *
       
  4711      * _.range(1, 4, 0);
       
  4712      * // => [1, 1, 1]
       
  4713      *
       
  4714      * _.range(0);
       
  4715      * // => []
       
  4716      */
       
  4717     function range(start, end, step) {
       
  4718       start = +start || 0;
       
  4719       step = typeof step == 'number' ? step : (+step || 1);
       
  4720 
       
  4721       if (end == null) {
       
  4722         end = start;
       
  4723         start = 0;
       
  4724       }
       
  4725       // use `Array(length)` so engines like Chakra and V8 avoid slower modes
       
  4726       // http://youtu.be/XAqIpGU8ZZk#t=17m25s
       
  4727       var index = -1,
       
  4728           length = nativeMax(0, ceil((end - start) / (step || 1))),
       
  4729           result = Array(length);
       
  4730 
       
  4731       while (++index < length) {
       
  4732         result[index] = start;
       
  4733         start += step;
       
  4734       }
       
  4735       return result;
       
  4736     }
       
  4737 
       
  4738     /**
       
  4739      * Removes all elements from an array that the callback returns truey for
       
  4740      * and returns an array of removed elements. The callback is bound to `thisArg`
       
  4741      * and invoked with three arguments; (value, index, array).
       
  4742      *
       
  4743      * If a property name is provided for `callback` the created "_.pluck" style
       
  4744      * callback will return the property value of the given element.
       
  4745      *
       
  4746      * If an object is provided for `callback` the created "_.where" style callback
       
  4747      * will return `true` for elements that have the properties of the given object,
       
  4748      * else `false`.
       
  4749      *
       
  4750      * @static
       
  4751      * @memberOf _
       
  4752      * @category Arrays
       
  4753      * @param {Array} array The array to modify.
       
  4754      * @param {Function|Object|string} [callback=identity] The function called
       
  4755      *  per iteration. If a property name or object is provided it will be used
       
  4756      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  4757      * @param {*} [thisArg] The `this` binding of `callback`.
       
  4758      * @returns {Array} Returns a new array of removed elements.
       
  4759      * @example
       
  4760      *
       
  4761      * var array = [1, 2, 3, 4, 5, 6];
       
  4762      * var evens = _.remove(array, function(num) { return num % 2 == 0; });
       
  4763      *
       
  4764      * console.log(array);
       
  4765      * // => [1, 3, 5]
       
  4766      *
       
  4767      * console.log(evens);
       
  4768      * // => [2, 4, 6]
       
  4769      */
       
  4770     function remove(array, callback, thisArg) {
       
  4771       var index = -1,
       
  4772           length = array ? array.length : 0,
       
  4773           result = [];
       
  4774 
       
  4775       callback = lodash.createCallback(callback, thisArg, 3);
       
  4776       while (++index < length) {
       
  4777         var value = array[index];
       
  4778         if (callback(value, index, array)) {
       
  4779           result.push(value);
       
  4780           splice.call(array, index--, 1);
       
  4781           length--;
       
  4782         }
       
  4783       }
       
  4784       return result;
       
  4785     }
       
  4786 
       
  4787     /**
       
  4788      * The opposite of `_.initial` this method gets all but the first element or
       
  4789      * first `n` elements of an array. If a callback function is provided elements
       
  4790      * at the beginning of the array are excluded from the result as long as the
       
  4791      * callback returns truey. The callback is bound to `thisArg` and invoked
       
  4792      * with three arguments; (value, index, array).
       
  4793      *
       
  4794      * If a property name is provided for `callback` the created "_.pluck" style
       
  4795      * callback will return the property value of the given element.
       
  4796      *
       
  4797      * If an object is provided for `callback` the created "_.where" style callback
       
  4798      * will return `true` for elements that have the properties of the given object,
       
  4799      * else `false`.
       
  4800      *
       
  4801      * @static
       
  4802      * @memberOf _
       
  4803      * @alias drop, tail
       
  4804      * @category Arrays
       
  4805      * @param {Array} array The array to query.
       
  4806      * @param {Function|Object|number|string} [callback=1] The function called
       
  4807      *  per element or the number of elements to exclude. If a property name or
       
  4808      *  object is provided it will be used to create a "_.pluck" or "_.where"
       
  4809      *  style callback, respectively.
       
  4810      * @param {*} [thisArg] The `this` binding of `callback`.
       
  4811      * @returns {Array} Returns a slice of `array`.
       
  4812      * @example
       
  4813      *
       
  4814      * _.rest([1, 2, 3]);
       
  4815      * // => [2, 3]
       
  4816      *
       
  4817      * _.rest([1, 2, 3], 2);
       
  4818      * // => [3]
       
  4819      *
       
  4820      * _.rest([1, 2, 3], function(num) {
       
  4821      *   return num < 3;
       
  4822      * });
       
  4823      * // => [3]
       
  4824      *
       
  4825      * var characters = [
       
  4826      *   { 'name': 'barney',  'blocked': true,  'employer': 'slate' },
       
  4827      *   { 'name': 'fred',    'blocked': false,  'employer': 'slate' },
       
  4828      *   { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
       
  4829      * ];
       
  4830      *
       
  4831      * // using "_.pluck" callback shorthand
       
  4832      * _.pluck(_.rest(characters, 'blocked'), 'name');
       
  4833      * // => ['fred', 'pebbles']
       
  4834      *
       
  4835      * // using "_.where" callback shorthand
       
  4836      * _.rest(characters, { 'employer': 'slate' });
       
  4837      * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
       
  4838      */
       
  4839     function rest(array, callback, thisArg) {
       
  4840       if (typeof callback != 'number' && callback != null) {
       
  4841         var n = 0,
       
  4842             index = -1,
       
  4843             length = array ? array.length : 0;
       
  4844 
       
  4845         callback = lodash.createCallback(callback, thisArg, 3);
       
  4846         while (++index < length && callback(array[index], index, array)) {
       
  4847           n++;
       
  4848         }
       
  4849       } else {
       
  4850         n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
       
  4851       }
       
  4852       return slice(array, n);
       
  4853     }
       
  4854 
       
  4855     /**
       
  4856      * Uses a binary search to determine the smallest index at which a value
       
  4857      * should be inserted into a given sorted array in order to maintain the sort
       
  4858      * order of the array. If a callback is provided it will be executed for
       
  4859      * `value` and each element of `array` to compute their sort ranking. The
       
  4860      * callback is bound to `thisArg` and invoked with one argument; (value).
       
  4861      *
       
  4862      * If a property name is provided for `callback` the created "_.pluck" style
       
  4863      * callback will return the property value of the given element.
       
  4864      *
       
  4865      * If an object is provided for `callback` the created "_.where" style callback
       
  4866      * will return `true` for elements that have the properties of the given object,
       
  4867      * else `false`.
       
  4868      *
       
  4869      * @static
       
  4870      * @memberOf _
       
  4871      * @category Arrays
       
  4872      * @param {Array} array The array to inspect.
       
  4873      * @param {*} value The value to evaluate.
       
  4874      * @param {Function|Object|string} [callback=identity] The function called
       
  4875      *  per iteration. If a property name or object is provided it will be used
       
  4876      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  4877      * @param {*} [thisArg] The `this` binding of `callback`.
       
  4878      * @returns {number} Returns the index at which `value` should be inserted
       
  4879      *  into `array`.
       
  4880      * @example
       
  4881      *
       
  4882      * _.sortedIndex([20, 30, 50], 40);
       
  4883      * // => 2
       
  4884      *
       
  4885      * // using "_.pluck" callback shorthand
       
  4886      * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
       
  4887      * // => 2
       
  4888      *
       
  4889      * var dict = {
       
  4890      *   'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
       
  4891      * };
       
  4892      *
       
  4893      * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
       
  4894      *   return dict.wordToNumber[word];
       
  4895      * });
       
  4896      * // => 2
       
  4897      *
       
  4898      * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
       
  4899      *   return this.wordToNumber[word];
       
  4900      * }, dict);
       
  4901      * // => 2
       
  4902      */
       
  4903     function sortedIndex(array, value, callback, thisArg) {
       
  4904       var low = 0,
       
  4905           high = array ? array.length : low;
       
  4906 
       
  4907       // explicitly reference `identity` for better inlining in Firefox
       
  4908       callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
       
  4909       value = callback(value);
       
  4910 
       
  4911       while (low < high) {
       
  4912         var mid = (low + high) >>> 1;
       
  4913         (callback(array[mid]) < value)
       
  4914           ? low = mid + 1
       
  4915           : high = mid;
       
  4916       }
       
  4917       return low;
       
  4918     }
       
  4919 
       
  4920     /**
       
  4921      * Creates an array of unique values, in order, of the provided arrays using
       
  4922      * strict equality for comparisons, i.e. `===`.
       
  4923      *
       
  4924      * @static
       
  4925      * @memberOf _
       
  4926      * @category Arrays
       
  4927      * @param {...Array} [array] The arrays to inspect.
       
  4928      * @returns {Array} Returns an array of combined values.
       
  4929      * @example
       
  4930      *
       
  4931      * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
       
  4932      * // => [1, 2, 3, 5, 4]
       
  4933      */
       
  4934     function union() {
       
  4935       return baseUniq(baseFlatten(arguments, true, true));
       
  4936     }
       
  4937 
       
  4938     /**
       
  4939      * Creates a duplicate-value-free version of an array using strict equality
       
  4940      * for comparisons, i.e. `===`. If the array is sorted, providing
       
  4941      * `true` for `isSorted` will use a faster algorithm. If a callback is provided
       
  4942      * each element of `array` is passed through the callback before uniqueness
       
  4943      * is computed. The callback is bound to `thisArg` and invoked with three
       
  4944      * arguments; (value, index, array).
       
  4945      *
       
  4946      * If a property name is provided for `callback` the created "_.pluck" style
       
  4947      * callback will return the property value of the given element.
       
  4948      *
       
  4949      * If an object is provided for `callback` the created "_.where" style callback
       
  4950      * will return `true` for elements that have the properties of the given object,
       
  4951      * else `false`.
       
  4952      *
       
  4953      * @static
       
  4954      * @memberOf _
       
  4955      * @alias unique
       
  4956      * @category Arrays
       
  4957      * @param {Array} array The array to process.
       
  4958      * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
       
  4959      * @param {Function|Object|string} [callback=identity] The function called
       
  4960      *  per iteration. If a property name or object is provided it will be used
       
  4961      *  to create a "_.pluck" or "_.where" style callback, respectively.
       
  4962      * @param {*} [thisArg] The `this` binding of `callback`.
       
  4963      * @returns {Array} Returns a duplicate-value-free array.
       
  4964      * @example
       
  4965      *
       
  4966      * _.uniq([1, 2, 1, 3, 1]);
       
  4967      * // => [1, 2, 3]
       
  4968      *
       
  4969      * _.uniq([1, 1, 2, 2, 3], true);
       
  4970      * // => [1, 2, 3]
       
  4971      *
       
  4972      * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
       
  4973      * // => ['A', 'b', 'C']
       
  4974      *
       
  4975      * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
       
  4976      * // => [1, 2.5, 3]
       
  4977      *
       
  4978      * // using "_.pluck" callback shorthand
       
  4979      * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
       
  4980      * // => [{ 'x': 1 }, { 'x': 2 }]
       
  4981      */
       
  4982     function uniq(array, isSorted, callback, thisArg) {
       
  4983       // juggle arguments
       
  4984       if (typeof isSorted != 'boolean' && isSorted != null) {
       
  4985         thisArg = callback;
       
  4986         callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
       
  4987         isSorted = false;
       
  4988       }
       
  4989       if (callback != null) {
       
  4990         callback = lodash.createCallback(callback, thisArg, 3);
       
  4991       }
       
  4992       return baseUniq(array, isSorted, callback);
       
  4993     }
       
  4994 
       
  4995     /**
       
  4996      * Creates an array excluding all provided values using strict equality for
       
  4997      * comparisons, i.e. `===`.
       
  4998      *
       
  4999      * @static
       
  5000      * @memberOf _
       
  5001      * @category Arrays
       
  5002      * @param {Array} array The array to filter.
       
  5003      * @param {...*} [value] The values to exclude.
       
  5004      * @returns {Array} Returns a new array of filtered values.
       
  5005      * @example
       
  5006      *
       
  5007      * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
       
  5008      * // => [2, 3, 4]
       
  5009      */
       
  5010     function without(array) {
       
  5011       return baseDifference(array, slice(arguments, 1));
       
  5012     }
       
  5013 
       
  5014     /**
       
  5015      * Creates an array that is the symmetric difference of the provided arrays.
       
  5016      * See http://en.wikipedia.org/wiki/Symmetric_difference.
       
  5017      *
       
  5018      * @static
       
  5019      * @memberOf _
       
  5020      * @category Arrays
       
  5021      * @param {...Array} [array] The arrays to inspect.
       
  5022      * @returns {Array} Returns an array of values.
       
  5023      * @example
       
  5024      *
       
  5025      * _.xor([1, 2, 3], [5, 2, 1, 4]);
       
  5026      * // => [3, 5, 4]
       
  5027      *
       
  5028      * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
       
  5029      * // => [1, 4, 5]
       
  5030      */
       
  5031     function xor() {
       
  5032       var index = -1,
       
  5033           length = arguments.length;
       
  5034 
       
  5035       while (++index < length) {
       
  5036         var array = arguments[index];
       
  5037         if (isArray(array) || isArguments(array)) {
       
  5038           var result = result
       
  5039             ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result)))
       
  5040             : array;
       
  5041         }
       
  5042       }
       
  5043       return result || [];
       
  5044     }
       
  5045 
       
  5046     /**
       
  5047      * Creates an array of grouped elements, the first of which contains the first
       
  5048      * elements of the given arrays, the second of which contains the second
       
  5049      * elements of the given arrays, and so on.
       
  5050      *
       
  5051      * @static
       
  5052      * @memberOf _
       
  5053      * @alias unzip
       
  5054      * @category Arrays
       
  5055      * @param {...Array} [array] Arrays to process.
       
  5056      * @returns {Array} Returns a new array of grouped elements.
       
  5057      * @example
       
  5058      *
       
  5059      * _.zip(['fred', 'barney'], [30, 40], [true, false]);
       
  5060      * // => [['fred', 30, true], ['barney', 40, false]]
       
  5061      */
       
  5062     function zip() {
       
  5063       var array = arguments.length > 1 ? arguments : arguments[0],
       
  5064           index = -1,
       
  5065           length = array ? max(pluck(array, 'length')) : 0,
       
  5066           result = Array(length < 0 ? 0 : length);
       
  5067 
       
  5068       while (++index < length) {
       
  5069         result[index] = pluck(array, index);
       
  5070       }
       
  5071       return result;
       
  5072     }
       
  5073 
       
  5074     /**
       
  5075      * Creates an object composed from arrays of `keys` and `values`. Provide
       
  5076      * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
       
  5077      * or two arrays, one of `keys` and one of corresponding `values`.
       
  5078      *
       
  5079      * @static
       
  5080      * @memberOf _
       
  5081      * @alias object
       
  5082      * @category Arrays
       
  5083      * @param {Array} keys The array of keys.
       
  5084      * @param {Array} [values=[]] The array of values.
       
  5085      * @returns {Object} Returns an object composed of the given keys and
       
  5086      *  corresponding values.
       
  5087      * @example
       
  5088      *
       
  5089      * _.zipObject(['fred', 'barney'], [30, 40]);
       
  5090      * // => { 'fred': 30, 'barney': 40 }
       
  5091      */
       
  5092     function zipObject(keys, values) {
       
  5093       var index = -1,
       
  5094           length = keys ? keys.length : 0,
       
  5095           result = {};
       
  5096 
       
  5097       if (!values && length && !isArray(keys[0])) {
       
  5098         values = [];
       
  5099       }
       
  5100       while (++index < length) {
       
  5101         var key = keys[index];
       
  5102         if (values) {
       
  5103           result[key] = values[index];
       
  5104         } else if (key) {
       
  5105           result[key[0]] = key[1];
       
  5106         }
       
  5107       }
       
  5108       return result;
       
  5109     }
       
  5110 
       
  5111     /*--------------------------------------------------------------------------*/
       
  5112 
       
  5113     /**
       
  5114      * Creates a function that executes `func`, with  the `this` binding and
       
  5115      * arguments of the created function, only after being called `n` times.
       
  5116      *
       
  5117      * @static
       
  5118      * @memberOf _
       
  5119      * @category Functions
       
  5120      * @param {number} n The number of times the function must be called before
       
  5121      *  `func` is executed.
       
  5122      * @param {Function} func The function to restrict.
       
  5123      * @returns {Function} Returns the new restricted function.
       
  5124      * @example
       
  5125      *
       
  5126      * var saves = ['profile', 'settings'];
       
  5127      *
       
  5128      * var done = _.after(saves.length, function() {
       
  5129      *   console.log('Done saving!');
       
  5130      * });
       
  5131      *
       
  5132      * _.forEach(saves, function(type) {
       
  5133      *   asyncSave({ 'type': type, 'complete': done });
       
  5134      * });
       
  5135      * // => logs 'Done saving!', after all saves have completed
       
  5136      */
       
  5137     function after(n, func) {
       
  5138       if (!isFunction(func)) {
       
  5139         throw new TypeError;
       
  5140       }
       
  5141       return function() {
       
  5142         if (--n < 1) {
       
  5143           return func.apply(this, arguments);
       
  5144         }
       
  5145       };
       
  5146     }
       
  5147 
       
  5148     /**
       
  5149      * Creates a function that, when called, invokes `func` with the `this`
       
  5150      * binding of `thisArg` and prepends any additional `bind` arguments to those
       
  5151      * provided to the bound function.
       
  5152      *
       
  5153      * @static
       
  5154      * @memberOf _
       
  5155      * @category Functions
       
  5156      * @param {Function} func The function to bind.
       
  5157      * @param {*} [thisArg] The `this` binding of `func`.
       
  5158      * @param {...*} [arg] Arguments to be partially applied.
       
  5159      * @returns {Function} Returns the new bound function.
       
  5160      * @example
       
  5161      *
       
  5162      * var func = function(greeting) {
       
  5163      *   return greeting + ' ' + this.name;
       
  5164      * };
       
  5165      *
       
  5166      * func = _.bind(func, { 'name': 'fred' }, 'hi');
       
  5167      * func();
       
  5168      * // => 'hi fred'
       
  5169      */
       
  5170     function bind(func, thisArg) {
       
  5171       return arguments.length > 2
       
  5172         ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
       
  5173         : createWrapper(func, 1, null, null, thisArg);
       
  5174     }
       
  5175 
       
  5176     /**
       
  5177      * Binds methods of an object to the object itself, overwriting the existing
       
  5178      * method. Method names may be specified as individual arguments or as arrays
       
  5179      * of method names. If no method names are provided all the function properties
       
  5180      * of `object` will be bound.
       
  5181      *
       
  5182      * @static
       
  5183      * @memberOf _
       
  5184      * @category Functions
       
  5185      * @param {Object} object The object to bind and assign the bound methods to.
       
  5186      * @param {...string} [methodName] The object method names to
       
  5187      *  bind, specified as individual method names or arrays of method names.
       
  5188      * @returns {Object} Returns `object`.
       
  5189      * @example
       
  5190      *
       
  5191      * var view = {
       
  5192      *   'label': 'docs',
       
  5193      *   'onClick': function() { console.log('clicked ' + this.label); }
       
  5194      * };
       
  5195      *
       
  5196      * _.bindAll(view);
       
  5197      * jQuery('#docs').on('click', view.onClick);
       
  5198      * // => logs 'clicked docs', when the button is clicked
       
  5199      */
       
  5200     function bindAll(object) {
       
  5201       var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
       
  5202           index = -1,
       
  5203           length = funcs.length;
       
  5204 
       
  5205       while (++index < length) {
       
  5206         var key = funcs[index];
       
  5207         object[key] = createWrapper(object[key], 1, null, null, object);
       
  5208       }
       
  5209       return object;
       
  5210     }
       
  5211 
       
  5212     /**
       
  5213      * Creates a function that, when called, invokes the method at `object[key]`
       
  5214      * and prepends any additional `bindKey` arguments to those provided to the bound
       
  5215      * function. This method differs from `_.bind` by allowing bound functions to
       
  5216      * reference methods that will be redefined or don't yet exist.
       
  5217      * See http://michaux.ca/articles/lazy-function-definition-pattern.
       
  5218      *
       
  5219      * @static
       
  5220      * @memberOf _
       
  5221      * @category Functions
       
  5222      * @param {Object} object The object the method belongs to.
       
  5223      * @param {string} key The key of the method.
       
  5224      * @param {...*} [arg] Arguments to be partially applied.
       
  5225      * @returns {Function} Returns the new bound function.
       
  5226      * @example
       
  5227      *
       
  5228      * var object = {
       
  5229      *   'name': 'fred',
       
  5230      *   'greet': function(greeting) {
       
  5231      *     return greeting + ' ' + this.name;
       
  5232      *   }
       
  5233      * };
       
  5234      *
       
  5235      * var func = _.bindKey(object, 'greet', 'hi');
       
  5236      * func();
       
  5237      * // => 'hi fred'
       
  5238      *
       
  5239      * object.greet = function(greeting) {
       
  5240      *   return greeting + 'ya ' + this.name + '!';
       
  5241      * };
       
  5242      *
       
  5243      * func();
       
  5244      * // => 'hiya fred!'
       
  5245      */
       
  5246     function bindKey(object, key) {
       
  5247       return arguments.length > 2
       
  5248         ? createWrapper(key, 19, slice(arguments, 2), null, object)
       
  5249         : createWrapper(key, 3, null, null, object);
       
  5250     }
       
  5251 
       
  5252     /**
       
  5253      * Creates a function that is the composition of the provided functions,
       
  5254      * where each function consumes the return value of the function that follows.
       
  5255      * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
       
  5256      * Each function is executed with the `this` binding of the composed function.
       
  5257      *
       
  5258      * @static
       
  5259      * @memberOf _
       
  5260      * @category Functions
       
  5261      * @param {...Function} [func] Functions to compose.
       
  5262      * @returns {Function} Returns the new composed function.
       
  5263      * @example
       
  5264      *
       
  5265      * var realNameMap = {
       
  5266      *   'pebbles': 'penelope'
       
  5267      * };
       
  5268      *
       
  5269      * var format = function(name) {
       
  5270      *   name = realNameMap[name.toLowerCase()] || name;
       
  5271      *   return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
       
  5272      * };
       
  5273      *
       
  5274      * var greet = function(formatted) {
       
  5275      *   return 'Hiya ' + formatted + '!';
       
  5276      * };
       
  5277      *
       
  5278      * var welcome = _.compose(greet, format);
       
  5279      * welcome('pebbles');
       
  5280      * // => 'Hiya Penelope!'
       
  5281      */
       
  5282     function compose() {
       
  5283       var funcs = arguments,
       
  5284           length = funcs.length;
       
  5285 
       
  5286       while (length--) {
       
  5287         if (!isFunction(funcs[length])) {
       
  5288           throw new TypeError;
       
  5289         }
       
  5290       }
       
  5291       return function() {
       
  5292         var args = arguments,
       
  5293             length = funcs.length;
       
  5294 
       
  5295         while (length--) {
       
  5296           args = [funcs[length].apply(this, args)];
       
  5297         }
       
  5298         return args[0];
       
  5299       };
       
  5300     }
       
  5301 
       
  5302     /**
       
  5303      * Creates a function which accepts one or more arguments of `func` that when
       
  5304      * invoked either executes `func` returning its result, if all `func` arguments
       
  5305      * have been provided, or returns a function that accepts one or more of the
       
  5306      * remaining `func` arguments, and so on. The arity of `func` can be specified
       
  5307      * if `func.length` is not sufficient.
       
  5308      *
       
  5309      * @static
       
  5310      * @memberOf _
       
  5311      * @category Functions
       
  5312      * @param {Function} func The function to curry.
       
  5313      * @param {number} [arity=func.length] The arity of `func`.
       
  5314      * @returns {Function} Returns the new curried function.
       
  5315      * @example
       
  5316      *
       
  5317      * var curried = _.curry(function(a, b, c) {
       
  5318      *   console.log(a + b + c);
       
  5319      * });
       
  5320      *
       
  5321      * curried(1)(2)(3);
       
  5322      * // => 6
       
  5323      *
       
  5324      * curried(1, 2)(3);
       
  5325      * // => 6
       
  5326      *
       
  5327      * curried(1, 2, 3);
       
  5328      * // => 6
       
  5329      */
       
  5330     function curry(func, arity) {
       
  5331       arity = typeof arity == 'number' ? arity : (+arity || func.length);
       
  5332       return createWrapper(func, 4, null, null, null, arity);
       
  5333     }
       
  5334 
       
  5335     /**
       
  5336      * Creates a function that will delay the execution of `func` until after
       
  5337      * `wait` milliseconds have elapsed since the last time it was invoked.
       
  5338      * Provide an options object to indicate that `func` should be invoked on
       
  5339      * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
       
  5340      * to the debounced function will return the result of the last `func` call.
       
  5341      *
       
  5342      * Note: If `leading` and `trailing` options are `true` `func` will be called
       
  5343      * on the trailing edge of the timeout only if the the debounced function is
       
  5344      * invoked more than once during the `wait` timeout.
       
  5345      *
       
  5346      * @static
       
  5347      * @memberOf _
       
  5348      * @category Functions
       
  5349      * @param {Function} func The function to debounce.
       
  5350      * @param {number} wait The number of milliseconds to delay.
       
  5351      * @param {Object} [options] The options object.
       
  5352      * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
       
  5353      * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
       
  5354      * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
       
  5355      * @returns {Function} Returns the new debounced function.
       
  5356      * @example
       
  5357      *
       
  5358      * // avoid costly calculations while the window size is in flux
       
  5359      * var lazyLayout = _.debounce(calculateLayout, 150);
       
  5360      * jQuery(window).on('resize', lazyLayout);
       
  5361      *
       
  5362      * // execute `sendMail` when the click event is fired, debouncing subsequent calls
       
  5363      * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
       
  5364      *   'leading': true,
       
  5365      *   'trailing': false
       
  5366      * });
       
  5367      *
       
  5368      * // ensure `batchLog` is executed once after 1 second of debounced calls
       
  5369      * var source = new EventSource('/stream');
       
  5370      * source.addEventListener('message', _.debounce(batchLog, 250, {
       
  5371      *   'maxWait': 1000
       
  5372      * }, false);
       
  5373      */
       
  5374     function debounce(func, wait, options) {
       
  5375       var args,
       
  5376           maxTimeoutId,
       
  5377           result,
       
  5378           stamp,
       
  5379           thisArg,
       
  5380           timeoutId,
       
  5381           trailingCall,
       
  5382           lastCalled = 0,
       
  5383           maxWait = false,
       
  5384           trailing = true;
       
  5385 
       
  5386       if (!isFunction(func)) {
       
  5387         throw new TypeError;
       
  5388       }
       
  5389       wait = nativeMax(0, wait) || 0;
       
  5390       if (options === true) {
       
  5391         var leading = true;
       
  5392         trailing = false;
       
  5393       } else if (isObject(options)) {
       
  5394         leading = options.leading;
       
  5395         maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
       
  5396         trailing = 'trailing' in options ? options.trailing : trailing;
       
  5397       }
       
  5398       var delayed = function() {
       
  5399         var remaining = wait - (now() - stamp);
       
  5400         if (remaining <= 0) {
       
  5401           if (maxTimeoutId) {
       
  5402             clearTimeout(maxTimeoutId);
       
  5403           }
       
  5404           var isCalled = trailingCall;
       
  5405           maxTimeoutId = timeoutId = trailingCall = undefined;
       
  5406           if (isCalled) {
       
  5407             lastCalled = now();
       
  5408             result = func.apply(thisArg, args);
       
  5409             if (!timeoutId && !maxTimeoutId) {
       
  5410               args = thisArg = null;
       
  5411             }
       
  5412           }
       
  5413         } else {
       
  5414           timeoutId = setTimeout(delayed, remaining);
       
  5415         }
       
  5416       };
       
  5417 
       
  5418       var maxDelayed = function() {
       
  5419         if (timeoutId) {
       
  5420           clearTimeout(timeoutId);
       
  5421         }
       
  5422         maxTimeoutId = timeoutId = trailingCall = undefined;
       
  5423         if (trailing || (maxWait !== wait)) {
       
  5424           lastCalled = now();
       
  5425           result = func.apply(thisArg, args);
       
  5426           if (!timeoutId && !maxTimeoutId) {
       
  5427             args = thisArg = null;
       
  5428           }
       
  5429         }
       
  5430       };
       
  5431 
       
  5432       return function() {
       
  5433         args = arguments;
       
  5434         stamp = now();
       
  5435         thisArg = this;
       
  5436         trailingCall = trailing && (timeoutId || !leading);
       
  5437 
       
  5438         if (maxWait === false) {
       
  5439           var leadingCall = leading && !timeoutId;
       
  5440         } else {
       
  5441           if (!maxTimeoutId && !leading) {
       
  5442             lastCalled = stamp;
       
  5443           }
       
  5444           var remaining = maxWait - (stamp - lastCalled),
       
  5445               isCalled = remaining <= 0;
       
  5446 
       
  5447           if (isCalled) {
       
  5448             if (maxTimeoutId) {
       
  5449               maxTimeoutId = clearTimeout(maxTimeoutId);
       
  5450             }
       
  5451             lastCalled = stamp;
       
  5452             result = func.apply(thisArg, args);
       
  5453           }
       
  5454           else if (!maxTimeoutId) {
       
  5455             maxTimeoutId = setTimeout(maxDelayed, remaining);
       
  5456           }
       
  5457         }
       
  5458         if (isCalled && timeoutId) {
       
  5459           timeoutId = clearTimeout(timeoutId);
       
  5460         }
       
  5461         else if (!timeoutId && wait !== maxWait) {
       
  5462           timeoutId = setTimeout(delayed, wait);
       
  5463         }
       
  5464         if (leadingCall) {
       
  5465           isCalled = true;
       
  5466           result = func.apply(thisArg, args);
       
  5467         }
       
  5468         if (isCalled && !timeoutId && !maxTimeoutId) {
       
  5469           args = thisArg = null;
       
  5470         }
       
  5471         return result;
       
  5472       };
       
  5473     }
       
  5474 
       
  5475     /**
       
  5476      * Defers executing the `func` function until the current call stack has cleared.
       
  5477      * Additional arguments will be provided to `func` when it is invoked.
       
  5478      *
       
  5479      * @static
       
  5480      * @memberOf _
       
  5481      * @category Functions
       
  5482      * @param {Function} func The function to defer.
       
  5483      * @param {...*} [arg] Arguments to invoke the function with.
       
  5484      * @returns {number} Returns the timer id.
       
  5485      * @example
       
  5486      *
       
  5487      * _.defer(function(text) { console.log(text); }, 'deferred');
       
  5488      * // logs 'deferred' after one or more milliseconds
       
  5489      */
       
  5490     function defer(func) {
       
  5491       if (!isFunction(func)) {
       
  5492         throw new TypeError;
       
  5493       }
       
  5494       var args = slice(arguments, 1);
       
  5495       return setTimeout(function() { func.apply(undefined, args); }, 1);
       
  5496     }
       
  5497 
       
  5498     /**
       
  5499      * Executes the `func` function after `wait` milliseconds. Additional arguments
       
  5500      * will be provided to `func` when it is invoked.
       
  5501      *
       
  5502      * @static
       
  5503      * @memberOf _
       
  5504      * @category Functions
       
  5505      * @param {Function} func The function to delay.
       
  5506      * @param {number} wait The number of milliseconds to delay execution.
       
  5507      * @param {...*} [arg] Arguments to invoke the function with.
       
  5508      * @returns {number} Returns the timer id.
       
  5509      * @example
       
  5510      *
       
  5511      * _.delay(function(text) { console.log(text); }, 1000, 'later');
       
  5512      * // => logs 'later' after one second
       
  5513      */
       
  5514     function delay(func, wait) {
       
  5515       if (!isFunction(func)) {
       
  5516         throw new TypeError;
       
  5517       }
       
  5518       var args = slice(arguments, 2);
       
  5519       return setTimeout(function() { func.apply(undefined, args); }, wait);
       
  5520     }
       
  5521 
       
  5522     /**
       
  5523      * Creates a function that memoizes the result of `func`. If `resolver` is
       
  5524      * provided it will be used to determine the cache key for storing the result
       
  5525      * based on the arguments provided to the memoized function. By default, the
       
  5526      * first argument provided to the memoized function is used as the cache key.
       
  5527      * The `func` is executed with the `this` binding of the memoized function.
       
  5528      * The result cache is exposed as the `cache` property on the memoized function.
       
  5529      *
       
  5530      * @static
       
  5531      * @memberOf _
       
  5532      * @category Functions
       
  5533      * @param {Function} func The function to have its output memoized.
       
  5534      * @param {Function} [resolver] A function used to resolve the cache key.
       
  5535      * @returns {Function} Returns the new memoizing function.
       
  5536      * @example
       
  5537      *
       
  5538      * var fibonacci = _.memoize(function(n) {
       
  5539      *   return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
       
  5540      * });
       
  5541      *
       
  5542      * fibonacci(9)
       
  5543      * // => 34
       
  5544      *
       
  5545      * var data = {
       
  5546      *   'fred': { 'name': 'fred', 'age': 40 },
       
  5547      *   'pebbles': { 'name': 'pebbles', 'age': 1 }
       
  5548      * };
       
  5549      *
       
  5550      * // modifying the result cache
       
  5551      * var get = _.memoize(function(name) { return data[name]; }, _.identity);
       
  5552      * get('pebbles');
       
  5553      * // => { 'name': 'pebbles', 'age': 1 }
       
  5554      *
       
  5555      * get.cache.pebbles.name = 'penelope';
       
  5556      * get('pebbles');
       
  5557      * // => { 'name': 'penelope', 'age': 1 }
       
  5558      */
       
  5559     function memoize(func, resolver) {
       
  5560       if (!isFunction(func)) {
       
  5561         throw new TypeError;
       
  5562       }
       
  5563       var memoized = function() {
       
  5564         var cache = memoized.cache,
       
  5565             key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
       
  5566 
       
  5567         return hasOwnProperty.call(cache, key)
       
  5568           ? cache[key]
       
  5569           : (cache[key] = func.apply(this, arguments));
       
  5570       }
       
  5571       memoized.cache = {};
       
  5572       return memoized;
       
  5573     }
       
  5574 
       
  5575     /**
       
  5576      * Creates a function that is restricted to execute `func` once. Repeat calls to
       
  5577      * the function will return the value of the first call. The `func` is executed
       
  5578      * with the `this` binding of the created function.
       
  5579      *
       
  5580      * @static
       
  5581      * @memberOf _
       
  5582      * @category Functions
       
  5583      * @param {Function} func The function to restrict.
       
  5584      * @returns {Function} Returns the new restricted function.
       
  5585      * @example
       
  5586      *
       
  5587      * var initialize = _.once(createApplication);
       
  5588      * initialize();
       
  5589      * initialize();
       
  5590      * // `initialize` executes `createApplication` once
       
  5591      */
       
  5592     function once(func) {
       
  5593       var ran,
       
  5594           result;
       
  5595 
       
  5596       if (!isFunction(func)) {
       
  5597         throw new TypeError;
       
  5598       }
       
  5599       return function() {
       
  5600         if (ran) {
       
  5601           return result;
       
  5602         }
       
  5603         ran = true;
       
  5604         result = func.apply(this, arguments);
       
  5605 
       
  5606         // clear the `func` variable so the function may be garbage collected
       
  5607         func = null;
       
  5608         return result;
       
  5609       };
       
  5610     }
       
  5611 
       
  5612     /**
       
  5613      * Creates a function that, when called, invokes `func` with any additional
       
  5614      * `partial` arguments prepended to those provided to the new function. This
       
  5615      * method is similar to `_.bind` except it does **not** alter the `this` binding.
       
  5616      *
       
  5617      * @static
       
  5618      * @memberOf _
       
  5619      * @category Functions
       
  5620      * @param {Function} func The function to partially apply arguments to.
       
  5621      * @param {...*} [arg] Arguments to be partially applied.
       
  5622      * @returns {Function} Returns the new partially applied function.
       
  5623      * @example
       
  5624      *
       
  5625      * var greet = function(greeting, name) { return greeting + ' ' + name; };
       
  5626      * var hi = _.partial(greet, 'hi');
       
  5627      * hi('fred');
       
  5628      * // => 'hi fred'
       
  5629      */
       
  5630     function partial(func) {
       
  5631       return createWrapper(func, 16, slice(arguments, 1));
       
  5632     }
       
  5633 
       
  5634     /**
       
  5635      * This method is like `_.partial` except that `partial` arguments are
       
  5636      * appended to those provided to the new function.
       
  5637      *
       
  5638      * @static
       
  5639      * @memberOf _
       
  5640      * @category Functions
       
  5641      * @param {Function} func The function to partially apply arguments to.
       
  5642      * @param {...*} [arg] Arguments to be partially applied.
       
  5643      * @returns {Function} Returns the new partially applied function.
       
  5644      * @example
       
  5645      *
       
  5646      * var defaultsDeep = _.partialRight(_.merge, _.defaults);
       
  5647      *
       
  5648      * var options = {
       
  5649      *   'variable': 'data',
       
  5650      *   'imports': { 'jq': $ }
       
  5651      * };
       
  5652      *
       
  5653      * defaultsDeep(options, _.templateSettings);
       
  5654      *
       
  5655      * options.variable
       
  5656      * // => 'data'
       
  5657      *
       
  5658      * options.imports
       
  5659      * // => { '_': _, 'jq': $ }
       
  5660      */
       
  5661     function partialRight(func) {
       
  5662       return createWrapper(func, 32, null, slice(arguments, 1));
       
  5663     }
       
  5664 
       
  5665     /**
       
  5666      * Creates a function that, when executed, will only call the `func` function
       
  5667      * at most once per every `wait` milliseconds. Provide an options object to
       
  5668      * indicate that `func` should be invoked on the leading and/or trailing edge
       
  5669      * of the `wait` timeout. Subsequent calls to the throttled function will
       
  5670      * return the result of the last `func` call.
       
  5671      *
       
  5672      * Note: If `leading` and `trailing` options are `true` `func` will be called
       
  5673      * on the trailing edge of the timeout only if the the throttled function is
       
  5674      * invoked more than once during the `wait` timeout.
       
  5675      *
       
  5676      * @static
       
  5677      * @memberOf _
       
  5678      * @category Functions
       
  5679      * @param {Function} func The function to throttle.
       
  5680      * @param {number} wait The number of milliseconds to throttle executions to.
       
  5681      * @param {Object} [options] The options object.
       
  5682      * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
       
  5683      * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
       
  5684      * @returns {Function} Returns the new throttled function.
       
  5685      * @example
       
  5686      *
       
  5687      * // avoid excessively updating the position while scrolling
       
  5688      * var throttled = _.throttle(updatePosition, 100);
       
  5689      * jQuery(window).on('scroll', throttled);
       
  5690      *
       
  5691      * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
       
  5692      * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
       
  5693      *   'trailing': false
       
  5694      * }));
       
  5695      */
       
  5696     function throttle(func, wait, options) {
       
  5697       var leading = true,
       
  5698           trailing = true;
       
  5699 
       
  5700       if (!isFunction(func)) {
       
  5701         throw new TypeError;
       
  5702       }
       
  5703       if (options === false) {
       
  5704         leading = false;
       
  5705       } else if (isObject(options)) {
       
  5706         leading = 'leading' in options ? options.leading : leading;
       
  5707         trailing = 'trailing' in options ? options.trailing : trailing;
       
  5708       }
       
  5709       debounceOptions.leading = leading;
       
  5710       debounceOptions.maxWait = wait;
       
  5711       debounceOptions.trailing = trailing;
       
  5712 
       
  5713       return debounce(func, wait, debounceOptions);
       
  5714     }
       
  5715 
       
  5716     /**
       
  5717      * Creates a function that provides `value` to the wrapper function as its
       
  5718      * first argument. Additional arguments provided to the function are appended
       
  5719      * to those provided to the wrapper function. The wrapper is executed with
       
  5720      * the `this` binding of the created function.
       
  5721      *
       
  5722      * @static
       
  5723      * @memberOf _
       
  5724      * @category Functions
       
  5725      * @param {*} value The value to wrap.
       
  5726      * @param {Function} wrapper The wrapper function.
       
  5727      * @returns {Function} Returns the new function.
       
  5728      * @example
       
  5729      *
       
  5730      * var p = _.wrap(_.escape, function(func, text) {
       
  5731      *   return '<p>' + func(text) + '</p>';
       
  5732      * });
       
  5733      *
       
  5734      * p('Fred, Wilma, & Pebbles');
       
  5735      * // => '<p>Fred, Wilma, &amp; Pebbles</p>'
       
  5736      */
       
  5737     function wrap(value, wrapper) {
       
  5738       return createWrapper(wrapper, 16, [value]);
       
  5739     }
       
  5740 
       
  5741     /*--------------------------------------------------------------------------*/
       
  5742 
       
  5743     /**
       
  5744      * Creates a function that returns `value`.
       
  5745      *
       
  5746      * @static
       
  5747      * @memberOf _
       
  5748      * @category Utilities
       
  5749      * @param {*} value The value to return from the new function.
       
  5750      * @returns {Function} Returns the new function.
       
  5751      * @example
       
  5752      *
       
  5753      * var object = { 'name': 'fred' };
       
  5754      * var getter = _.constant(object);
       
  5755      * getter() === object;
       
  5756      * // => true
       
  5757      */
       
  5758     function constant(value) {
       
  5759       return function() {
       
  5760         return value;
       
  5761       };
       
  5762     }
       
  5763 
       
  5764     /**
       
  5765      * Produces a callback bound to an optional `thisArg`. If `func` is a property
       
  5766      * name the created callback will return the property value for a given element.
       
  5767      * If `func` is an object the created callback will return `true` for elements
       
  5768      * that contain the equivalent object properties, otherwise it will return `false`.
       
  5769      *
       
  5770      * @static
       
  5771      * @memberOf _
       
  5772      * @category Utilities
       
  5773      * @param {*} [func=identity] The value to convert to a callback.
       
  5774      * @param {*} [thisArg] The `this` binding of the created callback.
       
  5775      * @param {number} [argCount] The number of arguments the callback accepts.
       
  5776      * @returns {Function} Returns a callback function.
       
  5777      * @example
       
  5778      *
       
  5779      * var characters = [
       
  5780      *   { 'name': 'barney', 'age': 36 },
       
  5781      *   { 'name': 'fred',   'age': 40 }
       
  5782      * ];
       
  5783      *
       
  5784      * // wrap to create custom callback shorthands
       
  5785      * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
       
  5786      *   var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
       
  5787      *   return !match ? func(callback, thisArg) : function(object) {
       
  5788      *     return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
       
  5789      *   };
       
  5790      * });
       
  5791      *
       
  5792      * _.filter(characters, 'age__gt38');
       
  5793      * // => [{ 'name': 'fred', 'age': 40 }]
       
  5794      */
       
  5795     function createCallback(func, thisArg, argCount) {
       
  5796       var type = typeof func;
       
  5797       if (func == null || type == 'function') {
       
  5798         return baseCreateCallback(func, thisArg, argCount);
       
  5799       }
       
  5800       // handle "_.pluck" style callback shorthands
       
  5801       if (type != 'object') {
       
  5802         return property(func);
       
  5803       }
       
  5804       var props = keys(func),
       
  5805           key = props[0],
       
  5806           a = func[key];
       
  5807 
       
  5808       // handle "_.where" style callback shorthands
       
  5809       if (props.length == 1 && a === a && !isObject(a)) {
       
  5810         // fast path the common case of providing an object with a single
       
  5811         // property containing a primitive value
       
  5812         return function(object) {
       
  5813           var b = object[key];
       
  5814           return a === b && (a !== 0 || (1 / a == 1 / b));
       
  5815         };
       
  5816       }
       
  5817       return function(object) {
       
  5818         var length = props.length,
       
  5819             result = false;
       
  5820 
       
  5821         while (length--) {
       
  5822           if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
       
  5823             break;
       
  5824           }
       
  5825         }
       
  5826         return result;
       
  5827       };
       
  5828     }
       
  5829 
       
  5830     /**
       
  5831      * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
       
  5832      * corresponding HTML entities.
       
  5833      *
       
  5834      * @static
       
  5835      * @memberOf _
       
  5836      * @category Utilities
       
  5837      * @param {string} string The string to escape.
       
  5838      * @returns {string} Returns the escaped string.
       
  5839      * @example
       
  5840      *
       
  5841      * _.escape('Fred, Wilma, & Pebbles');
       
  5842      * // => 'Fred, Wilma, &amp; Pebbles'
       
  5843      */
       
  5844     function escape(string) {
       
  5845       return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
       
  5846     }
       
  5847 
       
  5848     /**
       
  5849      * This method returns the first argument provided to it.
       
  5850      *
       
  5851      * @static
       
  5852      * @memberOf _
       
  5853      * @category Utilities
       
  5854      * @param {*} value Any value.
       
  5855      * @returns {*} Returns `value`.
       
  5856      * @example
       
  5857      *
       
  5858      * var object = { 'name': 'fred' };
       
  5859      * _.identity(object) === object;
       
  5860      * // => true
       
  5861      */
       
  5862     function identity(value) {
       
  5863       return value;
       
  5864     }
       
  5865 
       
  5866     /**
       
  5867      * Adds function properties of a source object to the destination object.
       
  5868      * If `object` is a function methods will be added to its prototype as well.
       
  5869      *
       
  5870      * @static
       
  5871      * @memberOf _
       
  5872      * @category Utilities
       
  5873      * @param {Function|Object} [object=lodash] object The destination object.
       
  5874      * @param {Object} source The object of functions to add.
       
  5875      * @param {Object} [options] The options object.
       
  5876      * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
       
  5877      * @example
       
  5878      *
       
  5879      * function capitalize(string) {
       
  5880      *   return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
       
  5881      * }
       
  5882      *
       
  5883      * _.mixin({ 'capitalize': capitalize });
       
  5884      * _.capitalize('fred');
       
  5885      * // => 'Fred'
       
  5886      *
       
  5887      * _('fred').capitalize().value();
       
  5888      * // => 'Fred'
       
  5889      *
       
  5890      * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
       
  5891      * _('fred').capitalize();
       
  5892      * // => 'Fred'
       
  5893      */
       
  5894     function mixin(object, source, options) {
       
  5895       var chain = true,
       
  5896           methodNames = source && functions(source);
       
  5897 
       
  5898       if (!source || (!options && !methodNames.length)) {
       
  5899         if (options == null) {
       
  5900           options = source;
       
  5901         }
       
  5902         ctor = lodashWrapper;
       
  5903         source = object;
       
  5904         object = lodash;
       
  5905         methodNames = functions(source);
       
  5906       }
       
  5907       if (options === false) {
       
  5908         chain = false;
       
  5909       } else if (isObject(options) && 'chain' in options) {
       
  5910         chain = options.chain;
       
  5911       }
       
  5912       var ctor = object,
       
  5913           isFunc = isFunction(ctor);
       
  5914 
       
  5915       forEach(methodNames, function(methodName) {
       
  5916         var func = object[methodName] = source[methodName];
       
  5917         if (isFunc) {
       
  5918           ctor.prototype[methodName] = function() {
       
  5919             var chainAll = this.__chain__,
       
  5920                 value = this.__wrapped__,
       
  5921                 args = [value];
       
  5922 
       
  5923             push.apply(args, arguments);
       
  5924             var result = func.apply(object, args);
       
  5925             if (chain || chainAll) {
       
  5926               if (value === result && isObject(result)) {
       
  5927                 return this;
       
  5928               }
       
  5929               result = new ctor(result);
       
  5930               result.__chain__ = chainAll;
       
  5931             }
       
  5932             return result;
       
  5933           };
       
  5934         }
       
  5935       });
       
  5936     }
       
  5937 
       
  5938     /**
       
  5939      * Reverts the '_' variable to its previous value and returns a reference to
       
  5940      * the `lodash` function.
       
  5941      *
       
  5942      * @static
       
  5943      * @memberOf _
       
  5944      * @category Utilities
       
  5945      * @returns {Function} Returns the `lodash` function.
       
  5946      * @example
       
  5947      *
       
  5948      * var lodash = _.noConflict();
       
  5949      */
       
  5950     function noConflict() {
       
  5951       context._ = oldDash;
       
  5952       return this;
       
  5953     }
       
  5954 
       
  5955     /**
       
  5956      * A no-operation function.
       
  5957      *
       
  5958      * @static
       
  5959      * @memberOf _
       
  5960      * @category Utilities
       
  5961      * @example
       
  5962      *
       
  5963      * var object = { 'name': 'fred' };
       
  5964      * _.noop(object) === undefined;
       
  5965      * // => true
       
  5966      */
       
  5967     function noop() {
       
  5968       // no operation performed
       
  5969     }
       
  5970 
       
  5971     /**
       
  5972      * Gets the number of milliseconds that have elapsed since the Unix epoch
       
  5973      * (1 January 1970 00:00:00 UTC).
       
  5974      *
       
  5975      * @static
       
  5976      * @memberOf _
       
  5977      * @category Utilities
       
  5978      * @example
       
  5979      *
       
  5980      * var stamp = _.now();
       
  5981      * _.defer(function() { console.log(_.now() - stamp); });
       
  5982      * // => logs the number of milliseconds it took for the deferred function to be called
       
  5983      */
       
  5984     var now = isNative(now = Date.now) && now || function() {
       
  5985       return new Date().getTime();
       
  5986     };
       
  5987 
       
  5988     /**
       
  5989      * Converts the given value into an integer of the specified radix.
       
  5990      * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
       
  5991      * `value` is a hexadecimal, in which case a `radix` of `16` is used.
       
  5992      *
       
  5993      * Note: This method avoids differences in native ES3 and ES5 `parseInt`
       
  5994      * implementations. See http://es5.github.io/#E.
       
  5995      *
       
  5996      * @static
       
  5997      * @memberOf _
       
  5998      * @category Utilities
       
  5999      * @param {string} value The value to parse.
       
  6000      * @param {number} [radix] The radix used to interpret the value to parse.
       
  6001      * @returns {number} Returns the new integer value.
       
  6002      * @example
       
  6003      *
       
  6004      * _.parseInt('08');
       
  6005      * // => 8
       
  6006      */
       
  6007     var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
       
  6008       // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
       
  6009       return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
       
  6010     };
       
  6011 
       
  6012     /**
       
  6013      * Creates a "_.pluck" style function, which returns the `key` value of a
       
  6014      * given object.
       
  6015      *
       
  6016      * @static
       
  6017      * @memberOf _
       
  6018      * @category Utilities
       
  6019      * @param {string} key The name of the property to retrieve.
       
  6020      * @returns {Function} Returns the new function.
       
  6021      * @example
       
  6022      *
       
  6023      * var characters = [
       
  6024      *   { 'name': 'fred',   'age': 40 },
       
  6025      *   { 'name': 'barney', 'age': 36 }
       
  6026      * ];
       
  6027      *
       
  6028      * var getName = _.property('name');
       
  6029      *
       
  6030      * _.map(characters, getName);
       
  6031      * // => ['barney', 'fred']
       
  6032      *
       
  6033      * _.sortBy(characters, getName);
       
  6034      * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred',   'age': 40 }]
       
  6035      */
       
  6036     function property(key) {
       
  6037       return function(object) {
       
  6038         return object[key];
       
  6039       };
       
  6040     }
       
  6041 
       
  6042     /**
       
  6043      * Produces a random number between `min` and `max` (inclusive). If only one
       
  6044      * argument is provided a number between `0` and the given number will be
       
  6045      * returned. If `floating` is truey or either `min` or `max` are floats a
       
  6046      * floating-point number will be returned instead of an integer.
       
  6047      *
       
  6048      * @static
       
  6049      * @memberOf _
       
  6050      * @category Utilities
       
  6051      * @param {number} [min=0] The minimum possible value.
       
  6052      * @param {number} [max=1] The maximum possible value.
       
  6053      * @param {boolean} [floating=false] Specify returning a floating-point number.
       
  6054      * @returns {number} Returns a random number.
       
  6055      * @example
       
  6056      *
       
  6057      * _.random(0, 5);
       
  6058      * // => an integer between 0 and 5
       
  6059      *
       
  6060      * _.random(5);
       
  6061      * // => also an integer between 0 and 5
       
  6062      *
       
  6063      * _.random(5, true);
       
  6064      * // => a floating-point number between 0 and 5
       
  6065      *
       
  6066      * _.random(1.2, 5.2);
       
  6067      * // => a floating-point number between 1.2 and 5.2
       
  6068      */
       
  6069     function random(min, max, floating) {
       
  6070       var noMin = min == null,
       
  6071           noMax = max == null;
       
  6072 
       
  6073       if (floating == null) {
       
  6074         if (typeof min == 'boolean' && noMax) {
       
  6075           floating = min;
       
  6076           min = 1;
       
  6077         }
       
  6078         else if (!noMax && typeof max == 'boolean') {
       
  6079           floating = max;
       
  6080           noMax = true;
       
  6081         }
       
  6082       }
       
  6083       if (noMin && noMax) {
       
  6084         max = 1;
       
  6085       }
       
  6086       min = +min || 0;
       
  6087       if (noMax) {
       
  6088         max = min;
       
  6089         min = 0;
       
  6090       } else {
       
  6091         max = +max || 0;
       
  6092       }
       
  6093       if (floating || min % 1 || max % 1) {
       
  6094         var rand = nativeRandom();
       
  6095         return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
       
  6096       }
       
  6097       return baseRandom(min, max);
       
  6098     }
       
  6099 
       
  6100     /**
       
  6101      * Resolves the value of property `key` on `object`. If `key` is a function
       
  6102      * it will be invoked with the `this` binding of `object` and its result returned,
       
  6103      * else the property value is returned. If `object` is falsey then `undefined`
       
  6104      * is returned.
       
  6105      *
       
  6106      * @static
       
  6107      * @memberOf _
       
  6108      * @category Utilities
       
  6109      * @param {Object} object The object to inspect.
       
  6110      * @param {string} key The name of the property to resolve.
       
  6111      * @returns {*} Returns the resolved value.
       
  6112      * @example
       
  6113      *
       
  6114      * var object = {
       
  6115      *   'cheese': 'crumpets',
       
  6116      *   'stuff': function() {
       
  6117      *     return 'nonsense';
       
  6118      *   }
       
  6119      * };
       
  6120      *
       
  6121      * _.result(object, 'cheese');
       
  6122      * // => 'crumpets'
       
  6123      *
       
  6124      * _.result(object, 'stuff');
       
  6125      * // => 'nonsense'
       
  6126      */
       
  6127     function result(object, key) {
       
  6128       if (object) {
       
  6129         var value = object[key];
       
  6130         return isFunction(value) ? object[key]() : value;
       
  6131       }
       
  6132     }
       
  6133 
       
  6134     /**
       
  6135      * A micro-templating method that handles arbitrary delimiters, preserves
       
  6136      * whitespace, and correctly escapes quotes within interpolated code.
       
  6137      *
       
  6138      * Note: In the development build, `_.template` utilizes sourceURLs for easier
       
  6139      * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
       
  6140      *
       
  6141      * For more information on precompiling templates see:
       
  6142      * http://lodash.com/custom-builds
       
  6143      *
       
  6144      * For more information on Chrome extension sandboxes see:
       
  6145      * http://developer.chrome.com/stable/extensions/sandboxingEval.html
       
  6146      *
       
  6147      * @static
       
  6148      * @memberOf _
       
  6149      * @category Utilities
       
  6150      * @param {string} text The template text.
       
  6151      * @param {Object} data The data object used to populate the text.
       
  6152      * @param {Object} [options] The options object.
       
  6153      * @param {RegExp} [options.escape] The "escape" delimiter.
       
  6154      * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
       
  6155      * @param {Object} [options.imports] An object to import into the template as local variables.
       
  6156      * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
       
  6157      * @param {string} [sourceURL] The sourceURL of the template's compiled source.
       
  6158      * @param {string} [variable] The data object variable name.
       
  6159      * @returns {Function|string} Returns a compiled function when no `data` object
       
  6160      *  is given, else it returns the interpolated text.
       
  6161      * @example
       
  6162      *
       
  6163      * // using the "interpolate" delimiter to create a compiled template
       
  6164      * var compiled = _.template('hello <%= name %>');
       
  6165      * compiled({ 'name': 'fred' });
       
  6166      * // => 'hello fred'
       
  6167      *
       
  6168      * // using the "escape" delimiter to escape HTML in data property values
       
  6169      * _.template('<b><%- value %></b>', { 'value': '<script>' });
       
  6170      * // => '<b>&lt;script&gt;</b>'
       
  6171      *
       
  6172      * // using the "evaluate" delimiter to generate HTML
       
  6173      * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
       
  6174      * _.template(list, { 'people': ['fred', 'barney'] });
       
  6175      * // => '<li>fred</li><li>barney</li>'
       
  6176      *
       
  6177      * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
       
  6178      * _.template('hello ${ name }', { 'name': 'pebbles' });
       
  6179      * // => 'hello pebbles'
       
  6180      *
       
  6181      * // using the internal `print` function in "evaluate" delimiters
       
  6182      * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
       
  6183      * // => 'hello barney!'
       
  6184      *
       
  6185      * // using a custom template delimiters
       
  6186      * _.templateSettings = {
       
  6187      *   'interpolate': /{{([\s\S]+?)}}/g
       
  6188      * };
       
  6189      *
       
  6190      * _.template('hello {{ name }}!', { 'name': 'mustache' });
       
  6191      * // => 'hello mustache!'
       
  6192      *
       
  6193      * // using the `imports` option to import jQuery
       
  6194      * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
       
  6195      * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
       
  6196      * // => '<li>fred</li><li>barney</li>'
       
  6197      *
       
  6198      * // using the `sourceURL` option to specify a custom sourceURL for the template
       
  6199      * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
       
  6200      * compiled(data);
       
  6201      * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
       
  6202      *
       
  6203      * // using the `variable` option to ensure a with-statement isn't used in the compiled template
       
  6204      * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
       
  6205      * compiled.source;
       
  6206      * // => function(data) {
       
  6207      *   var __t, __p = '', __e = _.escape;
       
  6208      *   __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
       
  6209      *   return __p;
       
  6210      * }
       
  6211      *
       
  6212      * // using the `source` property to inline compiled templates for meaningful
       
  6213      * // line numbers in error messages and a stack trace
       
  6214      * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
       
  6215      *   var JST = {\
       
  6216      *     "main": ' + _.template(mainText).source + '\
       
  6217      *   };\
       
  6218      * ');
       
  6219      */
       
  6220     function template(text, data, options) {
       
  6221       // based on John Resig's `tmpl` implementation
       
  6222       // http://ejohn.org/blog/javascript-micro-templating/
       
  6223       // and Laura Doktorova's doT.js
       
  6224       // https://github.com/olado/doT
       
  6225       var settings = lodash.templateSettings;
       
  6226       text = String(text || '');
       
  6227 
       
  6228       // avoid missing dependencies when `iteratorTemplate` is not defined
       
  6229       options = defaults({}, options, settings);
       
  6230 
       
  6231       var imports = defaults({}, options.imports, settings.imports),
       
  6232           importsKeys = keys(imports),
       
  6233           importsValues = values(imports);
       
  6234 
       
  6235       var isEvaluating,
       
  6236           index = 0,
       
  6237           interpolate = options.interpolate || reNoMatch,
       
  6238           source = "__p += '";
       
  6239 
       
  6240       // compile the regexp to match each delimiter
       
  6241       var reDelimiters = RegExp(
       
  6242         (options.escape || reNoMatch).source + '|' +
       
  6243         interpolate.source + '|' +
       
  6244         (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
       
  6245         (options.evaluate || reNoMatch).source + '|$'
       
  6246       , 'g');
       
  6247 
       
  6248       text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
       
  6249         interpolateValue || (interpolateValue = esTemplateValue);
       
  6250 
       
  6251         // escape characters that cannot be included in string literals
       
  6252         source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
       
  6253 
       
  6254         // replace delimiters with snippets
       
  6255         if (escapeValue) {
       
  6256           source += "' +\n__e(" + escapeValue + ") +\n'";
       
  6257         }
       
  6258         if (evaluateValue) {
       
  6259           isEvaluating = true;
       
  6260           source += "';\n" + evaluateValue + ";\n__p += '";
       
  6261         }
       
  6262         if (interpolateValue) {
       
  6263           source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
       
  6264         }
       
  6265         index = offset + match.length;
       
  6266 
       
  6267         // the JS engine embedded in Adobe products requires returning the `match`
       
  6268         // string in order to produce the correct `offset` value
       
  6269         return match;
       
  6270       });
       
  6271 
       
  6272       source += "';\n";
       
  6273 
       
  6274       // if `variable` is not specified, wrap a with-statement around the generated
       
  6275       // code to add the data object to the top of the scope chain
       
  6276       var variable = options.variable,
       
  6277           hasVariable = variable;
       
  6278 
       
  6279       if (!hasVariable) {
       
  6280         variable = 'obj';
       
  6281         source = 'with (' + variable + ') {\n' + source + '\n}\n';
       
  6282       }
       
  6283       // cleanup code by stripping empty strings
       
  6284       source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
       
  6285         .replace(reEmptyStringMiddle, '$1')
       
  6286         .replace(reEmptyStringTrailing, '$1;');
       
  6287 
       
  6288       // frame code as the function body
       
  6289       source = 'function(' + variable + ') {\n' +
       
  6290         (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
       
  6291         "var __t, __p = '', __e = _.escape" +
       
  6292         (isEvaluating
       
  6293           ? ', __j = Array.prototype.join;\n' +
       
  6294             "function print() { __p += __j.call(arguments, '') }\n"
       
  6295           : ';\n'
       
  6296         ) +
       
  6297         source +
       
  6298         'return __p\n}';
       
  6299 
       
  6300       // Use a sourceURL for easier debugging.
       
  6301       // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
       
  6302       var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
       
  6303 
       
  6304       try {
       
  6305         var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
       
  6306       } catch(e) {
       
  6307         e.source = source;
       
  6308         throw e;
       
  6309       }
       
  6310       if (data) {
       
  6311         return result(data);
       
  6312       }
       
  6313       // provide the compiled function's source by its `toString` method, in
       
  6314       // supported environments, or the `source` property as a convenience for
       
  6315       // inlining compiled templates during the build process
       
  6316       result.source = source;
       
  6317       return result;
       
  6318     }
       
  6319 
       
  6320     /**
       
  6321      * Executes the callback `n` times, returning an array of the results
       
  6322      * of each callback execution. The callback is bound to `thisArg` and invoked
       
  6323      * with one argument; (index).
       
  6324      *
       
  6325      * @static
       
  6326      * @memberOf _
       
  6327      * @category Utilities
       
  6328      * @param {number} n The number of times to execute the callback.
       
  6329      * @param {Function} callback The function called per iteration.
       
  6330      * @param {*} [thisArg] The `this` binding of `callback`.
       
  6331      * @returns {Array} Returns an array of the results of each `callback` execution.
       
  6332      * @example
       
  6333      *
       
  6334      * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
       
  6335      * // => [3, 6, 4]
       
  6336      *
       
  6337      * _.times(3, function(n) { mage.castSpell(n); });
       
  6338      * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
       
  6339      *
       
  6340      * _.times(3, function(n) { this.cast(n); }, mage);
       
  6341      * // => also calls `mage.castSpell(n)` three times
       
  6342      */
       
  6343     function times(n, callback, thisArg) {
       
  6344       n = (n = +n) > -1 ? n : 0;
       
  6345       var index = -1,
       
  6346           result = Array(n);
       
  6347 
       
  6348       callback = baseCreateCallback(callback, thisArg, 1);
       
  6349       while (++index < n) {
       
  6350         result[index] = callback(index);
       
  6351       }
       
  6352       return result;
       
  6353     }
       
  6354 
       
  6355     /**
       
  6356      * The inverse of `_.escape` this method converts the HTML entities
       
  6357      * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to their
       
  6358      * corresponding characters.
       
  6359      *
       
  6360      * @static
       
  6361      * @memberOf _
       
  6362      * @category Utilities
       
  6363      * @param {string} string The string to unescape.
       
  6364      * @returns {string} Returns the unescaped string.
       
  6365      * @example
       
  6366      *
       
  6367      * _.unescape('Fred, Barney &amp; Pebbles');
       
  6368      * // => 'Fred, Barney & Pebbles'
       
  6369      */
       
  6370     function unescape(string) {
       
  6371       return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
       
  6372     }
       
  6373 
       
  6374     /**
       
  6375      * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
       
  6376      *
       
  6377      * @static
       
  6378      * @memberOf _
       
  6379      * @category Utilities
       
  6380      * @param {string} [prefix] The value to prefix the ID with.
       
  6381      * @returns {string} Returns the unique ID.
       
  6382      * @example
       
  6383      *
       
  6384      * _.uniqueId('contact_');
       
  6385      * // => 'contact_104'
       
  6386      *
       
  6387      * _.uniqueId();
       
  6388      * // => '105'
       
  6389      */
       
  6390     function uniqueId(prefix) {
       
  6391       var id = ++idCounter;
       
  6392       return String(prefix == null ? '' : prefix) + id;
       
  6393     }
       
  6394 
       
  6395     /*--------------------------------------------------------------------------*/
       
  6396 
       
  6397     /**
       
  6398      * Creates a `lodash` object that wraps the given value with explicit
       
  6399      * method chaining enabled.
       
  6400      *
       
  6401      * @static
       
  6402      * @memberOf _
       
  6403      * @category Chaining
       
  6404      * @param {*} value The value to wrap.
       
  6405      * @returns {Object} Returns the wrapper object.
       
  6406      * @example
       
  6407      *
       
  6408      * var characters = [
       
  6409      *   { 'name': 'barney',  'age': 36 },
       
  6410      *   { 'name': 'fred',    'age': 40 },
       
  6411      *   { 'name': 'pebbles', 'age': 1 }
       
  6412      * ];
       
  6413      *
       
  6414      * var youngest = _.chain(characters)
       
  6415      *     .sortBy('age')
       
  6416      *     .map(function(chr) { return chr.name + ' is ' + chr.age; })
       
  6417      *     .first()
       
  6418      *     .value();
       
  6419      * // => 'pebbles is 1'
       
  6420      */
       
  6421     function chain(value) {
       
  6422       value = new lodashWrapper(value);
       
  6423       value.__chain__ = true;
       
  6424       return value;
       
  6425     }
       
  6426 
       
  6427     /**
       
  6428      * Invokes `interceptor` with the `value` as the first argument and then
       
  6429      * returns `value`. The purpose of this method is to "tap into" a method
       
  6430      * chain in order to perform operations on intermediate results within
       
  6431      * the chain.
       
  6432      *
       
  6433      * @static
       
  6434      * @memberOf _
       
  6435      * @category Chaining
       
  6436      * @param {*} value The value to provide to `interceptor`.
       
  6437      * @param {Function} interceptor The function to invoke.
       
  6438      * @returns {*} Returns `value`.
       
  6439      * @example
       
  6440      *
       
  6441      * _([1, 2, 3, 4])
       
  6442      *  .tap(function(array) { array.pop(); })
       
  6443      *  .reverse()
       
  6444      *  .value();
       
  6445      * // => [3, 2, 1]
       
  6446      */
       
  6447     function tap(value, interceptor) {
       
  6448       interceptor(value);
       
  6449       return value;
       
  6450     }
       
  6451 
       
  6452     /**
       
  6453      * Enables explicit method chaining on the wrapper object.
       
  6454      *
       
  6455      * @name chain
       
  6456      * @memberOf _
       
  6457      * @category Chaining
       
  6458      * @returns {*} Returns the wrapper object.
       
  6459      * @example
       
  6460      *
       
  6461      * var characters = [
       
  6462      *   { 'name': 'barney', 'age': 36 },
       
  6463      *   { 'name': 'fred',   'age': 40 }
       
  6464      * ];
       
  6465      *
       
  6466      * // without explicit chaining
       
  6467      * _(characters).first();
       
  6468      * // => { 'name': 'barney', 'age': 36 }
       
  6469      *
       
  6470      * // with explicit chaining
       
  6471      * _(characters).chain()
       
  6472      *   .first()
       
  6473      *   .pick('age')
       
  6474      *   .value();
       
  6475      * // => { 'age': 36 }
       
  6476      */
       
  6477     function wrapperChain() {
       
  6478       this.__chain__ = true;
       
  6479       return this;
       
  6480     }
       
  6481 
       
  6482     /**
       
  6483      * Produces the `toString` result of the wrapped value.
       
  6484      *
       
  6485      * @name toString
       
  6486      * @memberOf _
       
  6487      * @category Chaining
       
  6488      * @returns {string} Returns the string result.
       
  6489      * @example
       
  6490      *
       
  6491      * _([1, 2, 3]).toString();
       
  6492      * // => '1,2,3'
       
  6493      */
       
  6494     function wrapperToString() {
       
  6495       return String(this.__wrapped__);
       
  6496     }
       
  6497 
       
  6498     /**
       
  6499      * Extracts the wrapped value.
       
  6500      *
       
  6501      * @name valueOf
       
  6502      * @memberOf _
       
  6503      * @alias value
       
  6504      * @category Chaining
       
  6505      * @returns {*} Returns the wrapped value.
       
  6506      * @example
       
  6507      *
       
  6508      * _([1, 2, 3]).valueOf();
       
  6509      * // => [1, 2, 3]
       
  6510      */
       
  6511     function wrapperValueOf() {
       
  6512       return this.__wrapped__;
       
  6513     }
       
  6514 
       
  6515     /*--------------------------------------------------------------------------*/
       
  6516 
       
  6517     // add functions that return wrapped values when chaining
       
  6518     lodash.after = after;
       
  6519     lodash.assign = assign;
       
  6520     lodash.at = at;
       
  6521     lodash.bind = bind;
       
  6522     lodash.bindAll = bindAll;
       
  6523     lodash.bindKey = bindKey;
       
  6524     lodash.chain = chain;
       
  6525     lodash.compact = compact;
       
  6526     lodash.compose = compose;
       
  6527     lodash.constant = constant;
       
  6528     lodash.countBy = countBy;
       
  6529     lodash.create = create;
       
  6530     lodash.createCallback = createCallback;
       
  6531     lodash.curry = curry;
       
  6532     lodash.debounce = debounce;
       
  6533     lodash.defaults = defaults;
       
  6534     lodash.defer = defer;
       
  6535     lodash.delay = delay;
       
  6536     lodash.difference = difference;
       
  6537     lodash.filter = filter;
       
  6538     lodash.flatten = flatten;
       
  6539     lodash.forEach = forEach;
       
  6540     lodash.forEachRight = forEachRight;
       
  6541     lodash.forIn = forIn;
       
  6542     lodash.forInRight = forInRight;
       
  6543     lodash.forOwn = forOwn;
       
  6544     lodash.forOwnRight = forOwnRight;
       
  6545     lodash.functions = functions;
       
  6546     lodash.groupBy = groupBy;
       
  6547     lodash.indexBy = indexBy;
       
  6548     lodash.initial = initial;
       
  6549     lodash.intersection = intersection;
       
  6550     lodash.invert = invert;
       
  6551     lodash.invoke = invoke;
       
  6552     lodash.keys = keys;
       
  6553     lodash.map = map;
       
  6554     lodash.mapValues = mapValues;
       
  6555     lodash.max = max;
       
  6556     lodash.memoize = memoize;
       
  6557     lodash.merge = merge;
       
  6558     lodash.min = min;
       
  6559     lodash.omit = omit;
       
  6560     lodash.once = once;
       
  6561     lodash.pairs = pairs;
       
  6562     lodash.partial = partial;
       
  6563     lodash.partialRight = partialRight;
       
  6564     lodash.pick = pick;
       
  6565     lodash.pluck = pluck;
       
  6566     lodash.property = property;
       
  6567     lodash.pull = pull;
       
  6568     lodash.range = range;
       
  6569     lodash.reject = reject;
       
  6570     lodash.remove = remove;
       
  6571     lodash.rest = rest;
       
  6572     lodash.shuffle = shuffle;
       
  6573     lodash.sortBy = sortBy;
       
  6574     lodash.tap = tap;
       
  6575     lodash.throttle = throttle;
       
  6576     lodash.times = times;
       
  6577     lodash.toArray = toArray;
       
  6578     lodash.transform = transform;
       
  6579     lodash.union = union;
       
  6580     lodash.uniq = uniq;
       
  6581     lodash.values = values;
       
  6582     lodash.where = where;
       
  6583     lodash.without = without;
       
  6584     lodash.wrap = wrap;
       
  6585     lodash.xor = xor;
       
  6586     lodash.zip = zip;
       
  6587     lodash.zipObject = zipObject;
       
  6588 
       
  6589     // add aliases
       
  6590     lodash.collect = map;
       
  6591     lodash.drop = rest;
       
  6592     lodash.each = forEach;
       
  6593     lodash.eachRight = forEachRight;
       
  6594     lodash.extend = assign;
       
  6595     lodash.methods = functions;
       
  6596     lodash.object = zipObject;
       
  6597     lodash.select = filter;
       
  6598     lodash.tail = rest;
       
  6599     lodash.unique = uniq;
       
  6600     lodash.unzip = zip;
       
  6601 
       
  6602     // add functions to `lodash.prototype`
       
  6603     mixin(lodash);
       
  6604 
       
  6605     /*--------------------------------------------------------------------------*/
       
  6606 
       
  6607     // add functions that return unwrapped values when chaining
       
  6608     lodash.clone = clone;
       
  6609     lodash.cloneDeep = cloneDeep;
       
  6610     lodash.contains = contains;
       
  6611     lodash.escape = escape;
       
  6612     lodash.every = every;
       
  6613     lodash.find = find;
       
  6614     lodash.findIndex = findIndex;
       
  6615     lodash.findKey = findKey;
       
  6616     lodash.findLast = findLast;
       
  6617     lodash.findLastIndex = findLastIndex;
       
  6618     lodash.findLastKey = findLastKey;
       
  6619     lodash.has = has;
       
  6620     lodash.identity = identity;
       
  6621     lodash.indexOf = indexOf;
       
  6622     lodash.isArguments = isArguments;
       
  6623     lodash.isArray = isArray;
       
  6624     lodash.isBoolean = isBoolean;
       
  6625     lodash.isDate = isDate;
       
  6626     lodash.isElement = isElement;
       
  6627     lodash.isEmpty = isEmpty;
       
  6628     lodash.isEqual = isEqual;
       
  6629     lodash.isFinite = isFinite;
       
  6630     lodash.isFunction = isFunction;
       
  6631     lodash.isNaN = isNaN;
       
  6632     lodash.isNull = isNull;
       
  6633     lodash.isNumber = isNumber;
       
  6634     lodash.isObject = isObject;
       
  6635     lodash.isPlainObject = isPlainObject;
       
  6636     lodash.isRegExp = isRegExp;
       
  6637     lodash.isString = isString;
       
  6638     lodash.isUndefined = isUndefined;
       
  6639     lodash.lastIndexOf = lastIndexOf;
       
  6640     lodash.mixin = mixin;
       
  6641     lodash.noConflict = noConflict;
       
  6642     lodash.noop = noop;
       
  6643     lodash.now = now;
       
  6644     lodash.parseInt = parseInt;
       
  6645     lodash.random = random;
       
  6646     lodash.reduce = reduce;
       
  6647     lodash.reduceRight = reduceRight;
       
  6648     lodash.result = result;
       
  6649     lodash.runInContext = runInContext;
       
  6650     lodash.size = size;
       
  6651     lodash.some = some;
       
  6652     lodash.sortedIndex = sortedIndex;
       
  6653     lodash.template = template;
       
  6654     lodash.unescape = unescape;
       
  6655     lodash.uniqueId = uniqueId;
       
  6656 
       
  6657     // add aliases
       
  6658     lodash.all = every;
       
  6659     lodash.any = some;
       
  6660     lodash.detect = find;
       
  6661     lodash.findWhere = find;
       
  6662     lodash.foldl = reduce;
       
  6663     lodash.foldr = reduceRight;
       
  6664     lodash.include = contains;
       
  6665     lodash.inject = reduce;
       
  6666 
       
  6667     mixin(function() {
       
  6668       var source = {}
       
  6669       forOwn(lodash, function(func, methodName) {
       
  6670         if (!lodash.prototype[methodName]) {
       
  6671           source[methodName] = func;
       
  6672         }
       
  6673       });
       
  6674       return source;
       
  6675     }(), false);
       
  6676 
       
  6677     /*--------------------------------------------------------------------------*/
       
  6678 
       
  6679     // add functions capable of returning wrapped and unwrapped values when chaining
       
  6680     lodash.first = first;
       
  6681     lodash.last = last;
       
  6682     lodash.sample = sample;
       
  6683 
       
  6684     // add aliases
       
  6685     lodash.take = first;
       
  6686     lodash.head = first;
       
  6687 
       
  6688     forOwn(lodash, function(func, methodName) {
       
  6689       var callbackable = methodName !== 'sample';
       
  6690       if (!lodash.prototype[methodName]) {
       
  6691         lodash.prototype[methodName]= function(n, guard) {
       
  6692           var chainAll = this.__chain__,
       
  6693               result = func(this.__wrapped__, n, guard);
       
  6694 
       
  6695           return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function')))
       
  6696             ? result
       
  6697             : new lodashWrapper(result, chainAll);
       
  6698         };
       
  6699       }
       
  6700     });
       
  6701 
       
  6702     /*--------------------------------------------------------------------------*/
       
  6703 
       
  6704     /**
       
  6705      * The semantic version number.
       
  6706      *
       
  6707      * @static
       
  6708      * @memberOf _
       
  6709      * @type string
       
  6710      */
       
  6711     lodash.VERSION = '2.4.1';
       
  6712 
       
  6713     // add "Chaining" functions to the wrapper
       
  6714     lodash.prototype.chain = wrapperChain;
       
  6715     lodash.prototype.toString = wrapperToString;
       
  6716     lodash.prototype.value = wrapperValueOf;
       
  6717     lodash.prototype.valueOf = wrapperValueOf;
       
  6718 
       
  6719     // add `Array` functions that return unwrapped values
       
  6720     forEach(['join', 'pop', 'shift'], function(methodName) {
       
  6721       var func = arrayRef[methodName];
       
  6722       lodash.prototype[methodName] = function() {
       
  6723         var chainAll = this.__chain__,
       
  6724             result = func.apply(this.__wrapped__, arguments);
       
  6725 
       
  6726         return chainAll
       
  6727           ? new lodashWrapper(result, chainAll)
       
  6728           : result;
       
  6729       };
       
  6730     });
       
  6731 
       
  6732     // add `Array` functions that return the existing wrapped value
       
  6733     forEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
       
  6734       var func = arrayRef[methodName];
       
  6735       lodash.prototype[methodName] = function() {
       
  6736         func.apply(this.__wrapped__, arguments);
       
  6737         return this;
       
  6738       };
       
  6739     });
       
  6740 
       
  6741     // add `Array` functions that return new wrapped values
       
  6742     forEach(['concat', 'slice', 'splice'], function(methodName) {
       
  6743       var func = arrayRef[methodName];
       
  6744       lodash.prototype[methodName] = function() {
       
  6745         return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
       
  6746       };
       
  6747     });
       
  6748 
       
  6749     return lodash;
       
  6750   }
       
  6751 
       
  6752   /*--------------------------------------------------------------------------*/
       
  6753 
       
  6754   // expose Lo-Dash
       
  6755   var _ = runInContext();
       
  6756 
       
  6757   // some AMD build optimizers like r.js check for condition patterns like the following:
       
  6758   if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
       
  6759     // Expose Lo-Dash to the global object even when an AMD loader is present in
       
  6760     // case Lo-Dash is loaded with a RequireJS shim config.
       
  6761     // See http://requirejs.org/docs/api.html#config-shim
       
  6762     root._ = _;
       
  6763 
       
  6764     // define as an anonymous module so, through path mapping, it can be
       
  6765     // referenced as the "underscore" module
       
  6766     define(function() {
       
  6767       return _;
       
  6768     });
       
  6769   }
       
  6770   // check for `exports` after `define` in case a build optimizer adds an `exports` object
       
  6771   else if (freeExports && freeModule) {
       
  6772     // in Node.js or RingoJS
       
  6773     if (moduleExports) {
       
  6774       (freeModule.exports = _)._ = _;
       
  6775     }
       
  6776     // in Narwhal or Rhino -require
       
  6777     else {
       
  6778       freeExports._ = _;
       
  6779     }
       
  6780   }
       
  6781   else {
       
  6782     // in a browser or Rhino
       
  6783     root._ = _;
       
  6784   }
       
  6785 }.call(this));