Initial commit
[yaffs-website] / node_modules / lodash / dist / lodash.js
1 /**
2  * @license
3  * Lo-Dash 1.0.2 (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.4.4 <http://underscorejs.org/>
7  * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
8  * Available under MIT license <http://lodash.com/license>
9  */
10 ;(function(window, undefined) {
11
12   /** Detect free variable `exports` */
13   var freeExports = typeof exports == 'object' && exports;
14
15   /** Detect free variable `module` */
16   var freeModule = typeof module == 'object' && module && module.exports == freeExports && module;
17
18   /** Detect free variable `global` and use it as `window` */
19   var freeGlobal = typeof global == 'object' && global;
20   if (freeGlobal.global === freeGlobal) {
21     window = freeGlobal;
22   }
23
24   /** Used for array and object method references */
25   var arrayRef = [],
26       objectRef = {};
27
28   /** Used to generate unique IDs */
29   var idCounter = 0;
30
31   /** Used internally to indicate various things */
32   var indicatorObject = objectRef;
33
34   /** Used by `cachedContains` as the default size when optimizations are enabled for large arrays */
35   var largeArraySize = 30;
36
37   /** Used to restore the original `_` reference in `noConflict` */
38   var oldDash = window._;
39
40   /** Used to match HTML entities */
41   var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
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   /** Used to match regexp flags from their coerced string values */
49   var reFlags = /\w*$/;
50
51   /** Used to detect if a method is native */
52   var reNative = RegExp('^' +
53     (objectRef.valueOf + '')
54       .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
55       .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
56   );
57
58   /**
59    * Used to match ES6 template delimiters
60    * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
61    */
62   var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
63
64   /** Used to match "interpolate" template delimiters */
65   var reInterpolate = /<%=([\s\S]+?)%>/g;
66
67   /** Used to ensure capturing order of template delimiters */
68   var reNoMatch = /($^)/;
69
70   /** Used to match HTML characters */
71   var reUnescapedHtml = /[&<>"']/g;
72
73   /** Used to match unescaped characters in compiled string literals */
74   var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
75
76   /** Used to make template sourceURLs easier to identify */
77   var templateCounter = 0;
78
79   /** Native method shortcuts */
80   var ceil = Math.ceil,
81       concat = arrayRef.concat,
82       floor = Math.floor,
83       getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
84       hasOwnProperty = objectRef.hasOwnProperty,
85       push = arrayRef.push,
86       toString = objectRef.toString;
87
88   /* Native method shortcuts for methods with the same name as other `lodash` methods */
89   var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind,
90       nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
91       nativeIsFinite = window.isFinite,
92       nativeIsNaN = window.isNaN,
93       nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
94       nativeMax = Math.max,
95       nativeMin = Math.min,
96       nativeRandom = Math.random;
97
98   /** `Object#toString` result shortcuts */
99   var argsClass = '[object Arguments]',
100       arrayClass = '[object Array]',
101       boolClass = '[object Boolean]',
102       dateClass = '[object Date]',
103       funcClass = '[object Function]',
104       numberClass = '[object Number]',
105       objectClass = '[object Object]',
106       regexpClass = '[object RegExp]',
107       stringClass = '[object String]';
108
109   /** Detect various environments */
110   var isIeOpera = !!window.attachEvent,
111       isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
112
113   /* Detect if `Function#bind` exists and is inferred to be fast (all but V8) */
114   var isBindFast = nativeBind && !isV8;
115
116   /* Detect if `Object.keys` exists and is inferred to be fast (IE, Opera, V8) */
117   var isKeysFast = nativeKeys && (isIeOpera || isV8);
118
119   /** Used to identify object classifications that `_.clone` supports */
120   var cloneableClasses = {};
121   cloneableClasses[funcClass] = false;
122   cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
123   cloneableClasses[boolClass] = cloneableClasses[dateClass] =
124   cloneableClasses[numberClass] = cloneableClasses[objectClass] =
125   cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
126
127   /** Used to lookup a built-in constructor by [[Class]] */
128   var ctorByClass = {};
129   ctorByClass[arrayClass] = Array;
130   ctorByClass[boolClass] = Boolean;
131   ctorByClass[dateClass] = Date;
132   ctorByClass[objectClass] = Object;
133   ctorByClass[numberClass] = Number;
134   ctorByClass[regexpClass] = RegExp;
135   ctorByClass[stringClass] = String;
136
137   /** Used to determine if values are of the language type Object */
138   var objectTypes = {
139     'boolean': false,
140     'function': true,
141     'object': true,
142     'number': false,
143     'string': false,
144     'undefined': false
145   };
146
147   /** Used to escape characters for inclusion in compiled string literals */
148   var stringEscapes = {
149     '\\': '\\',
150     "'": "'",
151     '\n': 'n',
152     '\r': 'r',
153     '\t': 't',
154     '\u2028': 'u2028',
155     '\u2029': 'u2029'
156   };
157
158   /*--------------------------------------------------------------------------*/
159
160   /**
161    * Creates a `lodash` object, that wraps the given `value`, to enable method
162    * chaining.
163    *
164    * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
165    * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
166    * and `unshift`
167    *
168    * The chainable wrapper functions are:
169    * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, `compose`,
170    * `concat`, `countBy`, `debounce`, `defaults`, `defer`, `delay`, `difference`,
171    * `filter`, `flatten`, `forEach`, `forIn`, `forOwn`, `functions`, `groupBy`,
172    * `initial`, `intersection`, `invert`, `invoke`, `keys`, `map`, `max`, `memoize`,
173    * `merge`, `min`, `object`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
174    * `pick`, `pluck`, `push`, `range`, `reject`, `rest`, `reverse`, `shuffle`,
175    * `slice`, `sort`, `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`,
176    * `union`, `uniq`, `unshift`, `values`, `where`, `without`, `wrap`, and `zip`
177    *
178    * The non-chainable wrapper functions are:
179    * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, `identity`,
180    * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`,
181    * `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, `isObject`,
182    * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, `lastIndexOf`,
183    * `mixin`, `noConflict`, `pop`, `random`, `reduce`, `reduceRight`, `result`,
184    * `shift`, `size`, `some`, `sortedIndex`, `template`, `unescape`, and `uniqueId`
185    *
186    * The wrapper functions `first` and `last` return wrapped values when `n` is
187    * passed, otherwise they return unwrapped values.
188    *
189    * @name _
190    * @constructor
191    * @category Chaining
192    * @param {Mixed} value The value to wrap in a `lodash` instance.
193    * @returns {Object} Returns a `lodash` instance.
194    */
195   function lodash(value) {
196     // exit early if already wrapped, even if wrapped by a different `lodash` constructor
197     if (value && typeof value == 'object' && value.__wrapped__) {
198       return value;
199     }
200     // allow invoking `lodash` without the `new` operator
201     if (!(this instanceof lodash)) {
202       return new lodash(value);
203     }
204     this.__wrapped__ = value;
205   }
206
207   /**
208    * By default, the template delimiters used by Lo-Dash are similar to those in
209    * embedded Ruby (ERB). Change the following template settings to use alternative
210    * delimiters.
211    *
212    * @static
213    * @memberOf _
214    * @type Object
215    */
216   lodash.templateSettings = {
217
218     /**
219      * Used to detect `data` property values to be HTML-escaped.
220      *
221      * @memberOf _.templateSettings
222      * @type RegExp
223      */
224     'escape': /<%-([\s\S]+?)%>/g,
225
226     /**
227      * Used to detect code to be evaluated.
228      *
229      * @memberOf _.templateSettings
230      * @type RegExp
231      */
232     'evaluate': /<%([\s\S]+?)%>/g,
233
234     /**
235      * Used to detect `data` property values to inject.
236      *
237      * @memberOf _.templateSettings
238      * @type RegExp
239      */
240     'interpolate': reInterpolate,
241
242     /**
243      * Used to reference the data object in the template text.
244      *
245      * @memberOf _.templateSettings
246      * @type String
247      */
248     'variable': '',
249
250     /**
251      * Used to import variables into the compiled template.
252      *
253      * @memberOf _.templateSettings
254      * @type Object
255      */
256     'imports': {
257
258       /**
259        * A reference to the `lodash` function.
260        *
261        * @memberOf _.templateSettings.imports
262        * @type Function
263        */
264       '_': lodash
265     }
266   };
267
268   /*--------------------------------------------------------------------------*/
269
270   /**
271    * The template used to create iterator functions.
272    *
273    * @private
274    * @param {Obect} data The data object used to populate the text.
275    * @returns {String} Returns the interpolated text.
276    */
277   var iteratorTemplate = function(obj) {
278     
279     var __p = 'var index, iterable = ' +
280     (obj.firstArg ) +
281     ', result = iterable;\nif (!iterable) return result;\n' +
282     (obj.top ) +
283     ';\n';
284      if (obj.arrays) {
285     __p += 'var length = iterable.length; index = -1;\nif (' +
286     (obj.arrays ) +
287     ') {\n  while (++index < length) {\n    ' +
288     (obj.loop ) +
289     '\n  }\n}\nelse {  ';
290      } ;
291     
292      if (obj.isKeysFast && obj.useHas) {
293     __p += '\n  var ownIndex = -1,\n      ownProps = objectTypes[typeof iterable] ? nativeKeys(iterable) : [],\n      length = ownProps.length;\n\n  while (++ownIndex < length) {\n    index = ownProps[ownIndex];\n    ' +
294     (obj.loop ) +
295     '\n  }  ';
296      } else {
297     __p += '\n  for (index in iterable) {';
298         if (obj.useHas) {
299     __p += '\n    if (';
300           if (obj.useHas) {
301     __p += 'hasOwnProperty.call(iterable, index)';
302      }    ;
303     __p += ') {    ';
304      } ;
305     __p += 
306     (obj.loop ) +
307     ';    ';
308      if (obj.useHas) {
309     __p += '\n    }';
310      } ;
311     __p += '\n  }  ';
312      } ;
313     
314      if (obj.arrays) {
315     __p += '\n}';
316      } ;
317     __p += 
318     (obj.bottom ) +
319     ';\nreturn result';
320     
321     
322     return __p
323   };
324
325   /** Reusable iterator options for `assign` and `defaults` */
326   var defaultsIteratorOptions = {
327     'args': 'object, source, guard',
328     'top':
329       'var args = arguments,\n' +
330       '    argsIndex = 0,\n' +
331       "    argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
332       'while (++argsIndex < argsLength) {\n' +
333       '  iterable = args[argsIndex];\n' +
334       '  if (iterable && objectTypes[typeof iterable]) {',
335     'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
336     'bottom': '  }\n}'
337   };
338
339   /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
340   var eachIteratorOptions = {
341     'args': 'collection, callback, thisArg',
342     'top': "callback = callback && typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg)",
343     'arrays': "typeof length == 'number'",
344     'loop': 'if (callback(iterable[index], index, collection) === false) return result'
345   };
346
347   /** Reusable iterator options for `forIn` and `forOwn` */
348   var forOwnIteratorOptions = {
349     'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
350     'arrays': false
351   };
352
353   /*--------------------------------------------------------------------------*/
354
355   /**
356    * Creates a function optimized to search large arrays for a given `value`,
357    * starting at `fromIndex`, using strict equality for comparisons, i.e. `===`.
358    *
359    * @private
360    * @param {Array} array The array to search.
361    * @param {Mixed} value The value to search for.
362    * @param {Number} [fromIndex=0] The index to search from.
363    * @param {Number} [largeSize=30] The length at which an array is considered large.
364    * @returns {Boolean} Returns `true`, if `value` is found, else `false`.
365    */
366   function cachedContains(array, fromIndex, largeSize) {
367     fromIndex || (fromIndex = 0);
368
369     var length = array.length,
370         isLarge = (length - fromIndex) >= (largeSize || largeArraySize);
371
372     if (isLarge) {
373       var cache = {},
374           index = fromIndex - 1;
375
376       while (++index < length) {
377         // manually coerce `value` to a string because `hasOwnProperty`, in some
378         // older versions of Firefox, coerces objects incorrectly
379         var key = array[index] + '';
380         (hasOwnProperty.call(cache, key) ? cache[key] : (cache[key] = [])).push(array[index]);
381       }
382     }
383     return function(value) {
384       if (isLarge) {
385         var key = value + '';
386         return hasOwnProperty.call(cache, key) && indexOf(cache[key], value) > -1;
387       }
388       return indexOf(array, value, fromIndex) > -1;
389     }
390   }
391
392   /**
393    * Used by `_.max` and `_.min` as the default `callback` when a given
394    * `collection` is a string value.
395    *
396    * @private
397    * @param {String} value The character to inspect.
398    * @returns {Number} Returns the code unit of given character.
399    */
400   function charAtCallback(value) {
401     return value.charCodeAt(0);
402   }
403
404   /**
405    * Used by `sortBy` to compare transformed `collection` values, stable sorting
406    * them in ascending order.
407    *
408    * @private
409    * @param {Object} a The object to compare to `b`.
410    * @param {Object} b The object to compare to `a`.
411    * @returns {Number} Returns the sort order indicator of `1` or `-1`.
412    */
413   function compareAscending(a, b) {
414     var ai = a.index,
415         bi = b.index;
416
417     a = a.criteria;
418     b = b.criteria;
419
420     // ensure a stable sort in V8 and other engines
421     // http://code.google.com/p/v8/issues/detail?id=90
422     if (a !== b) {
423       if (a > b || typeof a == 'undefined') {
424         return 1;
425       }
426       if (a < b || typeof b == 'undefined') {
427         return -1;
428       }
429     }
430     return ai < bi ? -1 : 1;
431   }
432
433   /**
434    * Creates a function that, when called, invokes `func` with the `this` binding
435    * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
436    * bound function.
437    *
438    * @private
439    * @param {Function|String} func The function to bind or the method name.
440    * @param {Mixed} [thisArg] The `this` binding of `func`.
441    * @param {Array} partialArgs An array of arguments to be partially applied.
442    * @param {Object} [rightIndicator] Used to indicate partially applying arguments from the right.
443    * @returns {Function} Returns the new bound function.
444    */
445   function createBound(func, thisArg, partialArgs, rightIndicator) {
446     var isFunc = isFunction(func),
447         isPartial = !partialArgs,
448         key = thisArg;
449
450     // juggle arguments
451     if (isPartial) {
452       partialArgs = thisArg;
453     }
454     if (!isFunc) {
455       thisArg = func;
456     }
457
458     function bound() {
459       // `Function#bind` spec
460       // http://es5.github.com/#x15.3.4.5
461       var args = arguments,
462           thisBinding = isPartial ? this : thisArg;
463
464       if (!isFunc) {
465         func = thisArg[key];
466       }
467       if (partialArgs.length) {
468         args = args.length
469           ? (args = slice(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args))
470           : partialArgs;
471       }
472       if (this instanceof bound) {
473         // ensure `new bound` is an instance of `bound` and `func`
474         noop.prototype = func.prototype;
475         thisBinding = new noop;
476         noop.prototype = null;
477
478         // mimic the constructor's `return` behavior
479         // http://es5.github.com/#x13.2.2
480         var result = func.apply(thisBinding, args);
481         return isObject(result) ? result : thisBinding;
482       }
483       return func.apply(thisBinding, args);
484     }
485     return bound;
486   }
487
488   /**
489    * Produces a callback bound to an optional `thisArg`. If `func` is a property
490    * name, the created callback will return the property value for a given element.
491    * If `func` is an object, the created callback will return `true` for elements
492    * that contain the equivalent object properties, otherwise it will return `false`.
493    *
494    * @private
495    * @param {Mixed} [func=identity] The value to convert to a callback.
496    * @param {Mixed} [thisArg] The `this` binding of the created callback.
497    * @param {Number} [argCount=3] The number of arguments the callback accepts.
498    * @returns {Function} Returns a callback function.
499    */
500   function createCallback(func, thisArg, argCount) {
501     if (func == null) {
502       return identity;
503     }
504     var type = typeof func;
505     if (type != 'function') {
506       if (type != 'object') {
507         return function(object) {
508           return object[func];
509         };
510       }
511       var props = keys(func);
512       return function(object) {
513         var length = props.length,
514             result = false;
515         while (length--) {
516           if (!(result = isEqual(object[props[length]], func[props[length]], indicatorObject))) {
517             break;
518           }
519         }
520         return result;
521       };
522     }
523     if (typeof thisArg != 'undefined') {
524       if (argCount === 1) {
525         return function(value) {
526           return func.call(thisArg, value);
527         };
528       }
529       if (argCount === 2) {
530         return function(a, b) {
531           return func.call(thisArg, a, b);
532         };
533       }
534       if (argCount === 4) {
535         return function(accumulator, value, index, object) {
536           return func.call(thisArg, accumulator, value, index, object);
537         };
538       }
539       return function(value, index, object) {
540         return func.call(thisArg, value, index, object);
541       };
542     }
543     return func;
544   }
545
546   /**
547    * Creates compiled iteration functions.
548    *
549    * @private
550    * @param {Object} [options1, options2, ...] The compile options object(s).
551    *  arrays - A string of code to determine if the iterable is an array or array-like.
552    *  useHas - A boolean to specify using `hasOwnProperty` checks in the object loop.
553    *  args - A string of comma separated arguments the iteration function will accept.
554    *  top - A string of code to execute before the iteration branches.
555    *  loop - A string of code to execute in the object loop.
556    *  bottom - A string of code to execute after the iteration branches.
557    *
558    * @returns {Function} Returns the compiled function.
559    */
560   function createIterator() {
561     var data = {
562       // support properties
563       'isKeysFast': isKeysFast,
564
565       // iterator options
566       'arrays': 'isArray(iterable)',
567       'bottom': '',
568       'loop': '',
569       'top': '',
570       'useHas': true
571     };
572
573     // merge options into a template data object
574     for (var object, index = 0; object = arguments[index]; index++) {
575       for (var key in object) {
576         data[key] = object[key];
577       }
578     }
579     var args = data.args;
580     data.firstArg = /^[^,]+/.exec(args)[0];
581
582     // create the function factory
583     var factory = Function(
584         'createCallback, hasOwnProperty, isArguments, isArray, isString, ' +
585         'objectTypes, nativeKeys',
586       'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
587     );
588     // return the compiled function
589     return factory(
590       createCallback, hasOwnProperty, isArguments, isArray, isString,
591       objectTypes, nativeKeys
592     );
593   }
594
595   /**
596    * A function compiled to iterate `arguments` objects, arrays, objects, and
597    * strings consistenly across environments, executing the `callback` for each
598    * element in the `collection`. The `callback` is bound to `thisArg` and invoked
599    * with three arguments; (value, index|key, collection). Callbacks may exit
600    * iteration early by explicitly returning `false`.
601    *
602    * @private
603    * @type Function
604    * @param {Array|Object|String} collection The collection to iterate over.
605    * @param {Function} [callback=identity] The function called per iteration.
606    * @param {Mixed} [thisArg] The `this` binding of `callback`.
607    * @returns {Array|Object|String} Returns `collection`.
608    */
609   var each = createIterator(eachIteratorOptions);
610
611   /**
612    * Used by `template` to escape characters for inclusion in compiled
613    * string literals.
614    *
615    * @private
616    * @param {String} match The matched character to escape.
617    * @returns {String} Returns the escaped character.
618    */
619   function escapeStringChar(match) {
620     return '\\' + stringEscapes[match];
621   }
622
623   /**
624    * Used by `escape` to convert characters to HTML entities.
625    *
626    * @private
627    * @param {String} match The matched character to escape.
628    * @returns {String} Returns the escaped character.
629    */
630   function escapeHtmlChar(match) {
631     return htmlEscapes[match];
632   }
633
634   /**
635    * Checks if `value` is a DOM node in IE < 9.
636    *
637    * @private
638    * @param {Mixed} value The value to check.
639    * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`.
640    */
641   function isNode(value) {
642     // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
643     // methods that are `typeof` "string" and still can coerce nodes to strings
644     return typeof value.toString != 'function' && typeof (value + '') == 'string';
645   }
646
647   /**
648    * A no-operation function.
649    *
650    * @private
651    */
652   function noop() {
653     // no operation performed
654   }
655
656   /**
657    * Slices the `collection` from the `start` index up to, but not including,
658    * the `end` index.
659    *
660    * Note: This function is used, instead of `Array#slice`, to support node lists
661    * in IE < 9 and to ensure dense arrays are returned.
662    *
663    * @private
664    * @param {Array|Object|String} collection The collection to slice.
665    * @param {Number} start The start index.
666    * @param {Number} end The end index.
667    * @returns {Array} Returns the new array.
668    */
669   function slice(array, start, end) {
670     start || (start = 0);
671     if (typeof end == 'undefined') {
672       end = array ? array.length : 0;
673     }
674     var index = -1,
675         length = end - start || 0,
676         result = Array(length < 0 ? 0 : length);
677
678     while (++index < length) {
679       result[index] = array[start + index];
680     }
681     return result;
682   }
683
684   /**
685    * Used by `unescape` to convert HTML entities to characters.
686    *
687    * @private
688    * @param {String} match The matched character to unescape.
689    * @returns {String} Returns the unescaped character.
690    */
691   function unescapeHtmlChar(match) {
692     return htmlUnescapes[match];
693   }
694
695   /*--------------------------------------------------------------------------*/
696
697   /**
698    * Checks if `value` is an `arguments` object.
699    *
700    * @static
701    * @memberOf _
702    * @category Objects
703    * @param {Mixed} value The value to check.
704    * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`.
705    * @example
706    *
707    * (function() { return _.isArguments(arguments); })(1, 2, 3);
708    * // => true
709    *
710    * _.isArguments([1, 2, 3]);
711    * // => false
712    */
713   function isArguments(value) {
714     return toString.call(value) == argsClass;
715   }
716
717   /**
718    * Iterates over `object`'s own and inherited enumerable properties, executing
719    * the `callback` for each property. The `callback` is bound to `thisArg` and
720    * invoked with three arguments; (value, key, object). Callbacks may exit iteration
721    * early by explicitly returning `false`.
722    *
723    * @static
724    * @memberOf _
725    * @type Function
726    * @category Objects
727    * @param {Object} object The object to iterate over.
728    * @param {Function} [callback=identity] The function called per iteration.
729    * @param {Mixed} [thisArg] The `this` binding of `callback`.
730    * @returns {Object} Returns `object`.
731    * @example
732    *
733    * function Dog(name) {
734    *   this.name = name;
735    * }
736    *
737    * Dog.prototype.bark = function() {
738    *   alert('Woof, woof!');
739    * };
740    *
741    * _.forIn(new Dog('Dagny'), function(value, key) {
742    *   alert(key);
743    * });
744    * // => alerts 'name' and 'bark' (order is not guaranteed)
745    */
746   var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
747     'useHas': false
748   });
749
750   /**
751    * Iterates over an object's own enumerable properties, executing the `callback`
752    * for each property. The `callback` is bound to `thisArg` and invoked with three
753    * arguments; (value, key, object). Callbacks may exit iteration early by explicitly
754    * returning `false`.
755    *
756    * @static
757    * @memberOf _
758    * @type Function
759    * @category Objects
760    * @param {Object} object The object to iterate over.
761    * @param {Function} [callback=identity] The function called per iteration.
762    * @param {Mixed} [thisArg] The `this` binding of `callback`.
763    * @returns {Object} Returns `object`.
764    * @example
765    *
766    * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
767    *   alert(key);
768    * });
769    * // => alerts '0', '1', and 'length' (order is not guaranteed)
770    */
771   var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
772
773   /**
774    * Checks if `value` is an array.
775    *
776    * @static
777    * @memberOf _
778    * @category Objects
779    * @param {Mixed} value The value to check.
780    * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`.
781    * @example
782    *
783    * (function() { return _.isArray(arguments); })();
784    * // => false
785    *
786    * _.isArray([1, 2, 3]);
787    * // => true
788    */
789   var isArray = nativeIsArray || function(value) {
790     // `instanceof` may cause a memory leak in IE 7 if `value` is a host object
791     // http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak
792     return value instanceof Array || toString.call(value) == arrayClass;
793   };
794
795   /**
796    * Creates an array composed of the own enumerable property names of `object`.
797    *
798    * @static
799    * @memberOf _
800    * @category Objects
801    * @param {Object} object The object to inspect.
802    * @returns {Array} Returns a new array of property names.
803    * @example
804    *
805    * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
806    * // => ['one', 'two', 'three'] (order is not guaranteed)
807    */
808   var keys = !nativeKeys ? shimKeys : function(object) {
809     if (!isObject(object)) {
810       return [];
811     }
812     return nativeKeys(object);
813   };
814
815   /**
816    * A fallback implementation of `isPlainObject` that checks if a given `value`
817    * is an object created by the `Object` constructor, assuming objects created
818    * by the `Object` constructor have no inherited enumerable properties and that
819    * there are no `Object.prototype` extensions.
820    *
821    * @private
822    * @param {Mixed} value The value to check.
823    * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
824    */
825   function shimIsPlainObject(value) {
826     // avoid non-objects and false positives for `arguments` objects
827     var result = false;
828     if (!(value && typeof value == 'object') || isArguments(value)) {
829       return result;
830     }
831     // check that the constructor is `Object` (i.e. `Object instanceof Object`)
832     var ctor = value.constructor;
833     if ((!isFunction(ctor)) || ctor instanceof ctor) {
834       // In most environments an object's own properties are iterated before
835       // its inherited properties. If the last iterated property is an object's
836       // own property then there are no inherited enumerable properties.
837       forIn(value, function(value, key) {
838         result = key;
839       });
840       return result === false || hasOwnProperty.call(value, result);
841     }
842     return result;
843   }
844
845   /**
846    * A fallback implementation of `Object.keys` that produces an array of the
847    * given object's own enumerable property names.
848    *
849    * @private
850    * @param {Object} object The object to inspect.
851    * @returns {Array} Returns a new array of property names.
852    */
853   function shimKeys(object) {
854     var result = [];
855     forOwn(object, function(value, key) {
856       result.push(key);
857     });
858     return result;
859   }
860
861   /**
862    * Used to convert characters to HTML entities:
863    *
864    * Though the `>` character is escaped for symmetry, characters like `>` and `/`
865    * don't require escaping in HTML and have no special meaning unless they're part
866    * of a tag or an unquoted attribute value.
867    * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
868    */
869   var htmlEscapes = {
870     '&': '&amp;',
871     '<': '&lt;',
872     '>': '&gt;',
873     '"': '&quot;',
874     "'": '&#39;'
875   };
876
877   /** Used to convert HTML entities to characters */
878   var htmlUnescapes = invert(htmlEscapes);
879
880   /*--------------------------------------------------------------------------*/
881
882   /**
883    * Assigns own enumerable properties of source object(s) to the destination
884    * object. Subsequent sources will overwrite propery assignments of previous
885    * sources. If a `callback` function is passed, it will be executed to produce
886    * the assigned values. The `callback` is bound to `thisArg` and invoked with
887    * two arguments; (objectValue, sourceValue).
888    *
889    * @static
890    * @memberOf _
891    * @type Function
892    * @alias extend
893    * @category Objects
894    * @param {Object} object The destination object.
895    * @param {Object} [source1, source2, ...] The source objects.
896    * @param {Function} [callback] The function to customize assigning values.
897    * @param {Mixed} [thisArg] The `this` binding of `callback`.
898    * @returns {Object} Returns the destination object.
899    * @example
900    *
901    * _.assign({ 'name': 'moe' }, { 'age': 40 });
902    * // => { 'name': 'moe', 'age': 40 }
903    *
904    * var defaults = _.partialRight(_.assign, function(a, b) {
905    *   return typeof a == 'undefined' ? b : a;
906    * });
907    *
908    * var food = { 'name': 'apple' };
909    * defaults(food, { 'name': 'banana', 'type': 'fruit' });
910    * // => { 'name': 'apple', 'type': 'fruit' }
911    */
912   var assign = createIterator(defaultsIteratorOptions, {
913     'top':
914       defaultsIteratorOptions.top.replace(';',
915         ';\n' +
916         "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
917         '  var callback = createCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
918         "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
919         '  callback = args[--argsLength];\n' +
920         '}'
921       ),
922     'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
923   });
924
925   /**
926    * Creates a clone of `value`. If `deep` is `true`, nested objects will also
927    * be cloned, otherwise they will be assigned by reference. If a `callback`
928    * function is passed, it will be executed to produce the cloned values. If
929    * `callback` returns `undefined`, cloning will be handled by the method instead.
930    * The `callback` is bound to `thisArg` and invoked with one argument; (value).
931    *
932    * @static
933    * @memberOf _
934    * @category Objects
935    * @param {Mixed} value The value to clone.
936    * @param {Boolean} [deep=false] A flag to indicate a deep clone.
937    * @param {Function} [callback] The function to customize cloning values.
938    * @param {Mixed} [thisArg] The `this` binding of `callback`.
939    * @param- {Array} [stackA=[]] Internally used to track traversed source objects.
940    * @param- {Array} [stackB=[]] Internally used to associate clones with source counterparts.
941    * @returns {Mixed} Returns the cloned `value`.
942    * @example
943    *
944    * var stooges = [
945    *   { 'name': 'moe', 'age': 40 },
946    *   { 'name': 'larry', 'age': 50 }
947    * ];
948    *
949    * var shallow = _.clone(stooges);
950    * shallow[0] === stooges[0];
951    * // => true
952    *
953    * var deep = _.clone(stooges, true);
954    * deep[0] === stooges[0];
955    * // => false
956    *
957    * _.mixin({
958    *   'clone': _.partialRight(_.clone, function(value) {
959    *     return _.isElement(value) ? value.cloneNode(false) : undefined;
960    *   })
961    * });
962    *
963    * var clone = _.clone(document.body);
964    * clone.childNodes.length;
965    * // => 0
966    */
967   function clone(value, deep, callback, thisArg, stackA, stackB) {
968     var result = value;
969
970     // allows working with "Collections" methods without using their `callback`
971     // argument, `index|key`, for this method's `callback`
972     if (typeof deep == 'function') {
973       thisArg = callback;
974       callback = deep;
975       deep = false;
976     }
977     if (typeof callback == 'function') {
978       callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 1);
979       result = callback(result);
980
981       var done = typeof result != 'undefined';
982       if (!done) {
983         result = value;
984       }
985     }
986     // inspect [[Class]]
987     var isObj = isObject(result);
988     if (isObj) {
989       var className = toString.call(result);
990       if (!cloneableClasses[className]) {
991         return result;
992       }
993       var isArr = isArray(result);
994     }
995     // shallow clone
996     if (!isObj || !deep) {
997       return isObj && !done
998         ? (isArr ? slice(result) : assign({}, result))
999         : result;
1000     }
1001     var ctor = ctorByClass[className];
1002     switch (className) {
1003       case boolClass:
1004       case dateClass:
1005         return done ? result : new ctor(+result);
1006
1007       case numberClass:
1008       case stringClass:
1009         return done ? result : new ctor(result);
1010
1011       case regexpClass:
1012         return done ? result : ctor(result.source, reFlags.exec(result));
1013     }
1014     // check for circular references and return corresponding clone
1015     stackA || (stackA = []);
1016     stackB || (stackB = []);
1017
1018     var length = stackA.length;
1019     while (length--) {
1020       if (stackA[length] == value) {
1021         return stackB[length];
1022       }
1023     }
1024     // init cloned object
1025     if (!done) {
1026       result = isArr ? ctor(result.length) : {};
1027
1028       // add array properties assigned by `RegExp#exec`
1029       if (isArr) {
1030         if (hasOwnProperty.call(value, 'index')) {
1031           result.index = value.index;
1032         }
1033         if (hasOwnProperty.call(value, 'input')) {
1034           result.input = value.input;
1035         }
1036       }
1037     }
1038     // add the source value to the stack of traversed objects
1039     // and associate it with its clone
1040     stackA.push(value);
1041     stackB.push(result);
1042
1043     // recursively populate clone (susceptible to call stack limits)
1044     (isArr ? forEach : forOwn)(done ? result : value, function(objValue, key) {
1045       result[key] = clone(objValue, deep, callback, undefined, stackA, stackB);
1046     });
1047
1048     return result;
1049   }
1050
1051   /**
1052    * Creates a deep clone of `value`. If a `callback` function is passed, it will
1053    * be executed to produce the cloned values. If `callback` returns the value it
1054    * was passed, cloning will be handled by the method instead. The `callback` is
1055    * bound to `thisArg` and invoked with one argument; (value).
1056    *
1057    * Note: This function is loosely based on the structured clone algorithm. Functions
1058    * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
1059    * objects created by constructors other than `Object` are cloned to plain `Object` objects.
1060    * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
1061    *
1062    * @static
1063    * @memberOf _
1064    * @category Objects
1065    * @param {Mixed} value The value to deep clone.
1066    * @param {Function} [callback] The function to customize cloning values.
1067    * @param {Mixed} [thisArg] The `this` binding of `callback`.
1068    * @returns {Mixed} Returns the deep cloned `value`.
1069    * @example
1070    *
1071    * var stooges = [
1072    *   { 'name': 'moe', 'age': 40 },
1073    *   { 'name': 'larry', 'age': 50 }
1074    * ];
1075    *
1076    * var deep = _.cloneDeep(stooges);
1077    * deep[0] === stooges[0];
1078    * // => false
1079    *
1080    * var view = {
1081    *   'label': 'docs',
1082    *   'node': element
1083    * };
1084    *
1085    * var clone = _.cloneDeep(view, function(value) {
1086    *   return _.isElement(value) ? value.cloneNode(true) : value;
1087    * });
1088    *
1089    * clone.node == view.node;
1090    * // => false
1091    */
1092   function cloneDeep(value, callback, thisArg) {
1093     return clone(value, true, callback, thisArg);
1094   }
1095
1096   /**
1097    * Assigns own enumerable properties of source object(s) to the destination
1098    * object for all destination properties that resolve to `undefined`. Once a
1099    * property is set, additional defaults of the same property will be ignored.
1100    *
1101    * @static
1102    * @memberOf _
1103    * @type Function
1104    * @category Objects
1105    * @param {Object} object The destination object.
1106    * @param {Object} [source1, source2, ...] The source objects.
1107    * @param- {Object} [guard] Internally used to allow working with `_.reduce`
1108    *  without using its callback's `key` and `object` arguments as sources.
1109    * @returns {Object} Returns the destination object.
1110    * @example
1111    *
1112    * var food = { 'name': 'apple' };
1113    * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
1114    * // => { 'name': 'apple', 'type': 'fruit' }
1115    */
1116   var defaults = createIterator(defaultsIteratorOptions);
1117
1118   /**
1119    * Creates a sorted array of all enumerable properties, own and inherited,
1120    * of `object` that have function values.
1121    *
1122    * @static
1123    * @memberOf _
1124    * @alias methods
1125    * @category Objects
1126    * @param {Object} object The object to inspect.
1127    * @returns {Array} Returns a new array of property names that have function values.
1128    * @example
1129    *
1130    * _.functions(_);
1131    * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
1132    */
1133   function functions(object) {
1134     var result = [];
1135     forIn(object, function(value, key) {
1136       if (isFunction(value)) {
1137         result.push(key);
1138       }
1139     });
1140     return result.sort();
1141   }
1142
1143   /**
1144    * Checks if the specified object `property` exists and is a direct property,
1145    * instead of an inherited property.
1146    *
1147    * @static
1148    * @memberOf _
1149    * @category Objects
1150    * @param {Object} object The object to check.
1151    * @param {String} property The property to check for.
1152    * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
1153    * @example
1154    *
1155    * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
1156    * // => true
1157    */
1158   function has(object, property) {
1159     return object ? hasOwnProperty.call(object, property) : false;
1160   }
1161
1162   /**
1163    * Creates an object composed of the inverted keys and values of the given `object`.
1164    *
1165    * @static
1166    * @memberOf _
1167    * @category Objects
1168    * @param {Object} object The object to invert.
1169    * @returns {Object} Returns the created inverted object.
1170    * @example
1171    *
1172    *  _.invert({ 'first': 'moe', 'second': 'larry' });
1173    * // => { 'moe': 'first', 'larry': 'second' } (order is not guaranteed)
1174    */
1175   function invert(object) {
1176     var index = -1,
1177         props = keys(object),
1178         length = props.length,
1179         result = {};
1180
1181     while (++index < length) {
1182       var key = props[index];
1183       result[object[key]] = key;
1184     }
1185     return result;
1186   }
1187
1188   /**
1189    * Checks if `value` is a boolean value.
1190    *
1191    * @static
1192    * @memberOf _
1193    * @category Objects
1194    * @param {Mixed} value The value to check.
1195    * @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`.
1196    * @example
1197    *
1198    * _.isBoolean(null);
1199    * // => false
1200    */
1201   function isBoolean(value) {
1202     return value === true || value === false || toString.call(value) == boolClass;
1203   }
1204
1205   /**
1206    * Checks if `value` is a date.
1207    *
1208    * @static
1209    * @memberOf _
1210    * @category Objects
1211    * @param {Mixed} value The value to check.
1212    * @returns {Boolean} Returns `true`, if the `value` is a date, else `false`.
1213    * @example
1214    *
1215    * _.isDate(new Date);
1216    * // => true
1217    */
1218   function isDate(value) {
1219     return value instanceof Date || toString.call(value) == dateClass;
1220   }
1221
1222   /**
1223    * Checks if `value` is a DOM element.
1224    *
1225    * @static
1226    * @memberOf _
1227    * @category Objects
1228    * @param {Mixed} value The value to check.
1229    * @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`.
1230    * @example
1231    *
1232    * _.isElement(document.body);
1233    * // => true
1234    */
1235   function isElement(value) {
1236     return value ? value.nodeType === 1 : false;
1237   }
1238
1239   /**
1240    * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
1241    * length of `0` and objects with no own enumerable properties are considered
1242    * "empty".
1243    *
1244    * @static
1245    * @memberOf _
1246    * @category Objects
1247    * @param {Array|Object|String} value The value to inspect.
1248    * @returns {Boolean} Returns `true`, if the `value` is empty, else `false`.
1249    * @example
1250    *
1251    * _.isEmpty([1, 2, 3]);
1252    * // => false
1253    *
1254    * _.isEmpty({});
1255    * // => true
1256    *
1257    * _.isEmpty('');
1258    * // => true
1259    */
1260   function isEmpty(value) {
1261     var result = true;
1262     if (!value) {
1263       return result;
1264     }
1265     var className = toString.call(value),
1266         length = value.length;
1267
1268     if ((className == arrayClass || className == stringClass ||
1269         className == argsClass) ||
1270         (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
1271       return !length;
1272     }
1273     forOwn(value, function() {
1274       return (result = false);
1275     });
1276     return result;
1277   }
1278
1279   /**
1280    * Performs a deep comparison between two values to determine if they are
1281    * equivalent to each other. If `callback` is passed, it will be executed to
1282    * compare values. If `callback` returns `undefined`, comparisons will be handled
1283    * by the method instead. The `callback` is bound to `thisArg` and invoked with
1284    * two arguments; (a, b).
1285    *
1286    * @static
1287    * @memberOf _
1288    * @category Objects
1289    * @param {Mixed} a The value to compare.
1290    * @param {Mixed} b The other value to compare.
1291    * @param {Function} [callback] The function to customize comparing values.
1292    * @param {Mixed} [thisArg] The `this` binding of `callback`.
1293    * @param- {Object} [stackA=[]] Internally used track traversed `a` objects.
1294    * @param- {Object} [stackB=[]] Internally used track traversed `b` objects.
1295    * @returns {Boolean} Returns `true`, if the values are equvalent, else `false`.
1296    * @example
1297    *
1298    * var moe = { 'name': 'moe', 'age': 40 };
1299    * var copy = { 'name': 'moe', 'age': 40 };
1300    *
1301    * moe == copy;
1302    * // => false
1303    *
1304    * _.isEqual(moe, copy);
1305    * // => true
1306    *
1307    * var words = ['hello', 'goodbye'];
1308    * var otherWords = ['hi', 'goodbye'];
1309    *
1310    * _.isEqual(words, otherWords, function(a, b) {
1311    *   var reGreet = /^(?:hello|hi)$/i,
1312    *       aGreet = _.isString(a) && reGreet.test(a),
1313    *       bGreet = _.isString(b) && reGreet.test(b);
1314    *
1315    *   return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
1316    * });
1317    * // => true
1318    */
1319   function isEqual(a, b, callback, thisArg, stackA, stackB) {
1320     // used to indicate that when comparing objects, `a` has at least the properties of `b`
1321     var whereIndicator = callback === indicatorObject;
1322     if (callback && !whereIndicator) {
1323       callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 2);
1324       var result = callback(a, b);
1325       if (typeof result != 'undefined') {
1326         return !!result;
1327       }
1328     }
1329     // exit early for identical values
1330     if (a === b) {
1331       // treat `+0` vs. `-0` as not equal
1332       return a !== 0 || (1 / a == 1 / b);
1333     }
1334     var type = typeof a,
1335         otherType = typeof b;
1336
1337     // exit early for unlike primitive values
1338     if (a === a &&
1339         (!a || (type != 'function' && type != 'object')) &&
1340         (!b || (otherType != 'function' && otherType != 'object'))) {
1341       return false;
1342     }
1343     // exit early for `null` and `undefined`, avoiding ES3's Function#call behavior
1344     // http://es5.github.com/#x15.3.4.4
1345     if (a == null || b == null) {
1346       return a === b;
1347     }
1348     // compare [[Class]] names
1349     var className = toString.call(a),
1350         otherClass = toString.call(b);
1351
1352     if (className == argsClass) {
1353       className = objectClass;
1354     }
1355     if (otherClass == argsClass) {
1356       otherClass = objectClass;
1357     }
1358     if (className != otherClass) {
1359       return false;
1360     }
1361     switch (className) {
1362       case boolClass:
1363       case dateClass:
1364         // coerce dates and booleans to numbers, dates to milliseconds and booleans
1365         // to `1` or `0`, treating invalid dates coerced to `NaN` as not equal
1366         return +a == +b;
1367
1368       case numberClass:
1369         // treat `NaN` vs. `NaN` as equal
1370         return a != +a
1371           ? b != +b
1372           // but treat `+0` vs. `-0` as not equal
1373           : (a == 0 ? (1 / a == 1 / b) : a == +b);
1374
1375       case regexpClass:
1376       case stringClass:
1377         // coerce regexes to strings (http://es5.github.com/#x15.10.6.4)
1378         // treat string primitives and their corresponding object instances as equal
1379         return a == b + '';
1380     }
1381     var isArr = className == arrayClass;
1382     if (!isArr) {
1383       // unwrap any `lodash` wrapped values
1384       if (a.__wrapped__ || b.__wrapped__) {
1385         return isEqual(a.__wrapped__ || a, b.__wrapped__ || b, callback, thisArg, stackA, stackB);
1386       }
1387       // exit for functions and DOM nodes
1388       if (className != objectClass) {
1389         return false;
1390       }
1391       // in older versions of Opera, `arguments` objects have `Array` constructors
1392       var ctorA = a.constructor,
1393           ctorB = b.constructor;
1394
1395       // non `Object` object instances with different constructors are not equal
1396       if (ctorA != ctorB && !(
1397             isFunction(ctorA) && ctorA instanceof ctorA &&
1398             isFunction(ctorB) && ctorB instanceof ctorB
1399           )) {
1400         return false;
1401       }
1402     }
1403     // assume cyclic structures are equal
1404     // the algorithm for detecting cyclic structures is adapted from ES 5.1
1405     // section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3)
1406     stackA || (stackA = []);
1407     stackB || (stackB = []);
1408
1409     var length = stackA.length;
1410     while (length--) {
1411       if (stackA[length] == a) {
1412         return stackB[length] == b;
1413       }
1414     }
1415     var size = 0;
1416     result = true;
1417
1418     // add `a` and `b` to the stack of traversed objects
1419     stackA.push(a);
1420     stackB.push(b);
1421
1422     // recursively compare objects and arrays (susceptible to call stack limits)
1423     if (isArr) {
1424       length = a.length;
1425       size = b.length;
1426
1427       // compare lengths to determine if a deep comparison is necessary
1428       result = size == a.length;
1429       if (!result && !whereIndicator) {
1430         return result;
1431       }
1432       // deep compare the contents, ignoring non-numeric properties
1433       while (size--) {
1434         var index = length,
1435             value = b[size];
1436
1437         if (whereIndicator) {
1438           while (index--) {
1439             if ((result = isEqual(a[index], value, callback, thisArg, stackA, stackB))) {
1440               break;
1441             }
1442           }
1443         } else if (!(result = isEqual(a[size], value, callback, thisArg, stackA, stackB))) {
1444           break;
1445         }
1446       }
1447       return result;
1448     }
1449     // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
1450     // which, in this case, is more costly
1451     forIn(b, function(value, key, b) {
1452       if (hasOwnProperty.call(b, key)) {
1453         // count the number of properties.
1454         size++;
1455         // deep compare each property value.
1456         return (result = hasOwnProperty.call(a, key) && isEqual(a[key], value, callback, thisArg, stackA, stackB));
1457       }
1458     });
1459
1460     if (result && !whereIndicator) {
1461       // ensure both objects have the same number of properties
1462       forIn(a, function(value, key, a) {
1463         if (hasOwnProperty.call(a, key)) {
1464           // `size` will be `-1` if `a` has more properties than `b`
1465           return (result = --size > -1);
1466         }
1467       });
1468     }
1469     return result;
1470   }
1471
1472   /**
1473    * Checks if `value` is, or can be coerced to, a finite number.
1474    *
1475    * Note: This is not the same as native `isFinite`, which will return true for
1476    * booleans and empty strings. See http://es5.github.com/#x15.1.2.5.
1477    *
1478    * @static
1479    * @memberOf _
1480    * @category Objects
1481    * @param {Mixed} value The value to check.
1482    * @returns {Boolean} Returns `true`, if the `value` is finite, else `false`.
1483    * @example
1484    *
1485    * _.isFinite(-101);
1486    * // => true
1487    *
1488    * _.isFinite('10');
1489    * // => true
1490    *
1491    * _.isFinite(true);
1492    * // => false
1493    *
1494    * _.isFinite('');
1495    * // => false
1496    *
1497    * _.isFinite(Infinity);
1498    * // => false
1499    */
1500   function isFinite(value) {
1501     return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
1502   }
1503
1504   /**
1505    * Checks if `value` is a function.
1506    *
1507    * @static
1508    * @memberOf _
1509    * @category Objects
1510    * @param {Mixed} value The value to check.
1511    * @returns {Boolean} Returns `true`, if the `value` is a function, else `false`.
1512    * @example
1513    *
1514    * _.isFunction(_);
1515    * // => true
1516    */
1517   function isFunction(value) {
1518     return typeof value == 'function';
1519   }
1520   // fallback for older versions of Chrome and Safari
1521   if (isFunction(/x/)) {
1522     isFunction = function(value) {
1523       return value instanceof Function || toString.call(value) == funcClass;
1524     };
1525   }
1526
1527   /**
1528    * Checks if `value` is the language type of Object.
1529    * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
1530    *
1531    * @static
1532    * @memberOf _
1533    * @category Objects
1534    * @param {Mixed} value The value to check.
1535    * @returns {Boolean} Returns `true`, if the `value` is an object, else `false`.
1536    * @example
1537    *
1538    * _.isObject({});
1539    * // => true
1540    *
1541    * _.isObject([1, 2, 3]);
1542    * // => true
1543    *
1544    * _.isObject(1);
1545    * // => false
1546    */
1547   function isObject(value) {
1548     // check if the value is the ECMAScript language type of Object
1549     // http://es5.github.com/#x8
1550     // and avoid a V8 bug
1551     // http://code.google.com/p/v8/issues/detail?id=2291
1552     return value ? objectTypes[typeof value] : false;
1553   }
1554
1555   /**
1556    * Checks if `value` is `NaN`.
1557    *
1558    * Note: This is not the same as native `isNaN`, which will return `true` for
1559    * `undefined` and other values. See http://es5.github.com/#x15.1.2.4.
1560    *
1561    * @static
1562    * @memberOf _
1563    * @category Objects
1564    * @param {Mixed} value The value to check.
1565    * @returns {Boolean} Returns `true`, if the `value` is `NaN`, else `false`.
1566    * @example
1567    *
1568    * _.isNaN(NaN);
1569    * // => true
1570    *
1571    * _.isNaN(new Number(NaN));
1572    * // => true
1573    *
1574    * isNaN(undefined);
1575    * // => true
1576    *
1577    * _.isNaN(undefined);
1578    * // => false
1579    */
1580   function isNaN(value) {
1581     // `NaN` as a primitive is the only value that is not equal to itself
1582     // (perform the [[Class]] check first to avoid errors with some host objects in IE)
1583     return isNumber(value) && value != +value
1584   }
1585
1586   /**
1587    * Checks if `value` is `null`.
1588    *
1589    * @static
1590    * @memberOf _
1591    * @category Objects
1592    * @param {Mixed} value The value to check.
1593    * @returns {Boolean} Returns `true`, if the `value` is `null`, else `false`.
1594    * @example
1595    *
1596    * _.isNull(null);
1597    * // => true
1598    *
1599    * _.isNull(undefined);
1600    * // => false
1601    */
1602   function isNull(value) {
1603     return value === null;
1604   }
1605
1606   /**
1607    * Checks if `value` is a number.
1608    *
1609    * @static
1610    * @memberOf _
1611    * @category Objects
1612    * @param {Mixed} value The value to check.
1613    * @returns {Boolean} Returns `true`, if the `value` is a number, else `false`.
1614    * @example
1615    *
1616    * _.isNumber(8.4 * 5);
1617    * // => true
1618    */
1619   function isNumber(value) {
1620     return typeof value == 'number' || toString.call(value) == numberClass;
1621   }
1622
1623   /**
1624    * Checks if a given `value` is an object created by the `Object` constructor.
1625    *
1626    * @static
1627    * @memberOf _
1628    * @category Objects
1629    * @param {Mixed} value The value to check.
1630    * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
1631    * @example
1632    *
1633    * function Stooge(name, age) {
1634    *   this.name = name;
1635    *   this.age = age;
1636    * }
1637    *
1638    * _.isPlainObject(new Stooge('moe', 40));
1639    * // => false
1640    *
1641    * _.isPlainObject([1, 2, 3]);
1642    * // => false
1643    *
1644    * _.isPlainObject({ 'name': 'moe', 'age': 40 });
1645    * // => true
1646    */
1647   var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
1648     if (!(value && typeof value == 'object')) {
1649       return false;
1650     }
1651     var valueOf = value.valueOf,
1652         objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
1653
1654     return objProto
1655       ? value == objProto || (getPrototypeOf(value) == objProto && !isArguments(value))
1656       : shimIsPlainObject(value);
1657   };
1658
1659   /**
1660    * Checks if `value` is a regular expression.
1661    *
1662    * @static
1663    * @memberOf _
1664    * @category Objects
1665    * @param {Mixed} value The value to check.
1666    * @returns {Boolean} Returns `true`, if the `value` is a regular expression, else `false`.
1667    * @example
1668    *
1669    * _.isRegExp(/moe/);
1670    * // => true
1671    */
1672   function isRegExp(value) {
1673     return value instanceof RegExp || toString.call(value) == regexpClass;
1674   }
1675
1676   /**
1677    * Checks if `value` is a string.
1678    *
1679    * @static
1680    * @memberOf _
1681    * @category Objects
1682    * @param {Mixed} value The value to check.
1683    * @returns {Boolean} Returns `true`, if the `value` is a string, else `false`.
1684    * @example
1685    *
1686    * _.isString('moe');
1687    * // => true
1688    */
1689   function isString(value) {
1690     return typeof value == 'string' || toString.call(value) == stringClass;
1691   }
1692
1693   /**
1694    * Checks if `value` is `undefined`.
1695    *
1696    * @static
1697    * @memberOf _
1698    * @category Objects
1699    * @param {Mixed} value The value to check.
1700    * @returns {Boolean} Returns `true`, if the `value` is `undefined`, else `false`.
1701    * @example
1702    *
1703    * _.isUndefined(void 0);
1704    * // => true
1705    */
1706   function isUndefined(value) {
1707     return typeof value == 'undefined';
1708   }
1709
1710   /**
1711    * Recursively merges own enumerable properties of the source object(s), that
1712    * don't resolve to `undefined`, into the destination object. Subsequent sources
1713    * will overwrite propery assignments of previous sources. If a `callback` function
1714    * is passed, it will be executed to produce the merged values of the destination
1715    * and source properties. If `callback` returns `undefined`, merging will be
1716    * handled by the method instead. The `callback` is bound to `thisArg` and
1717    * invoked with two arguments; (objectValue, sourceValue).
1718    *
1719    * @static
1720    * @memberOf _
1721    * @category Objects
1722    * @param {Object} object The destination object.
1723    * @param {Object} [source1, source2, ...] The source objects.
1724    * @param {Function} [callback] The function to customize merging properties.
1725    * @param {Mixed} [thisArg] The `this` binding of `callback`.
1726    * @param- {Object} [deepIndicator] Internally used to indicate that `stackA`
1727    *  and `stackB` are arrays of traversed objects instead of source objects.
1728    * @param- {Array} [stackA=[]] Internally used to track traversed source objects.
1729    * @param- {Array} [stackB=[]] Internally used to associate values with their
1730    *  source counterparts.
1731    * @returns {Object} Returns the destination object.
1732    * @example
1733    *
1734    * var names = {
1735    *   'stooges': [
1736    *     { 'name': 'moe' },
1737    *     { 'name': 'larry' }
1738    *   ]
1739    * };
1740    *
1741    * var ages = {
1742    *   'stooges': [
1743    *     { 'age': 40 },
1744    *     { 'age': 50 }
1745    *   ]
1746    * };
1747    *
1748    * _.merge(names, ages);
1749    * // => { 'stooges': [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] }
1750    *
1751    * var food = {
1752    *   'fruits': ['apple'],
1753    *   'vegetables': ['beet']
1754    * };
1755    *
1756    * var otherFood = {
1757    *   'fruits': ['banana'],
1758    *   'vegetables': ['carrot']
1759    * };
1760    *
1761    * _.merge(food, otherFood, function(a, b) {
1762    *   return _.isArray(a) ? a.concat(b) : undefined;
1763    * });
1764    * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
1765    */
1766   function merge(object, source, deepIndicator) {
1767     var args = arguments,
1768         index = 0,
1769         length = 2;
1770
1771     if (!isObject(object)) {
1772       return object;
1773     }
1774     if (deepIndicator === indicatorObject) {
1775       var callback = args[3],
1776           stackA = args[4],
1777           stackB = args[5];
1778     } else {
1779       stackA = [];
1780       stackB = [];
1781
1782       // allows working with `_.reduce` and `_.reduceRight` without
1783       // using their `callback` arguments, `index|key` and `collection`
1784       if (typeof deepIndicator != 'number') {
1785         length = args.length;
1786       }
1787       if (length > 3 && typeof args[length - 2] == 'function') {
1788         callback = createCallback(args[--length - 1], args[length--], 2);
1789       } else if (length > 2 && typeof args[length - 1] == 'function') {
1790         callback = args[--length];
1791       }
1792     }
1793     while (++index < length) {
1794       (isArray(args[index]) ? forEach : forOwn)(args[index], function(source, key) {
1795         var found,
1796             isArr,
1797             result = source,
1798             value = object[key];
1799
1800         if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
1801           // avoid merging previously merged cyclic sources
1802           var stackLength = stackA.length;
1803           while (stackLength--) {
1804             if ((found = stackA[stackLength] == source)) {
1805               value = stackB[stackLength];
1806               break;
1807             }
1808           }
1809           if (!found) {
1810             value = isArr
1811               ? (isArray(value) ? value : [])
1812               : (isPlainObject(value) ? value : {});
1813
1814             if (callback) {
1815               result = callback(value, source);
1816               if (typeof result != 'undefined') {
1817                 value = result;
1818               }
1819             }
1820             // add `source` and associated `value` to the stack of traversed objects
1821             stackA.push(source);
1822             stackB.push(value);
1823
1824             // recursively merge objects and arrays (susceptible to call stack limits)
1825             if (!callback) {
1826               value = merge(value, source, indicatorObject, callback, stackA, stackB);
1827             }
1828           }
1829         }
1830         else {
1831           if (callback) {
1832             result = callback(value, source);
1833             if (typeof result == 'undefined') {
1834               result = source;
1835             }
1836           }
1837           if (typeof result != 'undefined') {
1838             value = result;
1839           }
1840         }
1841         object[key] = value;
1842       });
1843     }
1844     return object;
1845   }
1846
1847   /**
1848    * Creates a shallow clone of `object` excluding the specified properties.
1849    * Property names may be specified as individual arguments or as arrays of
1850    * property names. If a `callback` function is passed, it will be executed
1851    * for each property in the `object`, omitting the properties `callback`
1852    * returns truthy for. The `callback` is bound to `thisArg` and invoked
1853    * with three arguments; (value, key, object).
1854    *
1855    * @static
1856    * @memberOf _
1857    * @category Objects
1858    * @param {Object} object The source object.
1859    * @param {Function|String} callback|[prop1, prop2, ...] The properties to omit
1860    *  or the function called per iteration.
1861    * @param {Mixed} [thisArg] The `this` binding of `callback`.
1862    * @returns {Object} Returns an object without the omitted properties.
1863    * @example
1864    *
1865    * _.omit({ 'name': 'moe', 'age': 40 }, 'age');
1866    * // => { 'name': 'moe' }
1867    *
1868    * _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
1869    *   return typeof value == 'number';
1870    * });
1871    * // => { 'name': 'moe' }
1872    */
1873   function omit(object, callback, thisArg) {
1874     var isFunc = typeof callback == 'function',
1875         result = {};
1876
1877     if (isFunc) {
1878       callback = createCallback(callback, thisArg);
1879     } else {
1880       var props = concat.apply(arrayRef, arguments);
1881     }
1882     forIn(object, function(value, key, object) {
1883       if (isFunc
1884             ? !callback(value, key, object)
1885             : indexOf(props, key, 1) < 0
1886           ) {
1887         result[key] = value;
1888       }
1889     });
1890     return result;
1891   }
1892
1893   /**
1894    * Creates a two dimensional array of the given object's key-value pairs,
1895    * i.e. `[[key1, value1], [key2, value2]]`.
1896    *
1897    * @static
1898    * @memberOf _
1899    * @category Objects
1900    * @param {Object} object The object to inspect.
1901    * @returns {Array} Returns new array of key-value pairs.
1902    * @example
1903    *
1904    * _.pairs({ 'moe': 30, 'larry': 40 });
1905    * // => [['moe', 30], ['larry', 40]] (order is not guaranteed)
1906    */
1907   function pairs(object) {
1908     var index = -1,
1909         props = keys(object),
1910         length = props.length,
1911         result = Array(length);
1912
1913     while (++index < length) {
1914       var key = props[index];
1915       result[index] = [key, object[key]];
1916     }
1917     return result;
1918   }
1919
1920   /**
1921    * Creates a shallow clone of `object` composed of the specified properties.
1922    * Property names may be specified as individual arguments or as arrays of property
1923    * names. If `callback` is passed, it will be executed for each property in the
1924    * `object`, picking the properties `callback` returns truthy for. The `callback`
1925    * is bound to `thisArg` and invoked with three arguments; (value, key, object).
1926    *
1927    * @static
1928    * @memberOf _
1929    * @category Objects
1930    * @param {Object} object The source object.
1931    * @param {Array|Function|String} callback|[prop1, prop2, ...] The function called
1932    *  per iteration or properties to pick, either as individual arguments or arrays.
1933    * @param {Mixed} [thisArg] The `this` binding of `callback`.
1934    * @returns {Object} Returns an object composed of the picked properties.
1935    * @example
1936    *
1937    * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
1938    * // => { 'name': 'moe' }
1939    *
1940    * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
1941    *   return key.charAt(0) != '_';
1942    * });
1943    * // => { 'name': 'moe' }
1944    */
1945   function pick(object, callback, thisArg) {
1946     var result = {};
1947     if (typeof callback != 'function') {
1948       var index = 0,
1949           props = concat.apply(arrayRef, arguments),
1950           length = isObject(object) ? props.length : 0;
1951
1952       while (++index < length) {
1953         var key = props[index];
1954         if (key in object) {
1955           result[key] = object[key];
1956         }
1957       }
1958     } else {
1959       callback = createCallback(callback, thisArg);
1960       forIn(object, function(value, key, object) {
1961         if (callback(value, key, object)) {
1962           result[key] = value;
1963         }
1964       });
1965     }
1966     return result;
1967   }
1968
1969   /**
1970    * Creates an array composed of the own enumerable property values of `object`.
1971    *
1972    * @static
1973    * @memberOf _
1974    * @category Objects
1975    * @param {Object} object The object to inspect.
1976    * @returns {Array} Returns a new array of property values.
1977    * @example
1978    *
1979    * _.values({ 'one': 1, 'two': 2, 'three': 3 });
1980    * // => [1, 2, 3]
1981    */
1982   function values(object) {
1983     var index = -1,
1984         props = keys(object),
1985         length = props.length,
1986         result = Array(length);
1987
1988     while (++index < length) {
1989       result[index] = object[props[index]];
1990     }
1991     return result;
1992   }
1993
1994   /*--------------------------------------------------------------------------*/
1995
1996   /**
1997    * Creates an array of elements from the specified indexes, or keys, of the
1998    * `collection`. Indexes may be specified as individual arguments or as arrays
1999    * of indexes.
2000    *
2001    * @static
2002    * @memberOf _
2003    * @category Collections
2004    * @param {Array|Object|String} collection The collection to iterate over.
2005    * @param {Array|Number|String} [index1, index2, ...] The indexes of
2006    *  `collection` to retrieve, either as individual arguments or arrays.
2007    * @returns {Array} Returns a new array of elements corresponding to the
2008    *  provided indexes.
2009    * @example
2010    *
2011    * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
2012    * // => ['a', 'c', 'e']
2013    *
2014    * _.at(['moe', 'larry', 'curly'], 0, 2);
2015    * // => ['moe', 'curly']
2016    */
2017   function at(collection) {
2018     var index = -1,
2019         props = concat.apply(arrayRef, slice(arguments, 1)),
2020         length = props.length,
2021         result = Array(length);
2022
2023     while(++index < length) {
2024       result[index] = collection[props[index]];
2025     }
2026     return result;
2027   }
2028
2029   /**
2030    * Checks if a given `target` element is present in a `collection` using strict
2031    * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
2032    * as the offset from the end of the collection.
2033    *
2034    * @static
2035    * @memberOf _
2036    * @alias include
2037    * @category Collections
2038    * @param {Array|Object|String} collection The collection to iterate over.
2039    * @param {Mixed} target The value to check for.
2040    * @param {Number} [fromIndex=0] The index to search from.
2041    * @returns {Boolean} Returns `true` if the `target` element is found, else `false`.
2042    * @example
2043    *
2044    * _.contains([1, 2, 3], 1);
2045    * // => true
2046    *
2047    * _.contains([1, 2, 3], 1, 2);
2048    * // => false
2049    *
2050    * _.contains({ 'name': 'moe', 'age': 40 }, 'moe');
2051    * // => true
2052    *
2053    * _.contains('curly', 'ur');
2054    * // => true
2055    */
2056   function contains(collection, target, fromIndex) {
2057     var index = -1,
2058         length = collection ? collection.length : 0,
2059         result = false;
2060
2061     fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
2062     if (typeof length == 'number') {
2063       result = (isString(collection)
2064         ? collection.indexOf(target, fromIndex)
2065         : indexOf(collection, target, fromIndex)
2066       ) > -1;
2067     } else {
2068       each(collection, function(value) {
2069         if (++index >= fromIndex) {
2070           return !(result = value === target);
2071         }
2072       });
2073     }
2074     return result;
2075   }
2076
2077   /**
2078    * Creates an object composed of keys returned from running each element of the
2079    * `collection` through the given `callback`. The corresponding value of each key
2080    * is the number of times the key was returned by the `callback`. The `callback`
2081    * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
2082    *
2083    * If a property name is passed for `callback`, the created "_.pluck" style
2084    * callback will return the property value of the given element.
2085    *
2086    * If an object is passed for `callback`, the created "_.where" style callback
2087    * will return `true` for elements that have the propeties of the given object,
2088    * else `false`.
2089    *
2090    * @static
2091    * @memberOf _
2092    * @category Collections
2093    * @param {Array|Object|String} collection The collection to iterate over.
2094    * @param {Function|Object|String} [callback=identity] The function called per
2095    *  iteration. If a property name or object is passed, it will be used to create
2096    *  a "_.pluck" or "_.where" style callback, respectively.
2097    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2098    * @returns {Object} Returns the composed aggregate object.
2099    * @example
2100    *
2101    * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
2102    * // => { '4': 1, '6': 2 }
2103    *
2104    * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
2105    * // => { '4': 1, '6': 2 }
2106    *
2107    * _.countBy(['one', 'two', 'three'], 'length');
2108    * // => { '3': 2, '5': 1 }
2109    */
2110   function countBy(collection, callback, thisArg) {
2111     var result = {};
2112     callback = createCallback(callback, thisArg);
2113
2114     forEach(collection, function(value, key, collection) {
2115       key = callback(value, key, collection) + '';
2116       (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
2117     });
2118     return result;
2119   }
2120
2121   /**
2122    * Checks if the `callback` returns a truthy value for **all** elements of a
2123    * `collection`. The `callback` is bound to `thisArg` and invoked with three
2124    * arguments; (value, index|key, collection).
2125    *
2126    * If a property name is passed for `callback`, the created "_.pluck" style
2127    * callback will return the property value of the given element.
2128    *
2129    * If an object is passed for `callback`, the created "_.where" style callback
2130    * will return `true` for elements that have the propeties of the given object,
2131    * else `false`.
2132    *
2133    * @static
2134    * @memberOf _
2135    * @alias all
2136    * @category Collections
2137    * @param {Array|Object|String} collection The collection to iterate over.
2138    * @param {Function|Object|String} [callback=identity] The function called per
2139    *  iteration. If a property name or object is passed, it will be used to create
2140    *  a "_.pluck" or "_.where" style callback, respectively.
2141    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2142    * @returns {Boolean} Returns `true` if all elements pass the callback check,
2143    *  else `false`.
2144    * @example
2145    *
2146    * _.every([true, 1, null, 'yes'], Boolean);
2147    * // => false
2148    *
2149    * var stooges = [
2150    *   { 'name': 'moe', 'age': 40 },
2151    *   { 'name': 'larry', 'age': 50 }
2152    * ];
2153    *
2154    * // using "_.pluck" callback shorthand
2155    * _.every(stooges, 'age');
2156    * // => true
2157    *
2158    * // using "_.where" callback shorthand
2159    * _.every(stooges, { 'age': 50 });
2160    * // => false
2161    */
2162   function every(collection, callback, thisArg) {
2163     var result = true;
2164     callback = createCallback(callback, thisArg);
2165
2166     if (isArray(collection)) {
2167       var index = -1,
2168           length = collection.length;
2169
2170       while (++index < length) {
2171         if (!(result = !!callback(collection[index], index, collection))) {
2172           break;
2173         }
2174       }
2175     } else {
2176       each(collection, function(value, index, collection) {
2177         return (result = !!callback(value, index, collection));
2178       });
2179     }
2180     return result;
2181   }
2182
2183   /**
2184    * Examines each element in a `collection`, returning an array of all elements
2185    * the `callback` returns truthy for. The `callback` is bound to `thisArg` and
2186    * invoked with three arguments; (value, index|key, collection).
2187    *
2188    * If a property name is passed for `callback`, the created "_.pluck" style
2189    * callback will return the property value of the given element.
2190    *
2191    * If an object is passed for `callback`, the created "_.where" style callback
2192    * will return `true` for elements that have the propeties of the given object,
2193    * else `false`.
2194    *
2195    * @static
2196    * @memberOf _
2197    * @alias select
2198    * @category Collections
2199    * @param {Array|Object|String} collection The collection to iterate over.
2200    * @param {Function|Object|String} [callback=identity] The function called per
2201    *  iteration. If a property name or object is passed, it will be used to create
2202    *  a "_.pluck" or "_.where" style callback, respectively.
2203    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2204    * @returns {Array} Returns a new array of elements that passed the callback check.
2205    * @example
2206    *
2207    * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
2208    * // => [2, 4, 6]
2209    *
2210    * var food = [
2211    *   { 'name': 'apple',  'organic': false, 'type': 'fruit' },
2212    *   { 'name': 'carrot', 'organic': true,  'type': 'vegetable' }
2213    * ];
2214    *
2215    * // using "_.pluck" callback shorthand
2216    * _.filter(food, 'organic');
2217    * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
2218    *
2219    * // using "_.where" callback shorthand
2220    * _.filter(food, { 'type': 'fruit' });
2221    * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
2222    */
2223   function filter(collection, callback, thisArg) {
2224     var result = [];
2225     callback = createCallback(callback, thisArg);
2226
2227     if (isArray(collection)) {
2228       var index = -1,
2229           length = collection.length;
2230
2231       while (++index < length) {
2232         var value = collection[index];
2233         if (callback(value, index, collection)) {
2234           result.push(value);
2235         }
2236       }
2237     } else {
2238       each(collection, function(value, index, collection) {
2239         if (callback(value, index, collection)) {
2240           result.push(value);
2241         }
2242       });
2243     }
2244     return result;
2245   }
2246
2247   /**
2248    * Examines each element in a `collection`, returning the first that the `callback`
2249    * returns truthy for. The `callback` is bound to `thisArg` and invoked with three
2250    * arguments; (value, index|key, collection).
2251    *
2252    * If a property name is passed for `callback`, the created "_.pluck" style
2253    * callback will return the property value of the given element.
2254    *
2255    * If an object is passed for `callback`, the created "_.where" style callback
2256    * will return `true` for elements that have the propeties of the given object,
2257    * else `false`.
2258    *
2259    * @static
2260    * @memberOf _
2261    * @alias detect
2262    * @category Collections
2263    * @param {Array|Object|String} collection The collection to iterate over.
2264    * @param {Function|Object|String} [callback=identity] The function called per
2265    *  iteration. If a property name or object is passed, it will be used to create
2266    *  a "_.pluck" or "_.where" style callback, respectively.
2267    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2268    * @returns {Mixed} Returns the element that passed the callback check,
2269    *  else `undefined`.
2270    * @example
2271    *
2272    * var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
2273    * // => 2
2274    *
2275    * var food = [
2276    *   { 'name': 'apple',  'organic': false, 'type': 'fruit' },
2277    *   { 'name': 'banana', 'organic': true,  'type': 'fruit' },
2278    *   { 'name': 'beet',   'organic': false, 'type': 'vegetable' },
2279    *   { 'name': 'carrot', 'organic': true,  'type': 'vegetable' }
2280    * ];
2281    *
2282    * // using "_.where" callback shorthand
2283    * var veggie = _.find(food, { 'type': 'vegetable' });
2284    * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
2285    *
2286    * // using "_.pluck" callback shorthand
2287    * var healthy = _.find(food, 'organic');
2288    * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
2289    */
2290   function find(collection, callback, thisArg) {
2291     var result;
2292     callback = createCallback(callback, thisArg);
2293
2294     forEach(collection, function(value, index, collection) {
2295       if (callback(value, index, collection)) {
2296         result = value;
2297         return false;
2298       }
2299     });
2300     return result;
2301   }
2302
2303   /**
2304    * Iterates over a `collection`, executing the `callback` for each element in
2305    * the `collection`. The `callback` is bound to `thisArg` and invoked with three
2306    * arguments; (value, index|key, collection). Callbacks may exit iteration early
2307    * by explicitly returning `false`.
2308    *
2309    * @static
2310    * @memberOf _
2311    * @alias each
2312    * @category Collections
2313    * @param {Array|Object|String} collection The collection to iterate over.
2314    * @param {Function} [callback=identity] The function called per iteration.
2315    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2316    * @returns {Array|Object|String} Returns `collection`.
2317    * @example
2318    *
2319    * _([1, 2, 3]).forEach(alert).join(',');
2320    * // => alerts each number and returns '1,2,3'
2321    *
2322    * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert);
2323    * // => alerts each number value (order is not guaranteed)
2324    */
2325   function forEach(collection, callback, thisArg) {
2326     if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
2327       var index = -1,
2328           length = collection.length;
2329
2330       while (++index < length) {
2331         if (callback(collection[index], index, collection) === false) {
2332           break;
2333         }
2334       }
2335     } else {
2336       each(collection, callback, thisArg);
2337     }
2338     return collection;
2339   }
2340
2341   /**
2342    * Creates an object composed of keys returned from running each element of the
2343    * `collection` through the `callback`. The corresponding value of each key is
2344    * an array of elements passed to `callback` that returned the key. The `callback`
2345    * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
2346    *
2347    * If a property name is passed for `callback`, the created "_.pluck" style
2348    * callback will return the property value of the given element.
2349    *
2350    * If an object is passed for `callback`, the created "_.where" style callback
2351    * will return `true` for elements that have the propeties of the given object,
2352    * else `false`
2353    *
2354    * @static
2355    * @memberOf _
2356    * @category Collections
2357    * @param {Array|Object|String} collection The collection to iterate over.
2358    * @param {Function|Object|String} [callback=identity] The function called per
2359    *  iteration. If a property name or object is passed, it will be used to create
2360    *  a "_.pluck" or "_.where" style callback, respectively.
2361    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2362    * @returns {Object} Returns the composed aggregate object.
2363    * @example
2364    *
2365    * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
2366    * // => { '4': [4.2], '6': [6.1, 6.4] }
2367    *
2368    * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
2369    * // => { '4': [4.2], '6': [6.1, 6.4] }
2370    *
2371    * // using "_.pluck" callback shorthand
2372    * _.groupBy(['one', 'two', 'three'], 'length');
2373    * // => { '3': ['one', 'two'], '5': ['three'] }
2374    */
2375   function groupBy(collection, callback, thisArg) {
2376     var result = {};
2377     callback = createCallback(callback, thisArg);
2378
2379     forEach(collection, function(value, key, collection) {
2380       key = callback(value, key, collection) + '';
2381       (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
2382     });
2383     return result;
2384   }
2385
2386   /**
2387    * Invokes the method named by `methodName` on each element in the `collection`,
2388    * returning an array of the results of each invoked method. Additional arguments
2389    * will be passed to each invoked method. If `methodName` is a function, it will
2390    * be invoked for, and `this` bound to, each element in the `collection`.
2391    *
2392    * @static
2393    * @memberOf _
2394    * @category Collections
2395    * @param {Array|Object|String} collection The collection to iterate over.
2396    * @param {Function|String} methodName The name of the method to invoke or
2397    *  the function invoked per iteration.
2398    * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
2399    * @returns {Array} Returns a new array of the results of each invoked method.
2400    * @example
2401    *
2402    * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
2403    * // => [[1, 5, 7], [1, 2, 3]]
2404    *
2405    * _.invoke([123, 456], String.prototype.split, '');
2406    * // => [['1', '2', '3'], ['4', '5', '6']]
2407    */
2408   function invoke(collection, methodName) {
2409     var args = slice(arguments, 2),
2410         index = -1,
2411         isFunc = typeof methodName == 'function',
2412         length = collection ? collection.length : 0,
2413         result = Array(typeof length == 'number' ? length : 0);
2414
2415     forEach(collection, function(value) {
2416       result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
2417     });
2418     return result;
2419   }
2420
2421   /**
2422    * Creates an array of values by running each element in the `collection`
2423    * through the `callback`. The `callback` is bound to `thisArg` and invoked with
2424    * three arguments; (value, index|key, collection).
2425    *
2426    * If a property name is passed for `callback`, the created "_.pluck" style
2427    * callback will return the property value of the given element.
2428    *
2429    * If an object is passed for `callback`, the created "_.where" style callback
2430    * will return `true` for elements that have the propeties of the given object,
2431    * else `false`.
2432    *
2433    * @static
2434    * @memberOf _
2435    * @alias collect
2436    * @category Collections
2437    * @param {Array|Object|String} collection The collection to iterate over.
2438    * @param {Function|Object|String} [callback=identity] The function called per
2439    *  iteration. If a property name or object is passed, it will be used to create
2440    *  a "_.pluck" or "_.where" style callback, respectively.
2441    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2442    * @returns {Array} Returns a new array of the results of each `callback` execution.
2443    * @example
2444    *
2445    * _.map([1, 2, 3], function(num) { return num * 3; });
2446    * // => [3, 6, 9]
2447    *
2448    * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
2449    * // => [3, 6, 9] (order is not guaranteed)
2450    *
2451    * var stooges = [
2452    *   { 'name': 'moe', 'age': 40 },
2453    *   { 'name': 'larry', 'age': 50 }
2454    * ];
2455    *
2456    * // using "_.pluck" callback shorthand
2457    * _.map(stooges, 'name');
2458    * // => ['moe', 'larry']
2459    */
2460   function map(collection, callback, thisArg) {
2461     var index = -1,
2462         length = collection ? collection.length : 0,
2463         result = Array(typeof length == 'number' ? length : 0);
2464
2465     callback = createCallback(callback, thisArg);
2466     if (isArray(collection)) {
2467       while (++index < length) {
2468         result[index] = callback(collection[index], index, collection);
2469       }
2470     } else {
2471       each(collection, function(value, key, collection) {
2472         result[++index] = callback(value, key, collection);
2473       });
2474     }
2475     return result;
2476   }
2477
2478   /**
2479    * Retrieves the maximum value of an `array`. If `callback` is passed,
2480    * it will be executed for each value in the `array` to generate the
2481    * criterion by which the value is ranked. The `callback` is bound to
2482    * `thisArg` and invoked with three arguments; (value, index, collection).
2483    *
2484    * If a property name is passed for `callback`, the created "_.pluck" style
2485    * callback will return the property value of the given element.
2486    *
2487    * If an object is passed for `callback`, the created "_.where" style callback
2488    * will return `true` for elements that have the propeties of the given object,
2489    * else `false`.
2490    *
2491    * @static
2492    * @memberOf _
2493    * @category Collections
2494    * @param {Array|Object|String} collection The collection to iterate over.
2495    * @param {Function|Object|String} [callback=identity] The function called per
2496    *  iteration. If a property name or object is passed, it will be used to create
2497    *  a "_.pluck" or "_.where" style callback, respectively.
2498    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2499    * @returns {Mixed} Returns the maximum value.
2500    * @example
2501    *
2502    * _.max([4, 2, 8, 6]);
2503    * // => 8
2504    *
2505    * var stooges = [
2506    *   { 'name': 'moe', 'age': 40 },
2507    *   { 'name': 'larry', 'age': 50 }
2508    * ];
2509    *
2510    * _.max(stooges, function(stooge) { return stooge.age; });
2511    * // => { 'name': 'larry', 'age': 50 };
2512    *
2513    * // using "_.pluck" callback shorthand
2514    * _.max(stooges, 'age');
2515    * // => { 'name': 'larry', 'age': 50 };
2516    */
2517   function max(collection, callback, thisArg) {
2518     var computed = -Infinity,
2519         result = computed;
2520
2521     if (!callback && isArray(collection)) {
2522       var index = -1,
2523           length = collection.length;
2524
2525       while (++index < length) {
2526         var value = collection[index];
2527         if (value > result) {
2528           result = value;
2529         }
2530       }
2531     } else {
2532       callback = !callback && isString(collection)
2533         ? charAtCallback
2534         : createCallback(callback, thisArg);
2535
2536       each(collection, function(value, index, collection) {
2537         var current = callback(value, index, collection);
2538         if (current > computed) {
2539           computed = current;
2540           result = value;
2541         }
2542       });
2543     }
2544     return result;
2545   }
2546
2547   /**
2548    * Retrieves the minimum value of an `array`. If `callback` is passed,
2549    * it will be executed for each value in the `array` to generate the
2550    * criterion by which the value is ranked. The `callback` is bound to `thisArg`
2551    * and invoked with three arguments; (value, index, collection).
2552    *
2553    * If a property name is passed for `callback`, the created "_.pluck" style
2554    * callback will return the property value of the given element.
2555    *
2556    * If an object is passed for `callback`, the created "_.where" style callback
2557    * will return `true` for elements that have the propeties of the given object,
2558    * else `false`.
2559    *
2560    * @static
2561    * @memberOf _
2562    * @category Collections
2563    * @param {Array|Object|String} collection The collection to iterate over.
2564    * @param {Function|Object|String} [callback=identity] The function called per
2565    *  iteration. If a property name or object is passed, it will be used to create
2566    *  a "_.pluck" or "_.where" style callback, respectively.
2567    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2568    * @returns {Mixed} Returns the minimum value.
2569    * @example
2570    *
2571    * _.min([4, 2, 8, 6]);
2572    * // => 2
2573    *
2574    * var stooges = [
2575    *   { 'name': 'moe', 'age': 40 },
2576    *   { 'name': 'larry', 'age': 50 }
2577    * ];
2578    *
2579    * _.min(stooges, function(stooge) { return stooge.age; });
2580    * // => { 'name': 'moe', 'age': 40 };
2581    *
2582    * // using "_.pluck" callback shorthand
2583    * _.min(stooges, 'age');
2584    * // => { 'name': 'moe', 'age': 40 };
2585    */
2586   function min(collection, callback, thisArg) {
2587     var computed = Infinity,
2588         result = computed;
2589
2590     if (!callback && isArray(collection)) {
2591       var index = -1,
2592           length = collection.length;
2593
2594       while (++index < length) {
2595         var value = collection[index];
2596         if (value < result) {
2597           result = value;
2598         }
2599       }
2600     } else {
2601       callback = !callback && isString(collection)
2602         ? charAtCallback
2603         : createCallback(callback, thisArg);
2604
2605       each(collection, function(value, index, collection) {
2606         var current = callback(value, index, collection);
2607         if (current < computed) {
2608           computed = current;
2609           result = value;
2610         }
2611       });
2612     }
2613     return result;
2614   }
2615
2616   /**
2617    * Retrieves the value of a specified property from all elements in the `collection`.
2618    *
2619    * @static
2620    * @memberOf _
2621    * @type Function
2622    * @category Collections
2623    * @param {Array|Object|String} collection The collection to iterate over.
2624    * @param {String} property The property to pluck.
2625    * @returns {Array} Returns a new array of property values.
2626    * @example
2627    *
2628    * var stooges = [
2629    *   { 'name': 'moe', 'age': 40 },
2630    *   { 'name': 'larry', 'age': 50 }
2631    * ];
2632    *
2633    * _.pluck(stooges, 'name');
2634    * // => ['moe', 'larry']
2635    */
2636   var pluck = map;
2637
2638   /**
2639    * Reduces a `collection` to a value that is the accumulated result of running
2640    * each element in the `collection` through the `callback`, where each successive
2641    * `callback` execution consumes the return value of the previous execution.
2642    * If `accumulator` is not passed, the first element of the `collection` will be
2643    * used as the initial `accumulator` value. The `callback` is bound to `thisArg`
2644    * and invoked with four arguments; (accumulator, value, index|key, collection).
2645    *
2646    * @static
2647    * @memberOf _
2648    * @alias foldl, inject
2649    * @category Collections
2650    * @param {Array|Object|String} collection The collection to iterate over.
2651    * @param {Function} [callback=identity] The function called per iteration.
2652    * @param {Mixed} [accumulator] Initial value of the accumulator.
2653    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2654    * @returns {Mixed} Returns the accumulated value.
2655    * @example
2656    *
2657    * var sum = _.reduce([1, 2, 3], function(sum, num) {
2658    *   return sum + num;
2659    * });
2660    * // => 6
2661    *
2662    * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
2663    *   result[key] = num * 3;
2664    *   return result;
2665    * }, {});
2666    * // => { 'a': 3, 'b': 6, 'c': 9 }
2667    */
2668   function reduce(collection, callback, accumulator, thisArg) {
2669     var noaccum = arguments.length < 3;
2670     callback = createCallback(callback, thisArg, 4);
2671
2672     if (isArray(collection)) {
2673       var index = -1,
2674           length = collection.length;
2675
2676       if (noaccum) {
2677         accumulator = collection[++index];
2678       }
2679       while (++index < length) {
2680         accumulator = callback(accumulator, collection[index], index, collection);
2681       }
2682     } else {
2683       each(collection, function(value, index, collection) {
2684         accumulator = noaccum
2685           ? (noaccum = false, value)
2686           : callback(accumulator, value, index, collection)
2687       });
2688     }
2689     return accumulator;
2690   }
2691
2692   /**
2693    * This method is similar to `_.reduce`, except that it iterates over a
2694    * `collection` from right to left.
2695    *
2696    * @static
2697    * @memberOf _
2698    * @alias foldr
2699    * @category Collections
2700    * @param {Array|Object|String} collection The collection to iterate over.
2701    * @param {Function} [callback=identity] The function called per iteration.
2702    * @param {Mixed} [accumulator] Initial value of the accumulator.
2703    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2704    * @returns {Mixed} Returns the accumulated value.
2705    * @example
2706    *
2707    * var list = [[0, 1], [2, 3], [4, 5]];
2708    * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
2709    * // => [4, 5, 2, 3, 0, 1]
2710    */
2711   function reduceRight(collection, callback, accumulator, thisArg) {
2712     var iterable = collection,
2713         length = collection ? collection.length : 0,
2714         noaccum = arguments.length < 3;
2715
2716     if (typeof length != 'number') {
2717       var props = keys(collection);
2718       length = props.length;
2719     }
2720     callback = createCallback(callback, thisArg, 4);
2721     forEach(collection, function(value, index, collection) {
2722       index = props ? props[--length] : --length;
2723       accumulator = noaccum
2724         ? (noaccum = false, iterable[index])
2725         : callback(accumulator, iterable[index], index, collection);
2726     });
2727     return accumulator;
2728   }
2729
2730   /**
2731    * The opposite of `_.filter`, this method returns the elements of a
2732    * `collection` that `callback` does **not** return truthy for.
2733    *
2734    * If a property name is passed for `callback`, the created "_.pluck" style
2735    * callback will return the property value of the given element.
2736    *
2737    * If an object is passed for `callback`, the created "_.where" style callback
2738    * will return `true` for elements that have the propeties of the given object,
2739    * else `false`.
2740    *
2741    * @static
2742    * @memberOf _
2743    * @category Collections
2744    * @param {Array|Object|String} collection The collection to iterate over.
2745    * @param {Function|Object|String} [callback=identity] The function called per
2746    *  iteration. If a property name or object is passed, it will be used to create
2747    *  a "_.pluck" or "_.where" style callback, respectively.
2748    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2749    * @returns {Array} Returns a new array of elements that did **not** pass the
2750    *  callback check.
2751    * @example
2752    *
2753    * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
2754    * // => [1, 3, 5]
2755    *
2756    * var food = [
2757    *   { 'name': 'apple',  'organic': false, 'type': 'fruit' },
2758    *   { 'name': 'carrot', 'organic': true,  'type': 'vegetable' }
2759    * ];
2760    *
2761    * // using "_.pluck" callback shorthand
2762    * _.reject(food, 'organic');
2763    * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
2764    *
2765    * // using "_.where" callback shorthand
2766    * _.reject(food, { 'type': 'fruit' });
2767    * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
2768    */
2769   function reject(collection, callback, thisArg) {
2770     callback = createCallback(callback, thisArg);
2771     return filter(collection, function(value, index, collection) {
2772       return !callback(value, index, collection);
2773     });
2774   }
2775
2776   /**
2777    * Creates an array of shuffled `array` values, using a version of the
2778    * Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
2779    *
2780    * @static
2781    * @memberOf _
2782    * @category Collections
2783    * @param {Array|Object|String} collection The collection to shuffle.
2784    * @returns {Array} Returns a new shuffled collection.
2785    * @example
2786    *
2787    * _.shuffle([1, 2, 3, 4, 5, 6]);
2788    * // => [4, 1, 6, 3, 5, 2]
2789    */
2790   function shuffle(collection) {
2791     var index = -1,
2792         length = collection ? collection.length : 0,
2793         result = Array(typeof length == 'number' ? length : 0);
2794
2795     forEach(collection, function(value) {
2796       var rand = floor(nativeRandom() * (++index + 1));
2797       result[index] = result[rand];
2798       result[rand] = value;
2799     });
2800     return result;
2801   }
2802
2803   /**
2804    * Gets the size of the `collection` by returning `collection.length` for arrays
2805    * and array-like objects or the number of own enumerable properties for objects.
2806    *
2807    * @static
2808    * @memberOf _
2809    * @category Collections
2810    * @param {Array|Object|String} collection The collection to inspect.
2811    * @returns {Number} Returns `collection.length` or number of own enumerable properties.
2812    * @example
2813    *
2814    * _.size([1, 2]);
2815    * // => 2
2816    *
2817    * _.size({ 'one': 1, 'two': 2, 'three': 3 });
2818    * // => 3
2819    *
2820    * _.size('curly');
2821    * // => 5
2822    */
2823   function size(collection) {
2824     var length = collection ? collection.length : 0;
2825     return typeof length == 'number' ? length : keys(collection).length;
2826   }
2827
2828   /**
2829    * Checks if the `callback` returns a truthy value for **any** element of a
2830    * `collection`. The function returns as soon as it finds passing value, and
2831    * does not iterate over the entire `collection`. The `callback` is bound to
2832    * `thisArg` and invoked with three arguments; (value, index|key, collection).
2833    *
2834    * If a property name is passed for `callback`, the created "_.pluck" style
2835    * callback will return the property value of the given element.
2836    *
2837    * If an object is passed for `callback`, the created "_.where" style callback
2838    * will return `true` for elements that have the propeties of the given object,
2839    * else `false`.
2840    *
2841    * @static
2842    * @memberOf _
2843    * @alias any
2844    * @category Collections
2845    * @param {Array|Object|String} collection The collection to iterate over.
2846    * @param {Function|Object|String} [callback=identity] The function called per
2847    *  iteration. If a property name or object is passed, it will be used to create
2848    *  a "_.pluck" or "_.where" style callback, respectively.
2849    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2850    * @returns {Boolean} Returns `true` if any element passes the callback check,
2851    *  else `false`.
2852    * @example
2853    *
2854    * _.some([null, 0, 'yes', false], Boolean);
2855    * // => true
2856    *
2857    * var food = [
2858    *   { 'name': 'apple',  'organic': false, 'type': 'fruit' },
2859    *   { 'name': 'carrot', 'organic': true,  'type': 'vegetable' }
2860    * ];
2861    *
2862    * // using "_.pluck" callback shorthand
2863    * _.some(food, 'organic');
2864    * // => true
2865    *
2866    * // using "_.where" callback shorthand
2867    * _.some(food, { 'type': 'meat' });
2868    * // => false
2869    */
2870   function some(collection, callback, thisArg) {
2871     var result;
2872     callback = createCallback(callback, thisArg);
2873
2874     if (isArray(collection)) {
2875       var index = -1,
2876           length = collection.length;
2877
2878       while (++index < length) {
2879         if ((result = callback(collection[index], index, collection))) {
2880           break;
2881         }
2882       }
2883     } else {
2884       each(collection, function(value, index, collection) {
2885         return !(result = callback(value, index, collection));
2886       });
2887     }
2888     return !!result;
2889   }
2890
2891   /**
2892    * Creates an array of elements, sorted in ascending order by the results of
2893    * running each element in the `collection` through the `callback`. This method
2894    * performs a stable sort, that is, it will preserve the original sort order of
2895    * equal elements. The `callback` is bound to `thisArg` and invoked with three
2896    * arguments; (value, index|key, collection).
2897    *
2898    * If a property name is passed for `callback`, the created "_.pluck" style
2899    * callback will return the property value of the given element.
2900    *
2901    * If an object is passed for `callback`, the created "_.where" style callback
2902    * will return `true` for elements that have the propeties of the given object,
2903    * else `false`.
2904    *
2905    * @static
2906    * @memberOf _
2907    * @category Collections
2908    * @param {Array|Object|String} collection The collection to iterate over.
2909    * @param {Function|Object|String} [callback=identity] The function called per
2910    *  iteration. If a property name or object is passed, it will be used to create
2911    *  a "_.pluck" or "_.where" style callback, respectively.
2912    * @param {Mixed} [thisArg] The `this` binding of `callback`.
2913    * @returns {Array} Returns a new array of sorted elements.
2914    * @example
2915    *
2916    * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
2917    * // => [3, 1, 2]
2918    *
2919    * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
2920    * // => [3, 1, 2]
2921    *
2922    * // using "_.pluck" callback shorthand
2923    * _.sortBy(['banana', 'strawberry', 'apple'], 'length');
2924    * // => ['apple', 'banana', 'strawberry']
2925    */
2926   function sortBy(collection, callback, thisArg) {
2927     var index = -1,
2928         length = collection ? collection.length : 0,
2929         result = Array(typeof length == 'number' ? length : 0);
2930
2931     callback = createCallback(callback, thisArg);
2932     forEach(collection, function(value, key, collection) {
2933       result[++index] = {
2934         'criteria': callback(value, key, collection),
2935         'index': index,
2936         'value': value
2937       };
2938     });
2939
2940     length = result.length;
2941     result.sort(compareAscending);
2942     while (length--) {
2943       result[length] = result[length].value;
2944     }
2945     return result;
2946   }
2947
2948   /**
2949    * Converts the `collection` to an array.
2950    *
2951    * @static
2952    * @memberOf _
2953    * @category Collections
2954    * @param {Array|Object|String} collection The collection to convert.
2955    * @returns {Array} Returns the new converted array.
2956    * @example
2957    *
2958    * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
2959    * // => [2, 3, 4]
2960    */
2961   function toArray(collection) {
2962     if (collection && typeof collection.length == 'number') {
2963       return  slice(collection);
2964     }
2965     return values(collection);
2966   }
2967
2968   /**
2969    * Examines each element in a `collection`, returning an array of all elements
2970    * that have the given `properties`. When checking `properties`, this method
2971    * performs a deep comparison between values to determine if they are equivalent
2972    * to each other.
2973    *
2974    * @static
2975    * @memberOf _
2976    * @type Function
2977    * @category Collections
2978    * @param {Array|Object|String} collection The collection to iterate over.
2979    * @param {Object} properties The object of property values to filter by.
2980    * @returns {Array} Returns a new array of elements that have the given `properties`.
2981    * @example
2982    *
2983    * var stooges = [
2984    *   { 'name': 'moe', 'age': 40 },
2985    *   { 'name': 'larry', 'age': 50 }
2986    * ];
2987    *
2988    * _.where(stooges, { 'age': 40 });
2989    * // => [{ 'name': 'moe', 'age': 40 }]
2990    */
2991   var where = filter;
2992
2993   /*--------------------------------------------------------------------------*/
2994
2995   /**
2996    * Creates an array with all falsey values of `array` removed. The values
2997    * `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey.
2998    *
2999    * @static
3000    * @memberOf _
3001    * @category Arrays
3002    * @param {Array} array The array to compact.
3003    * @returns {Array} Returns a new filtered array.
3004    * @example
3005    *
3006    * _.compact([0, 1, false, 2, '', 3]);
3007    * // => [1, 2, 3]
3008    */
3009   function compact(array) {
3010     var index = -1,
3011         length = array ? array.length : 0,
3012         result = [];
3013
3014     while (++index < length) {
3015       var value = array[index];
3016       if (value) {
3017         result.push(value);
3018       }
3019     }
3020     return result;
3021   }
3022
3023   /**
3024    * Creates an array of `array` elements not present in the other arrays
3025    * using strict equality for comparisons, i.e. `===`.
3026    *
3027    * @static
3028    * @memberOf _
3029    * @category Arrays
3030    * @param {Array} array The array to process.
3031    * @param {Array} [array1, array2, ...] Arrays to check.
3032    * @returns {Array} Returns a new array of `array` elements not present in the
3033    *  other arrays.
3034    * @example
3035    *
3036    * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
3037    * // => [1, 3, 4]
3038    */
3039   function difference(array) {
3040     var index = -1,
3041         length = array ? array.length : 0,
3042         flattened = concat.apply(arrayRef, arguments),
3043         contains = cachedContains(flattened, length),
3044         result = [];
3045
3046     while (++index < length) {
3047       var value = array[index];
3048       if (!contains(value)) {
3049         result.push(value);
3050       }
3051     }
3052     return result;
3053   }
3054
3055   /**
3056    * Gets the first element of the `array`. If a number `n` is passed, the first
3057    * `n` elements of the `array` are returned. If a `callback` function is passed,
3058    * the first elements the `callback` returns truthy for are returned. The `callback`
3059    * is bound to `thisArg` and invoked with three arguments; (value, index, array).
3060    *
3061    * If a property name is passed for `callback`, the created "_.pluck" style
3062    * callback will return the property value of the given element.
3063    *
3064    * If an object is passed for `callback`, the created "_.where" style callback
3065    * will return `true` for elements that have the propeties of the given object,
3066    * else `false`.
3067    *
3068    * @static
3069    * @memberOf _
3070    * @alias head, take
3071    * @category Arrays
3072    * @param {Array} array The array to query.
3073    * @param {Function|Object|Number|String} [callback|n] The function called
3074    *  per element or the number of elements to return. If a property name or
3075    *  object is passed, it will be used to create a "_.pluck" or "_.where"
3076    *  style callback, respectively.
3077    * @param {Mixed} [thisArg] The `this` binding of `callback`.
3078    * @returns {Mixed} Returns the first element(s) of `array`.
3079    * @example
3080    *
3081    * _.first([1, 2, 3]);
3082    * // => 1
3083    *
3084    * _.first([1, 2, 3], 2);
3085    * // => [1, 2]
3086    *
3087    * _.first([1, 2, 3], function(num) {
3088    *   return num < 3;
3089    * });
3090    * // => [1, 2]
3091    *
3092    * var food = [
3093    *   { 'name': 'banana', 'organic': true },
3094    *   { 'name': 'beet',   'organic': false },
3095    * ];
3096    *
3097    * // using "_.pluck" callback shorthand
3098    * _.first(food, 'organic');
3099    * // => [{ 'name': 'banana', 'organic': true }]
3100    *
3101    * var food = [
3102    *   { 'name': 'apple',  'type': 'fruit' },
3103    *   { 'name': 'banana', 'type': 'fruit' },
3104    *   { 'name': 'beet',   'type': 'vegetable' }
3105    * ];
3106    *
3107    * // using "_.where" callback shorthand
3108    * _.first(food, { 'type': 'fruit' });
3109    * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }]
3110    */
3111   function first(array, callback, thisArg) {
3112     if (array) {
3113       var n = 0,
3114           length = array.length;
3115
3116       if (typeof callback != 'number' && callback != null) {
3117         var index = -1;
3118         callback = createCallback(callback, thisArg);
3119         while (++index < length && callback(array[index], index, array)) {
3120           n++;
3121         }
3122       } else {
3123         n = callback;
3124         if (n == null || thisArg) {
3125           return array[0];
3126         }
3127       }
3128       return slice(array, 0, nativeMin(nativeMax(0, n), length));
3129     }
3130   }
3131
3132   /**
3133    * Flattens a nested array (the nesting can be to any depth). If `shallow` is
3134    * truthy, `array` will only be flattened a single level.
3135    *
3136    * @static
3137    * @memberOf _
3138    * @category Arrays
3139    * @param {Array} array The array to compact.
3140    * @param {Boolean} shallow A flag to indicate only flattening a single level.
3141    * @returns {Array} Returns a new flattened array.
3142    * @example
3143    *
3144    * _.flatten([1, [2], [3, [[4]]]]);
3145    * // => [1, 2, 3, 4];
3146    *
3147    * _.flatten([1, [2], [3, [[4]]]], true);
3148    * // => [1, 2, 3, [[4]]];
3149    */
3150   function flatten(array, shallow) {
3151     var index = -1,
3152         length = array ? array.length : 0,
3153         result = [];
3154
3155     while (++index < length) {
3156       var value = array[index];
3157
3158       // recursively flatten arrays (susceptible to call stack limits)
3159       if (isArray(value)) {
3160         push.apply(result, shallow ? value : flatten(value));
3161       } else {
3162         result.push(value);
3163       }
3164     }
3165     return result;
3166   }
3167
3168   /**
3169    * Gets the index at which the first occurrence of `value` is found using
3170    * strict equality for comparisons, i.e. `===`. If the `array` is already
3171    * sorted, passing `true` for `fromIndex` will run a faster binary search.
3172    *
3173    * @static
3174    * @memberOf _
3175    * @category Arrays
3176    * @param {Array} array The array to search.
3177    * @param {Mixed} value The value to search for.
3178    * @param {Boolean|Number} [fromIndex=0] The index to search from or `true` to
3179    *  perform a binary search on a sorted `array`.
3180    * @returns {Number} Returns the index of the matched value or `-1`.
3181    * @example
3182    *
3183    * _.indexOf([1, 2, 3, 1, 2, 3], 2);
3184    * // => 1
3185    *
3186    * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
3187    * // => 4
3188    *
3189    * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
3190    * // => 2
3191    */
3192   function indexOf(array, value, fromIndex) {
3193     var index = -1,
3194         length = array ? array.length : 0;
3195
3196     if (typeof fromIndex == 'number') {
3197       index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1;
3198     } else if (fromIndex) {
3199       index = sortedIndex(array, value);
3200       return array[index] === value ? index : -1;
3201     }
3202     while (++index < length) {
3203       if (array[index] === value) {
3204         return index;
3205       }
3206     }
3207     return -1;
3208   }
3209
3210   /**
3211    * Gets all but the last element of `array`. If a number `n` is passed, the
3212    * last `n` elements are excluded from the result. If a `callback` function
3213    * is passed, the last elements the `callback` returns truthy for are excluded
3214    * from the result. The `callback` is bound to `thisArg` and invoked with three
3215    * arguments; (value, index, array).
3216    *
3217    * If a property name is passed for `callback`, the created "_.pluck" style
3218    * callback will return the property value of the given element.
3219    *
3220    * If an object is passed for `callback`, the created "_.where" style callback
3221    * will return `true` for elements that have the propeties of the given object,
3222    * else `false`.
3223    *
3224    * @static
3225    * @memberOf _
3226    * @category Arrays
3227    * @param {Array} array The array to query.
3228    * @param {Function|Object|Number|String} [callback|n=1] The function called
3229    *  per element or the number of elements to exclude. If a property name or
3230    *  object is passed, it will be used to create a "_.pluck" or "_.where"
3231    *  style callback, respectively.
3232    * @param {Mixed} [thisArg] The `this` binding of `callback`.
3233    * @returns {Array} Returns a slice of `array`.
3234    * @example
3235    *
3236    * _.initial([1, 2, 3]);
3237    * // => [1, 2]
3238    *
3239    * _.initial([1, 2, 3], 2);
3240    * // => [1]
3241    *
3242    * _.initial([1, 2, 3], function(num) {
3243    *   return num > 1;
3244    * });
3245    * // => [1]
3246    *
3247    * var food = [
3248    *   { 'name': 'beet',   'organic': false },
3249    *   { 'name': 'carrot', 'organic': true }
3250    * ];
3251    *
3252    * // using "_.pluck" callback shorthand
3253    * _.initial(food, 'organic');
3254    * // => [{ 'name': 'beet',   'organic': false }]
3255    *
3256    * var food = [
3257    *   { 'name': 'banana', 'type': 'fruit' },
3258    *   { 'name': 'beet',   'type': 'vegetable' },
3259    *   { 'name': 'carrot', 'type': 'vegetable' }
3260    * ];
3261    *
3262    * // using "_.where" callback shorthand
3263    * _.initial(food, { 'type': 'vegetable' });
3264    * // => [{ 'name': 'banana', 'type': 'fruit' }]
3265    */
3266   function initial(array, callback, thisArg) {
3267     if (!array) {
3268       return [];
3269     }
3270     var n = 0,
3271         length = array.length;
3272
3273     if (typeof callback != 'number' && callback != null) {
3274       var index = length;
3275       callback = createCallback(callback, thisArg);
3276       while (index-- && callback(array[index], index, array)) {
3277         n++;
3278       }
3279     } else {
3280       n = (callback == null || thisArg) ? 1 : callback || n;
3281     }
3282     return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
3283   }
3284
3285   /**
3286    * Computes the intersection of all the passed-in arrays using strict equality
3287    * for comparisons, i.e. `===`.
3288    *
3289    * @static
3290    * @memberOf _
3291    * @category Arrays
3292    * @param {Array} [array1, array2, ...] Arrays to process.
3293    * @returns {Array} Returns a new array of unique elements that are present
3294    *  in **all** of the arrays.
3295    * @example
3296    *
3297    * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
3298    * // => [1, 2]
3299    */
3300   function intersection(array) {
3301     var args = arguments,
3302         argsLength = args.length,
3303         cache = { '0': {} },
3304         index = -1,
3305         length = array ? array.length : 0,
3306         isLarge = length >= 100,
3307         result = [],
3308         seen = result;
3309
3310     outer:
3311     while (++index < length) {
3312       var value = array[index];
3313       if (isLarge) {
3314         var key = value + '';
3315         var inited = hasOwnProperty.call(cache[0], key)
3316           ? !(seen = cache[0][key])
3317           : (seen = cache[0][key] = []);
3318       }
3319       if (inited || indexOf(seen, value) < 0) {
3320         if (isLarge) {
3321           seen.push(value);
3322         }
3323         var argsIndex = argsLength;
3324         while (--argsIndex) {
3325           if (!(cache[argsIndex] || (cache[argsIndex] = cachedContains(args[argsIndex], 0, 100)))(value)) {
3326             continue outer;
3327           }
3328         }
3329         result.push(value);
3330       }
3331     }
3332     return result;
3333   }
3334
3335   /**
3336    * Gets the last element of the `array`. If a number `n` is passed, the last
3337    * `n` elements of the `array` are returned. If a `callback` function is passed,
3338    * the last elements the `callback` returns truthy for are returned. The `callback`
3339    * is bound to `thisArg` and invoked with three arguments; (value, index, array).
3340    *
3341    *
3342    * If a property name is passed for `callback`, the created "_.pluck" style
3343    * callback will return the property value of the given element.
3344    *
3345    * If an object is passed for `callback`, the created "_.where" style callback
3346    * will return `true` for elements that have the propeties of the given object,
3347    * else `false`.
3348    *
3349    * @static
3350    * @memberOf _
3351    * @category Arrays
3352    * @param {Array} array The array to query.
3353    * @param {Function|Object|Number|String} [callback|n] The function called
3354    *  per element or the number of elements to return. If a property name or
3355    *  object is passed, it will be used to create a "_.pluck" or "_.where"
3356    *  style callback, respectively.
3357    * @param {Mixed} [thisArg] The `this` binding of `callback`.
3358    * @returns {Mixed} Returns the last element(s) of `array`.
3359    * @example
3360    *
3361    * _.last([1, 2, 3]);
3362    * // => 3
3363    *
3364    * _.last([1, 2, 3], 2);
3365    * // => [2, 3]
3366    *
3367    * _.last([1, 2, 3], function(num) {
3368    *   return num > 1;
3369    * });
3370    * // => [2, 3]
3371    *
3372    * var food = [
3373    *   { 'name': 'beet',   'organic': false },
3374    *   { 'name': 'carrot', 'organic': true }
3375    * ];
3376    *
3377    * // using "_.pluck" callback shorthand
3378    * _.last(food, 'organic');
3379    * // => [{ 'name': 'carrot', 'organic': true }]
3380    *
3381    * var food = [
3382    *   { 'name': 'banana', 'type': 'fruit' },
3383    *   { 'name': 'beet',   'type': 'vegetable' },
3384    *   { 'name': 'carrot', 'type': 'vegetable' }
3385    * ];
3386    *
3387    * // using "_.where" callback shorthand
3388    * _.last(food, { 'type': 'vegetable' });
3389    * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }]
3390    */
3391   function last(array, callback, thisArg) {
3392     if (array) {
3393       var n = 0,
3394           length = array.length;
3395
3396       if (typeof callback != 'number' && callback != null) {
3397         var index = length;
3398         callback = createCallback(callback, thisArg);
3399         while (index-- && callback(array[index], index, array)) {
3400           n++;
3401         }
3402       } else {
3403         n = callback;
3404         if (n == null || thisArg) {
3405           return array[length - 1];
3406         }
3407       }
3408       return slice(array, nativeMax(0, length - n));
3409     }
3410   }
3411
3412   /**
3413    * Gets the index at which the last occurrence of `value` is found using strict
3414    * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
3415    * as the offset from the end of the collection.
3416    *
3417    * @static
3418    * @memberOf _
3419    * @category Arrays
3420    * @param {Array} array The array to search.
3421    * @param {Mixed} value The value to search for.
3422    * @param {Number} [fromIndex=array.length-1] The index to search from.
3423    * @returns {Number} Returns the index of the matched value or `-1`.
3424    * @example
3425    *
3426    * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
3427    * // => 4
3428    *
3429    * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
3430    * // => 1
3431    */
3432   function lastIndexOf(array, value, fromIndex) {
3433     var index = array ? array.length : 0;
3434     if (typeof fromIndex == 'number') {
3435       index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
3436     }
3437     while (index--) {
3438       if (array[index] === value) {
3439         return index;
3440       }
3441     }
3442     return -1;
3443   }
3444
3445   /**
3446    * Creates an object composed from arrays of `keys` and `values`. Pass either
3447    * a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`, or
3448    * two arrays, one of `keys` and one of corresponding `values`.
3449    *
3450    * @static
3451    * @memberOf _
3452    * @category Arrays
3453    * @param {Array} keys The array of keys.
3454    * @param {Array} [values=[]] The array of values.
3455    * @returns {Object} Returns an object composed of the given keys and
3456    *  corresponding values.
3457    * @example
3458    *
3459    * _.object(['moe', 'larry'], [30, 40]);
3460    * // => { 'moe': 30, 'larry': 40 }
3461    */
3462   function object(keys, values) {
3463     var index = -1,
3464         length = keys ? keys.length : 0,
3465         result = {};
3466
3467     while (++index < length) {
3468       var key = keys[index];
3469       if (values) {
3470         result[key] = values[index];
3471       } else {
3472         result[key[0]] = key[1];
3473       }
3474     }
3475     return result;
3476   }
3477
3478   /**
3479    * Creates an array of numbers (positive and/or negative) progressing from
3480    * `start` up to but not including `end`.
3481    *
3482    * @static
3483    * @memberOf _
3484    * @category Arrays
3485    * @param {Number} [start=0] The start of the range.
3486    * @param {Number} end The end of the range.
3487    * @param {Number} [step=1] The value to increment or descrement by.
3488    * @returns {Array} Returns a new range array.
3489    * @example
3490    *
3491    * _.range(10);
3492    * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3493    *
3494    * _.range(1, 11);
3495    * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
3496    *
3497    * _.range(0, 30, 5);
3498    * // => [0, 5, 10, 15, 20, 25]
3499    *
3500    * _.range(0, -10, -1);
3501    * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
3502    *
3503    * _.range(0);
3504    * // => []
3505    */
3506   function range(start, end, step) {
3507     start = +start || 0;
3508     step = +step || 1;
3509
3510     if (end == null) {
3511       end = start;
3512       start = 0;
3513     }
3514     // use `Array(length)` so V8 will avoid the slower "dictionary" mode
3515     // http://youtu.be/XAqIpGU8ZZk#t=17m25s
3516     var index = -1,
3517         length = nativeMax(0, ceil((end - start) / step)),
3518         result = Array(length);
3519
3520     while (++index < length) {
3521       result[index] = start;
3522       start += step;
3523     }
3524     return result;
3525   }
3526
3527   /**
3528    * The opposite of `_.initial`, this method gets all but the first value of `array`.
3529    * If a number `n` is passed, the first `n` values are excluded from the result.
3530    * If a `callback` function is passed, the first elements the `callback` returns
3531    * truthy for are excluded from the result. The `callback` is bound to `thisArg`
3532    * and invoked with three arguments; (value, index, array).
3533    *
3534    * If a property name is passed for `callback`, the created "_.pluck" style
3535    * callback will return the property value of the given element.
3536    *
3537    * If an object is passed for `callback`, the created "_.where" style callback
3538    * will return `true` for elements that have the propeties of the given object,
3539    * else `false`.
3540    *
3541    * @static
3542    * @memberOf _
3543    * @alias drop, tail
3544    * @category Arrays
3545    * @param {Array} array The array to query.
3546    * @param {Function|Object|Number|String} [callback|n=1] The function called
3547    *  per element or the number of elements to exclude. If a property name or
3548    *  object is passed, it will be used to create a "_.pluck" or "_.where"
3549    *  style callback, respectively.
3550    * @param {Mixed} [thisArg] The `this` binding of `callback`.
3551    * @returns {Array} Returns a slice of `array`.
3552    * @example
3553    *
3554    * _.rest([1, 2, 3]);
3555    * // => [2, 3]
3556    *
3557    * _.rest([1, 2, 3], 2);
3558    * // => [3]
3559    *
3560    * _.rest([1, 2, 3], function(num) {
3561    *   return num < 3;
3562    * });
3563    * // => [3]
3564    *
3565    * var food = [
3566    *   { 'name': 'banana', 'organic': true },
3567    *   { 'name': 'beet',   'organic': false },
3568    * ];
3569    *
3570    * // using "_.pluck" callback shorthand
3571    * _.rest(food, 'organic');
3572    * // => [{ 'name': 'beet', 'organic': false }]
3573    *
3574    * var food = [
3575    *   { 'name': 'apple',  'type': 'fruit' },
3576    *   { 'name': 'banana', 'type': 'fruit' },
3577    *   { 'name': 'beet',   'type': 'vegetable' }
3578    * ];
3579    *
3580    * // using "_.where" callback shorthand
3581    * _.rest(food, { 'type': 'fruit' });
3582    * // => [{ 'name': 'beet', 'type': 'vegetable' }]
3583    */
3584   function rest(array, callback, thisArg) {
3585     if (typeof callback != 'number' && callback != null) {
3586       var n = 0,
3587           index = -1,
3588           length = array ? array.length : 0;
3589
3590       callback = createCallback(callback, thisArg);
3591       while (++index < length && callback(array[index], index, array)) {
3592         n++;
3593       }
3594     } else {
3595       n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
3596     }
3597     return slice(array, n);
3598   }
3599
3600   /**
3601    * Uses a binary search to determine the smallest index at which the `value`
3602    * should be inserted into `array` in order to maintain the sort order of the
3603    * sorted `array`. If `callback` is passed, it will be executed for `value` and
3604    * each element in `array` to compute their sort ranking. The `callback` is
3605    * bound to `thisArg` and invoked with one argument; (value).
3606    *
3607    * If a property name is passed for `callback`, the created "_.pluck" style
3608    * callback will return the property value of the given element.
3609    *
3610    * If an object is passed for `callback`, the created "_.where" style callback
3611    * will return `true` for elements that have the propeties of the given object,
3612    * else `false`.
3613    *
3614    * @static
3615    * @memberOf _
3616    * @category Arrays
3617    * @param {Array} array The array to iterate over.
3618    * @param {Mixed} value The value to evaluate.
3619    * @param {Function|Object|String} [callback=identity] The function called per
3620    *  iteration. If a property name or object is passed, it will be used to create
3621    *  a "_.pluck" or "_.where" style callback, respectively.
3622    * @param {Mixed} [thisArg] The `this` binding of `callback`.
3623    * @returns {Number} Returns the index at which the value should be inserted
3624    *  into `array`.
3625    * @example
3626    *
3627    * _.sortedIndex([20, 30, 50], 40);
3628    * // => 2
3629    *
3630    * // using "_.pluck" callback shorthand
3631    * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
3632    * // => 2
3633    *
3634    * var dict = {
3635    *   'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
3636    * };
3637    *
3638    * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
3639    *   return dict.wordToNumber[word];
3640    * });
3641    * // => 2
3642    *
3643    * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
3644    *   return this.wordToNumber[word];
3645    * }, dict);
3646    * // => 2
3647    */
3648   function sortedIndex(array, value, callback, thisArg) {
3649     var low = 0,
3650         high = array ? array.length : low;
3651
3652     // explicitly reference `identity` for better inlining in Firefox
3653     callback = callback ? createCallback(callback, thisArg, 1) : identity;
3654     value = callback(value);
3655
3656     while (low < high) {
3657       var mid = (low + high) >>> 1;
3658       callback(array[mid]) < value
3659         ? low = mid + 1
3660         : high = mid;
3661     }
3662     return low;
3663   }
3664
3665   /**
3666    * Computes the union of the passed-in arrays using strict equality for
3667    * comparisons, i.e. `===`.
3668    *
3669    * @static
3670    * @memberOf _
3671    * @category Arrays
3672    * @param {Array} [array1, array2, ...] Arrays to process.
3673    * @returns {Array} Returns a new array of unique values, in order, that are
3674    *  present in one or more of the arrays.
3675    * @example
3676    *
3677    * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
3678    * // => [1, 2, 3, 101, 10]
3679    */
3680   function union() {
3681     return uniq(concat.apply(arrayRef, arguments));
3682   }
3683
3684   /**
3685    * Creates a duplicate-value-free version of the `array` using strict equality
3686    * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true`
3687    * for `isSorted` will run a faster algorithm. If `callback` is passed, each
3688    * element of `array` is passed through a callback` before uniqueness is computed.
3689    * The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array).
3690    *
3691    * If a property name is passed for `callback`, the created "_.pluck" style
3692    * callback will return the property value of the given element.
3693    *
3694    * If an object is passed for `callback`, the created "_.where" style callback
3695    * will return `true` for elements that have the propeties of the given object,
3696    * else `false`.
3697    *
3698    * @static
3699    * @memberOf _
3700    * @alias unique
3701    * @category Arrays
3702    * @param {Array} array The array to process.
3703    * @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted.
3704    * @param {Function|Object|String} [callback=identity] The function called per
3705    *  iteration. If a property name or object is passed, it will be used to create
3706    *  a "_.pluck" or "_.where" style callback, respectively.
3707    * @param {Mixed} [thisArg] The `this` binding of `callback`.
3708    * @returns {Array} Returns a duplicate-value-free array.
3709    * @example
3710    *
3711    * _.uniq([1, 2, 1, 3, 1]);
3712    * // => [1, 2, 3]
3713    *
3714    * _.uniq([1, 1, 2, 2, 3], true);
3715    * // => [1, 2, 3]
3716    *
3717    * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return Math.floor(num); });
3718    * // => [1, 2, 3]
3719    *
3720    * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math);
3721    * // => [1, 2, 3]
3722    *
3723    * // using "_.pluck" callback shorthand
3724    * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
3725    * // => [{ 'x': 1 }, { 'x': 2 }]
3726    */
3727   function uniq(array, isSorted, callback, thisArg) {
3728     var index = -1,
3729         length = array ? array.length : 0,
3730         result = [],
3731         seen = result;
3732
3733     // juggle arguments
3734     if (typeof isSorted == 'function') {
3735       thisArg = callback;
3736       callback = isSorted;
3737       isSorted = false;
3738     }
3739     // init value cache for large arrays
3740     var isLarge = !isSorted && length >= 75;
3741     if (isLarge) {
3742       var cache = {};
3743     }
3744     if (callback) {
3745       seen = [];
3746       callback = createCallback(callback, thisArg);
3747     }
3748     while (++index < length) {
3749       var value = array[index],
3750           computed = callback ? callback(value, index, array) : value;
3751
3752       if (isLarge) {
3753         var key = computed + '';
3754         var inited = hasOwnProperty.call(cache, key)
3755           ? !(seen = cache[key])
3756           : (seen = cache[key] = []);
3757       }
3758       if (isSorted
3759             ? !index || seen[seen.length - 1] !== computed
3760             : inited || indexOf(seen, computed) < 0
3761           ) {
3762         if (callback || isLarge) {
3763           seen.push(computed);
3764         }
3765         result.push(value);
3766       }
3767     }
3768     return result;
3769   }
3770
3771   /**
3772    * Creates an array with all occurrences of the passed values removed using
3773    * strict equality for comparisons, i.e. `===`.
3774    *
3775    * @static
3776    * @memberOf _
3777    * @category Arrays
3778    * @param {Array} array The array to filter.
3779    * @param {Mixed} [value1, value2, ...] Values to remove.
3780    * @returns {Array} Returns a new filtered array.
3781    * @example
3782    *
3783    * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
3784    * // => [2, 3, 4]
3785    */
3786   function without(array) {
3787     var index = -1,
3788         length = array ? array.length : 0,
3789         contains = cachedContains(arguments, 1),
3790         result = [];
3791
3792     while (++index < length) {
3793       var value = array[index];
3794       if (!contains(value)) {
3795         result.push(value);
3796       }
3797     }
3798     return result;
3799   }
3800
3801   /**
3802    * Groups the elements of each array at their corresponding indexes. Useful for
3803    * separate data sources that are coordinated through matching array indexes.
3804    * For a matrix of nested arrays, `_.zip.apply(...)` can transpose the matrix
3805    * in a similar fashion.
3806    *
3807    * @static
3808    * @memberOf _
3809    * @category Arrays
3810    * @param {Array} [array1, array2, ...] Arrays to process.
3811    * @returns {Array} Returns a new array of grouped elements.
3812    * @example
3813    *
3814    * _.zip(['moe', 'larry'], [30, 40], [true, false]);
3815    * // => [['moe', 30, true], ['larry', 40, false]]
3816    */
3817   function zip(array) {
3818     var index = -1,
3819         length = array ? max(pluck(arguments, 'length')) : 0,
3820         result = Array(length);
3821
3822     while (++index < length) {
3823       result[index] = pluck(arguments, index);
3824     }
3825     return result;
3826   }
3827
3828   /*--------------------------------------------------------------------------*/
3829
3830   /**
3831    * Creates a function that is restricted to executing `func` only after it is
3832    * called `n` times. The `func` is executed with the `this` binding of the
3833    * created function.
3834    *
3835    * @static
3836    * @memberOf _
3837    * @category Functions
3838    * @param {Number} n The number of times the function must be called before
3839    * it is executed.
3840    * @param {Function} func The function to restrict.
3841    * @returns {Function} Returns the new restricted function.
3842    * @example
3843    *
3844    * var renderNotes = _.after(notes.length, render);
3845    * _.forEach(notes, function(note) {
3846    *   note.asyncSave({ 'success': renderNotes });
3847    * });
3848    * // `renderNotes` is run once, after all notes have saved
3849    */
3850   function after(n, func) {
3851     if (n < 1) {
3852       return func();
3853     }
3854     return function() {
3855       if (--n < 1) {
3856         return func.apply(this, arguments);
3857       }
3858     };
3859   }
3860
3861   /**
3862    * Creates a function that, when called, invokes `func` with the `this`
3863    * binding of `thisArg` and prepends any additional `bind` arguments to those
3864    * passed to the bound function.
3865    *
3866    * @static
3867    * @memberOf _
3868    * @category Functions
3869    * @param {Function} func The function to bind.
3870    * @param {Mixed} [thisArg] The `this` binding of `func`.
3871    * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
3872    * @returns {Function} Returns the new bound function.
3873    * @example
3874    *
3875    * var func = function(greeting) {
3876    *   return greeting + ' ' + this.name;
3877    * };
3878    *
3879    * func = _.bind(func, { 'name': 'moe' }, 'hi');
3880    * func();
3881    * // => 'hi moe'
3882    */
3883   function bind(func, thisArg) {
3884     // use `Function#bind` if it exists and is fast
3885     // (in V8 `Function#bind` is slower except when partially applied)
3886     return isBindFast || (nativeBind && arguments.length > 2)
3887       ? nativeBind.call.apply(nativeBind, arguments)
3888       : createBound(func, thisArg, slice(arguments, 2));
3889   }
3890
3891   /**
3892    * Binds methods on `object` to `object`, overwriting the existing method.
3893    * Method names may be specified as individual arguments or as arrays of method
3894    * names. If no method names are provided, all the function properties of `object`
3895    * will be bound.
3896    *
3897    * @static
3898    * @memberOf _
3899    * @category Functions
3900    * @param {Object} object The object to bind and assign the bound methods to.
3901    * @param {String} [methodName1, methodName2, ...] Method names on the object to bind.
3902    * @returns {Object} Returns `object`.
3903    * @example
3904    *
3905    * var view = {
3906    *  'label': 'docs',
3907    *  'onClick': function() { alert('clicked ' + this.label); }
3908    * };
3909    *
3910    * _.bindAll(view);
3911    * jQuery('#docs').on('click', view.onClick);
3912    * // => alerts 'clicked docs', when the button is clicked
3913    */
3914   function bindAll(object) {
3915     var funcs = concat.apply(arrayRef, arguments),
3916         index = funcs.length > 1 ? 0 : (funcs = functions(object), -1),
3917         length = funcs.length;
3918
3919     while (++index < length) {
3920       var key = funcs[index];
3921       object[key] = bind(object[key], object);
3922     }
3923     return object;
3924   }
3925
3926   /**
3927    * Creates a function that, when called, invokes the method at `object[key]`
3928    * and prepends any additional `bindKey` arguments to those passed to the bound
3929    * function. This method differs from `_.bind` by allowing bound functions to
3930    * reference methods that will be redefined or don't yet exist.
3931    * See http://michaux.ca/articles/lazy-function-definition-pattern.
3932    *
3933    * @static
3934    * @memberOf _
3935    * @category Functions
3936    * @param {Object} object The object the method belongs to.
3937    * @param {String} key The key of the method.
3938    * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
3939    * @returns {Function} Returns the new bound function.
3940    * @example
3941    *
3942    * var object = {
3943    *   'name': 'moe',
3944    *   'greet': function(greeting) {
3945    *     return greeting + ' ' + this.name;
3946    *   }
3947    * };
3948    *
3949    * var func = _.bindKey(object, 'greet', 'hi');
3950    * func();
3951    * // => 'hi moe'
3952    *
3953    * object.greet = function(greeting) {
3954    *   return greeting + ', ' + this.name + '!';
3955    * };
3956    *
3957    * func();
3958    * // => 'hi, moe!'
3959    */
3960   function bindKey(object, key) {
3961     return createBound(object, key, slice(arguments, 2));
3962   }
3963
3964   /**
3965    * Creates a function that is the composition of the passed functions,
3966    * where each function consumes the return value of the function that follows.
3967    * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
3968    * Each function is executed with the `this` binding of the composed function.
3969    *
3970    * @static
3971    * @memberOf _
3972    * @category Functions
3973    * @param {Function} [func1, func2, ...] Functions to compose.
3974    * @returns {Function} Returns the new composed function.
3975    * @example
3976    *
3977    * var greet = function(name) { return 'hi ' + name; };
3978    * var exclaim = function(statement) { return statement + '!'; };
3979    * var welcome = _.compose(exclaim, greet);
3980    * welcome('moe');
3981    * // => 'hi moe!'
3982    */
3983   function compose() {
3984     var funcs = arguments;
3985     return function() {
3986       var args = arguments,
3987           length = funcs.length;
3988
3989       while (length--) {
3990         args = [funcs[length].apply(this, args)];
3991       }
3992       return args[0];
3993     };
3994   }
3995
3996   /**
3997    * Creates a function that will delay the execution of `func` until after
3998    * `wait` milliseconds have elapsed since the last time it was invoked. Pass
3999    * `true` for `immediate` to cause debounce to invoke `func` on the leading,
4000    * instead of the trailing, edge of the `wait` timeout. Subsequent calls to
4001    * the debounced function will return the result of the last `func` call.
4002    *
4003    * @static
4004    * @memberOf _
4005    * @category Functions
4006    * @param {Function} func The function to debounce.
4007    * @param {Number} wait The number of milliseconds to delay.
4008    * @param {Boolean} immediate A flag to indicate execution is on the leading
4009    *  edge of the timeout.
4010    * @returns {Function} Returns the new debounced function.
4011    * @example
4012    *
4013    * var lazyLayout = _.debounce(calculateLayout, 300);
4014    * jQuery(window).on('resize', lazyLayout);
4015    */
4016   function debounce(func, wait, immediate) {
4017     var args,
4018         result,
4019         thisArg,
4020         timeoutId;
4021
4022     function delayed() {
4023       timeoutId = null;
4024       if (!immediate) {
4025         result = func.apply(thisArg, args);
4026       }
4027     }
4028     return function() {
4029       var isImmediate = immediate && !timeoutId;
4030       args = arguments;
4031       thisArg = this;
4032
4033       clearTimeout(timeoutId);
4034       timeoutId = setTimeout(delayed, wait);
4035
4036       if (isImmediate) {
4037         result = func.apply(thisArg, args);
4038       }
4039       return result;
4040     };
4041   }
4042
4043   /**
4044    * Executes the `func` function after `wait` milliseconds. Additional arguments
4045    * will be passed to `func` when it is invoked.
4046    *
4047    * @static
4048    * @memberOf _
4049    * @category Functions
4050    * @param {Function} func The function to delay.
4051    * @param {Number} wait The number of milliseconds to delay execution.
4052    * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
4053    * @returns {Number} Returns the `setTimeout` timeout id.
4054    * @example
4055    *
4056    * var log = _.bind(console.log, console);
4057    * _.delay(log, 1000, 'logged later');
4058    * // => 'logged later' (Appears after one second.)
4059    */
4060   function delay(func, wait) {
4061     var args = slice(arguments, 2);
4062     return setTimeout(function() { func.apply(undefined, args); }, wait);
4063   }
4064
4065   /**
4066    * Defers executing the `func` function until the current call stack has cleared.
4067    * Additional arguments will be passed to `func` when it is invoked.
4068    *
4069    * @static
4070    * @memberOf _
4071    * @category Functions
4072    * @param {Function} func The function to defer.
4073    * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
4074    * @returns {Number} Returns the `setTimeout` timeout id.
4075    * @example
4076    *
4077    * _.defer(function() { alert('deferred'); });
4078    * // returns from the function before `alert` is called
4079    */
4080   function defer(func) {
4081     var args = slice(arguments, 1);
4082     return setTimeout(function() { func.apply(undefined, args); }, 1);
4083   }
4084   // use `setImmediate` if it's available in Node.js
4085   if (isV8 && freeModule && typeof setImmediate == 'function') {
4086     defer = bind(setImmediate, window);
4087   }
4088
4089   /**
4090    * Creates a function that memoizes the result of `func`. If `resolver` is
4091    * passed, it will be used to determine the cache key for storing the result
4092    * based on the arguments passed to the memoized function. By default, the first
4093    * argument passed to the memoized function is used as the cache key. The `func`
4094    * is executed with the `this` binding of the memoized function.
4095    *
4096    * @static
4097    * @memberOf _
4098    * @category Functions
4099    * @param {Function} func The function to have its output memoized.
4100    * @param {Function} [resolver] A function used to resolve the cache key.
4101    * @returns {Function} Returns the new memoizing function.
4102    * @example
4103    *
4104    * var fibonacci = _.memoize(function(n) {
4105    *   return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
4106    * });
4107    */
4108   function memoize(func, resolver) {
4109     var cache = {};
4110     return function() {
4111       var key = (resolver ? resolver.apply(this, arguments) : arguments[0]) + '';
4112       return hasOwnProperty.call(cache, key)
4113         ? cache[key]
4114         : (cache[key] = func.apply(this, arguments));
4115     };
4116   }
4117
4118   /**
4119    * Creates a function that is restricted to execute `func` once. Repeat calls to
4120    * the function will return the value of the first call. The `func` is executed
4121    * with the `this` binding of the created function.
4122    *
4123    * @static
4124    * @memberOf _
4125    * @category Functions
4126    * @param {Function} func The function to restrict.
4127    * @returns {Function} Returns the new restricted function.
4128    * @example
4129    *
4130    * var initialize = _.once(createApplication);
4131    * initialize();
4132    * initialize();
4133    * // `initialize` executes `createApplication` once
4134    */
4135   function once(func) {
4136     var ran,
4137         result;
4138
4139     return function() {
4140       if (ran) {
4141         return result;
4142       }
4143       ran = true;
4144       result = func.apply(this, arguments);
4145
4146       // clear the `func` variable so the function may be garbage collected
4147       func = null;
4148       return result;
4149     };
4150   }
4151
4152   /**
4153    * Creates a function that, when called, invokes `func` with any additional
4154    * `partial` arguments prepended to those passed to the new function. This
4155    * method is similar to `_.bind`, except it does **not** alter the `this` binding.
4156    *
4157    * @static
4158    * @memberOf _
4159    * @category Functions
4160    * @param {Function} func The function to partially apply arguments to.
4161    * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
4162    * @returns {Function} Returns the new partially applied function.
4163    * @example
4164    *
4165    * var greet = function(greeting, name) { return greeting + ' ' + name; };
4166    * var hi = _.partial(greet, 'hi');
4167    * hi('moe');
4168    * // => 'hi moe'
4169    */
4170   function partial(func) {
4171     return createBound(func, slice(arguments, 1));
4172   }
4173
4174   /**
4175    * This method is similar to `_.partial`, except that `partial` arguments are
4176    * appended to those passed to the new function.
4177    *
4178    * @static
4179    * @memberOf _
4180    * @category Functions
4181    * @param {Function} func The function to partially apply arguments to.
4182    * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
4183    * @returns {Function} Returns the new partially applied function.
4184    * @example
4185    *
4186    * var defaultsDeep = _.partialRight(_.merge, _.defaults);
4187    *
4188    * var options = {
4189    *   'variable': 'data',
4190    *   'imports': { 'jq': $ }
4191    * };
4192    *
4193    * defaultsDeep(options, _.templateSettings);
4194    *
4195    * options.variable
4196    * // => 'data'
4197    *
4198    * options.imports
4199    * // => { '_': _, 'jq': $ }
4200    */
4201   function partialRight(func) {
4202     return createBound(func, slice(arguments, 1), null, indicatorObject);
4203   }
4204
4205   /**
4206    * Creates a function that, when executed, will only call the `func`
4207    * function at most once per every `wait` milliseconds. If the throttled
4208    * function is invoked more than once during the `wait` timeout, `func` will
4209    * also be called on the trailing edge of the timeout. Subsequent calls to the
4210    * throttled function will return the result of the last `func` call.
4211    *
4212    * @static
4213    * @memberOf _
4214    * @category Functions
4215    * @param {Function} func The function to throttle.
4216    * @param {Number} wait The number of milliseconds to throttle executions to.
4217    * @returns {Function} Returns the new throttled function.
4218    * @example
4219    *
4220    * var throttled = _.throttle(updatePosition, 100);
4221    * jQuery(window).on('scroll', throttled);
4222    */
4223   function throttle(func, wait) {
4224     var args,
4225         result,
4226         thisArg,
4227         timeoutId,
4228         lastCalled = 0;
4229
4230     function trailingCall() {
4231       lastCalled = new Date;
4232       timeoutId = null;
4233       result = func.apply(thisArg, args);
4234     }
4235     return function() {
4236       var now = new Date,
4237           remaining = wait - (now - lastCalled);
4238
4239       args = arguments;
4240       thisArg = this;
4241
4242       if (remaining <= 0) {
4243         clearTimeout(timeoutId);
4244         timeoutId = null;
4245         lastCalled = now;
4246         result = func.apply(thisArg, args);
4247       }
4248       else if (!timeoutId) {
4249         timeoutId = setTimeout(trailingCall, remaining);
4250       }
4251       return result;
4252     };
4253   }
4254
4255   /**
4256    * Creates a function that passes `value` to the `wrapper` function as its
4257    * first argument. Additional arguments passed to the function are appended
4258    * to those passed to the `wrapper` function. The `wrapper` is executed with
4259    * the `this` binding of the created function.
4260    *
4261    * @static
4262    * @memberOf _
4263    * @category Functions
4264    * @param {Mixed} value The value to wrap.
4265    * @param {Function} wrapper The wrapper function.
4266    * @returns {Function} Returns the new function.
4267    * @example
4268    *
4269    * var hello = function(name) { return 'hello ' + name; };
4270    * hello = _.wrap(hello, function(func) {
4271    *   return 'before, ' + func('moe') + ', after';
4272    * });
4273    * hello();
4274    * // => 'before, hello moe, after'
4275    */
4276   function wrap(value, wrapper) {
4277     return function() {
4278       var args = [value];
4279       push.apply(args, arguments);
4280       return wrapper.apply(this, args);
4281     };
4282   }
4283
4284   /*--------------------------------------------------------------------------*/
4285
4286   /**
4287    * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
4288    * corresponding HTML entities.
4289    *
4290    * @static
4291    * @memberOf _
4292    * @category Utilities
4293    * @param {String} string The string to escape.
4294    * @returns {String} Returns the escaped string.
4295    * @example
4296    *
4297    * _.escape('Moe, Larry & Curly');
4298    * // => 'Moe, Larry &amp; Curly'
4299    */
4300   function escape(string) {
4301     return string == null ? '' : (string + '').replace(reUnescapedHtml, escapeHtmlChar);
4302   }
4303
4304   /**
4305    * This function returns the first argument passed to it.
4306    *
4307    * @static
4308    * @memberOf _
4309    * @category Utilities
4310    * @param {Mixed} value Any value.
4311    * @returns {Mixed} Returns `value`.
4312    * @example
4313    *
4314    * var moe = { 'name': 'moe' };
4315    * moe === _.identity(moe);
4316    * // => true
4317    */
4318   function identity(value) {
4319     return value;
4320   }
4321
4322   /**
4323    * Adds functions properties of `object` to the `lodash` function and chainable
4324    * wrapper.
4325    *
4326    * @static
4327    * @memberOf _
4328    * @category Utilities
4329    * @param {Object} object The object of function properties to add to `lodash`.
4330    * @example
4331    *
4332    * _.mixin({
4333    *   'capitalize': function(string) {
4334    *     return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
4335    *   }
4336    * });
4337    *
4338    * _.capitalize('moe');
4339    * // => 'Moe'
4340    *
4341    * _('moe').capitalize();
4342    * // => 'Moe'
4343    */
4344   function mixin(object) {
4345     forEach(functions(object), function(methodName) {
4346       var func = lodash[methodName] = object[methodName];
4347
4348       lodash.prototype[methodName] = function() {
4349         var args = [this.__wrapped__];
4350         push.apply(args, arguments);
4351         return new lodash(func.apply(lodash, args));
4352       };
4353     });
4354   }
4355
4356   /**
4357    * Reverts the '_' variable to its previous value and returns a reference to
4358    * the `lodash` function.
4359    *
4360    * @static
4361    * @memberOf _
4362    * @category Utilities
4363    * @returns {Function} Returns the `lodash` function.
4364    * @example
4365    *
4366    * var lodash = _.noConflict();
4367    */
4368   function noConflict() {
4369     window._ = oldDash;
4370     return this;
4371   }
4372
4373   /**
4374    * Produces a random number between `min` and `max` (inclusive). If only one
4375    * argument is passed, a number between `0` and the given number will be returned.
4376    *
4377    * @static
4378    * @memberOf _
4379    * @category Utilities
4380    * @param {Number} [min=0] The minimum possible value.
4381    * @param {Number} [max=1] The maximum possible value.
4382    * @returns {Number} Returns a random number.
4383    * @example
4384    *
4385    * _.random(0, 5);
4386    * // => a number between 0 and 5
4387    *
4388    * _.random(5);
4389    * // => also a number between 0 and 5
4390    */
4391   function random(min, max) {
4392     if (min == null && max == null) {
4393       max = 1;
4394     }
4395     min = +min || 0;
4396     if (max == null) {
4397       max = min;
4398       min = 0;
4399     }
4400     return min + floor(nativeRandom() * ((+max || 0) - min + 1));
4401   }
4402
4403   /**
4404    * Resolves the value of `property` on `object`. If `property` is a function,
4405    * it will be invoked and its result returned, else the property value is
4406    * returned. If `object` is falsey, then `null` is returned.
4407    *
4408    * @static
4409    * @memberOf _
4410    * @category Utilities
4411    * @param {Object} object The object to inspect.
4412    * @param {String} property The property to get the value of.
4413    * @returns {Mixed} Returns the resolved value.
4414    * @example
4415    *
4416    * var object = {
4417    *   'cheese': 'crumpets',
4418    *   'stuff': function() {
4419    *     return 'nonsense';
4420    *   }
4421    * };
4422    *
4423    * _.result(object, 'cheese');
4424    * // => 'crumpets'
4425    *
4426    * _.result(object, 'stuff');
4427    * // => 'nonsense'
4428    */
4429   function result(object, property) {
4430     var value = object ? object[property] : undefined;
4431     return isFunction(value) ? object[property]() : value;
4432   }
4433
4434   /**
4435    * A micro-templating method that handles arbitrary delimiters, preserves
4436    * whitespace, and correctly escapes quotes within interpolated code.
4437    *
4438    * Note: In the development build, `_.template` utilizes sourceURLs for easier
4439    * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
4440    *
4441    * Note: Lo-Dash may be used in Chrome extensions by either creating a `lodash csp`
4442    * build and using precompiled templates, or loading Lo-Dash in a sandbox.
4443    *
4444    * For more information on precompiling templates see:
4445    * http://lodash.com/#custom-builds
4446    *
4447    * For more information on Chrome extension sandboxes see:
4448    * http://developer.chrome.com/stable/extensions/sandboxingEval.html
4449    *
4450    * @static
4451    * @memberOf _
4452    * @category Utilities
4453    * @param {String} text The template text.
4454    * @param {Obect} data The data object used to populate the text.
4455    * @param {Object} options The options object.
4456    *  escape - The "escape" delimiter regexp.
4457    *  evaluate - The "evaluate" delimiter regexp.
4458    *  interpolate - The "interpolate" delimiter regexp.
4459    *  sourceURL - The sourceURL of the template's compiled source.
4460    *  variable - The data object variable name.
4461    *
4462    * @returns {Function|String} Returns a compiled function when no `data` object
4463    *  is given, else it returns the interpolated text.
4464    * @example
4465    *
4466    * // using a compiled template
4467    * var compiled = _.template('hello <%= name %>');
4468    * compiled({ 'name': 'moe' });
4469    * // => 'hello moe'
4470    *
4471    * var list = '<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>';
4472    * _.template(list, { 'people': ['moe', 'larry'] });
4473    * // => '<li>moe</li><li>larry</li>'
4474    *
4475    * // using the "escape" delimiter to escape HTML in data property values
4476    * _.template('<b><%- value %></b>', { 'value': '<script>' });
4477    * // => '<b>&lt;script&gt;</b>'
4478    *
4479    * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
4480    * _.template('hello ${ name }', { 'name': 'curly' });
4481    * // => 'hello curly'
4482    *
4483    * // using the internal `print` function in "evaluate" delimiters
4484    * _.template('<% print("hello " + epithet); %>!', { 'epithet': 'stooge' });
4485    * // => 'hello stooge!'
4486    *
4487    * // using custom template delimiters
4488    * _.templateSettings = {
4489    *   'interpolate': /{{([\s\S]+?)}}/g
4490    * };
4491    *
4492    * _.template('hello {{ name }}!', { 'name': 'mustache' });
4493    * // => 'hello mustache!'
4494    *
4495    * // using the `sourceURL` option to specify a custom sourceURL for the template
4496    * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
4497    * compiled(data);
4498    * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
4499    *
4500    * // using the `variable` option to ensure a with-statement isn't used in the compiled template
4501    * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
4502    * compiled.source;
4503    * // => function(data) {
4504    *   var __t, __p = '', __e = _.escape;
4505    *   __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
4506    *   return __p;
4507    * }
4508    *
4509    * // using the `source` property to inline compiled templates for meaningful
4510    * // line numbers in error messages and a stack trace
4511    * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
4512    *   var JST = {\
4513    *     "main": ' + _.template(mainText).source + '\
4514    *   };\
4515    * ');
4516    */
4517   function template(text, data, options) {
4518     // based on John Resig's `tmpl` implementation
4519     // http://ejohn.org/blog/javascript-micro-templating/
4520     // and Laura Doktorova's doT.js
4521     // https://github.com/olado/doT
4522     var settings = lodash.templateSettings;
4523     text || (text = '');
4524
4525     // avoid missing dependencies when `iteratorTemplate` is not defined
4526     options = defaults({}, options, settings);
4527
4528     var imports = defaults({}, options.imports, settings.imports),
4529         importsKeys = keys(imports),
4530         importsValues = values(imports);
4531
4532     var isEvaluating,
4533         index = 0,
4534         interpolate = options.interpolate || reNoMatch,
4535         source = "__p += '";
4536
4537     // compile regexp to match each delimiter
4538     var reDelimiters = RegExp(
4539       (options.escape || reNoMatch).source + '|' +
4540       interpolate.source + '|' +
4541       (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
4542       (options.evaluate || reNoMatch).source + '|$'
4543     , 'g');
4544
4545     text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
4546       interpolateValue || (interpolateValue = esTemplateValue);
4547
4548       // escape characters that cannot be included in string literals
4549       source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
4550
4551       // replace delimiters with snippets
4552       if (escapeValue) {
4553         source += "' +\n__e(" + escapeValue + ") +\n'";
4554       }
4555       if (evaluateValue) {
4556         isEvaluating = true;
4557         source += "';\n" + evaluateValue + ";\n__p += '";
4558       }
4559       if (interpolateValue) {
4560         source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
4561       }
4562       index = offset + match.length;
4563
4564       // the JS engine embedded in Adobe products requires returning the `match`
4565       // string in order to produce the correct `offset` value
4566       return match;
4567     });
4568
4569     source += "';\n";
4570
4571     // if `variable` is not specified and the template contains "evaluate"
4572     // delimiters, wrap a with-statement around the generated code to add the
4573     // data object to the top of the scope chain
4574     var variable = options.variable,
4575         hasVariable = variable;
4576
4577     if (!hasVariable) {
4578       variable = 'obj';
4579       source = 'with (' + variable + ') {\n' + source + '\n}\n';
4580     }
4581     // cleanup code by stripping empty strings
4582     source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
4583       .replace(reEmptyStringMiddle, '$1')
4584       .replace(reEmptyStringTrailing, '$1;');
4585
4586     // frame code as the function body
4587     source = 'function(' + variable + ') {\n' +
4588       (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
4589       "var __t, __p = '', __e = _.escape" +
4590       (isEvaluating
4591         ? ', __j = Array.prototype.join;\n' +
4592           "function print() { __p += __j.call(arguments, '') }\n"
4593         : ';\n'
4594       ) +
4595       source +
4596       'return __p\n}';
4597
4598     // Use a sourceURL for easier debugging and wrap in a multi-line comment to
4599     // avoid issues with Narwhal, IE conditional compilation, and the JS engine
4600     // embedded in Adobe products.
4601     // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
4602     var sourceURL = '\n/*\n//@ sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
4603
4604     try {
4605       var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
4606     } catch(e) {
4607       e.source = source;
4608       throw e;
4609     }
4610     if (data) {
4611       return result(data);
4612     }
4613     // provide the compiled function's source via its `toString` method, in
4614     // supported environments, or the `source` property as a convenience for
4615     // inlining compiled templates during the build process
4616     result.source = source;
4617     return result;
4618   }
4619
4620   /**
4621    * Executes the `callback` function `n` times, returning an array of the results
4622    * of each `callback` execution. The `callback` is bound to `thisArg` and invoked
4623    * with one argument; (index).
4624    *
4625    * @static
4626    * @memberOf _
4627    * @category Utilities
4628    * @param {Number} n The number of times to execute the callback.
4629    * @param {Function} callback The function called per iteration.
4630    * @param {Mixed} [thisArg] The `this` binding of `callback`.
4631    * @returns {Array} Returns a new array of the results of each `callback` execution.
4632    * @example
4633    *
4634    * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
4635    * // => [3, 6, 4]
4636    *
4637    * _.times(3, function(n) { mage.castSpell(n); });
4638    * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
4639    *
4640    * _.times(3, function(n) { this.cast(n); }, mage);
4641    * // => also calls `mage.castSpell(n)` three times
4642    */
4643   function times(n, callback, thisArg) {
4644     n = +n || 0;
4645     var index = -1,
4646         result = Array(n);
4647
4648     while (++index < n) {
4649       result[index] = callback.call(thisArg, index);
4650     }
4651     return result;
4652   }
4653
4654   /**
4655    * The opposite of `_.escape`, this method converts the HTML entities
4656    * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to their
4657    * corresponding characters.
4658    *
4659    * @static
4660    * @memberOf _
4661    * @category Utilities
4662    * @param {String} string The string to unescape.
4663    * @returns {String} Returns the unescaped string.
4664    * @example
4665    *
4666    * _.unescape('Moe, Larry &amp; Curly');
4667    * // => 'Moe, Larry & Curly'
4668    */
4669   function unescape(string) {
4670     return string == null ? '' : (string + '').replace(reEscapedHtml, unescapeHtmlChar);
4671   }
4672
4673   /**
4674    * Generates a unique ID. If `prefix` is passed, the ID will be appended to it.
4675    *
4676    * @static
4677    * @memberOf _
4678    * @category Utilities
4679    * @param {String} [prefix] The value to prefix the ID with.
4680    * @returns {String} Returns the unique ID.
4681    * @example
4682    *
4683    * _.uniqueId('contact_');
4684    * // => 'contact_104'
4685    *
4686    * _.uniqueId();
4687    * // => '105'
4688    */
4689   function uniqueId(prefix) {
4690     var id = ++idCounter;
4691     return (prefix == null ? '' : prefix + '') + id;
4692   }
4693
4694   /*--------------------------------------------------------------------------*/
4695
4696   /**
4697    * Invokes `interceptor` with the `value` as the first argument, and then
4698    * returns `value`. The purpose of this method is to "tap into" a method chain,
4699    * in order to perform operations on intermediate results within the chain.
4700    *
4701    * @static
4702    * @memberOf _
4703    * @category Chaining
4704    * @param {Mixed} value The value to pass to `interceptor`.
4705    * @param {Function} interceptor The function to invoke.
4706    * @returns {Mixed} Returns `value`.
4707    * @example
4708    *
4709    * _([1, 2, 3, 4])
4710    *  .filter(function(num) { return num % 2 == 0; })
4711    *  .tap(alert)
4712    *  .map(function(num) { return num * num; })
4713    *  .value();
4714    * // => // [2, 4] (alerted)
4715    * // => [4, 16]
4716    */
4717   function tap(value, interceptor) {
4718     interceptor(value);
4719     return value;
4720   }
4721
4722   /**
4723    * Produces the `toString` result of the wrapped value.
4724    *
4725    * @name toString
4726    * @memberOf _
4727    * @category Chaining
4728    * @returns {String} Returns the string result.
4729    * @example
4730    *
4731    * _([1, 2, 3]).toString();
4732    * // => '1,2,3'
4733    */
4734   function wrapperToString() {
4735     return this.__wrapped__ + '';
4736   }
4737
4738   /**
4739    * Extracts the wrapped value.
4740    *
4741    * @name valueOf
4742    * @memberOf _
4743    * @alias value
4744    * @category Chaining
4745    * @returns {Mixed} Returns the wrapped value.
4746    * @example
4747    *
4748    * _([1, 2, 3]).valueOf();
4749    * // => [1, 2, 3]
4750    */
4751   function wrapperValueOf() {
4752     return this.__wrapped__;
4753   }
4754
4755   /*--------------------------------------------------------------------------*/
4756
4757   // add functions that return wrapped values when chaining
4758   lodash.after = after;
4759   lodash.assign = assign;
4760   lodash.at = at;
4761   lodash.bind = bind;
4762   lodash.bindAll = bindAll;
4763   lodash.bindKey = bindKey;
4764   lodash.compact = compact;
4765   lodash.compose = compose;
4766   lodash.countBy = countBy;
4767   lodash.debounce = debounce;
4768   lodash.defaults = defaults;
4769   lodash.defer = defer;
4770   lodash.delay = delay;
4771   lodash.difference = difference;
4772   lodash.filter = filter;
4773   lodash.flatten = flatten;
4774   lodash.forEach = forEach;
4775   lodash.forIn = forIn;
4776   lodash.forOwn = forOwn;
4777   lodash.functions = functions;
4778   lodash.groupBy = groupBy;
4779   lodash.initial = initial;
4780   lodash.intersection = intersection;
4781   lodash.invert = invert;
4782   lodash.invoke = invoke;
4783   lodash.keys = keys;
4784   lodash.map = map;
4785   lodash.max = max;
4786   lodash.memoize = memoize;
4787   lodash.merge = merge;
4788   lodash.min = min;
4789   lodash.object = object;
4790   lodash.omit = omit;
4791   lodash.once = once;
4792   lodash.pairs = pairs;
4793   lodash.partial = partial;
4794   lodash.partialRight = partialRight;
4795   lodash.pick = pick;
4796   lodash.pluck = pluck;
4797   lodash.range = range;
4798   lodash.reject = reject;
4799   lodash.rest = rest;
4800   lodash.shuffle = shuffle;
4801   lodash.sortBy = sortBy;
4802   lodash.tap = tap;
4803   lodash.throttle = throttle;
4804   lodash.times = times;
4805   lodash.toArray = toArray;
4806   lodash.union = union;
4807   lodash.uniq = uniq;
4808   lodash.values = values;
4809   lodash.where = where;
4810   lodash.without = without;
4811   lodash.wrap = wrap;
4812   lodash.zip = zip;
4813
4814   // add aliases
4815   lodash.collect = map;
4816   lodash.drop = rest;
4817   lodash.each = forEach;
4818   lodash.extend = assign;
4819   lodash.methods = functions;
4820   lodash.select = filter;
4821   lodash.tail = rest;
4822   lodash.unique = uniq;
4823
4824   // add functions to `lodash.prototype`
4825   mixin(lodash);
4826
4827   /*--------------------------------------------------------------------------*/
4828
4829   // add functions that return unwrapped values when chaining
4830   lodash.clone = clone;
4831   lodash.cloneDeep = cloneDeep;
4832   lodash.contains = contains;
4833   lodash.escape = escape;
4834   lodash.every = every;
4835   lodash.find = find;
4836   lodash.has = has;
4837   lodash.identity = identity;
4838   lodash.indexOf = indexOf;
4839   lodash.isArguments = isArguments;
4840   lodash.isArray = isArray;
4841   lodash.isBoolean = isBoolean;
4842   lodash.isDate = isDate;
4843   lodash.isElement = isElement;
4844   lodash.isEmpty = isEmpty;
4845   lodash.isEqual = isEqual;
4846   lodash.isFinite = isFinite;
4847   lodash.isFunction = isFunction;
4848   lodash.isNaN = isNaN;
4849   lodash.isNull = isNull;
4850   lodash.isNumber = isNumber;
4851   lodash.isObject = isObject;
4852   lodash.isPlainObject = isPlainObject;
4853   lodash.isRegExp = isRegExp;
4854   lodash.isString = isString;
4855   lodash.isUndefined = isUndefined;
4856   lodash.lastIndexOf = lastIndexOf;
4857   lodash.mixin = mixin;
4858   lodash.noConflict = noConflict;
4859   lodash.random = random;
4860   lodash.reduce = reduce;
4861   lodash.reduceRight = reduceRight;
4862   lodash.result = result;
4863   lodash.size = size;
4864   lodash.some = some;
4865   lodash.sortedIndex = sortedIndex;
4866   lodash.template = template;
4867   lodash.unescape = unescape;
4868   lodash.uniqueId = uniqueId;
4869
4870   // add aliases
4871   lodash.all = every;
4872   lodash.any = some;
4873   lodash.detect = find;
4874   lodash.foldl = reduce;
4875   lodash.foldr = reduceRight;
4876   lodash.include = contains;
4877   lodash.inject = reduce;
4878
4879   forOwn(lodash, function(func, methodName) {
4880     if (!lodash.prototype[methodName]) {
4881       lodash.prototype[methodName] = function() {
4882         var args = [this.__wrapped__];
4883         push.apply(args, arguments);
4884         return func.apply(lodash, args);
4885       };
4886     }
4887   });
4888
4889   /*--------------------------------------------------------------------------*/
4890
4891   // add functions capable of returning wrapped and unwrapped values when chaining
4892   lodash.first = first;
4893   lodash.last = last;
4894
4895   // add aliases
4896   lodash.take = first;
4897   lodash.head = first;
4898
4899   forOwn(lodash, function(func, methodName) {
4900     if (!lodash.prototype[methodName]) {
4901       lodash.prototype[methodName]= function(callback, thisArg) {
4902         var result = func(this.__wrapped__, callback, thisArg);
4903         return callback == null || (thisArg && typeof callback != 'function')
4904           ? result
4905           : new lodash(result);
4906       };
4907     }
4908   });
4909
4910   /*--------------------------------------------------------------------------*/
4911
4912   /**
4913    * The semantic version number.
4914    *
4915    * @static
4916    * @memberOf _
4917    * @type String
4918    */
4919   lodash.VERSION = '1.0.2';
4920
4921   // add "Chaining" functions to the wrapper
4922   lodash.prototype.toString = wrapperToString;
4923   lodash.prototype.value = wrapperValueOf;
4924   lodash.prototype.valueOf = wrapperValueOf;
4925
4926   // add `Array` functions that return unwrapped values
4927   each(['join', 'pop', 'shift'], function(methodName) {
4928     var func = arrayRef[methodName];
4929     lodash.prototype[methodName] = function() {
4930       return func.apply(this.__wrapped__, arguments);
4931     };
4932   });
4933
4934   // add `Array` functions that return the wrapped value
4935   each(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
4936     var func = arrayRef[methodName];
4937     lodash.prototype[methodName] = function() {
4938       func.apply(this.__wrapped__, arguments);
4939       return this;
4940     };
4941   });
4942
4943   // add `Array` functions that return new wrapped values
4944   each(['concat', 'slice', 'splice'], function(methodName) {
4945     var func = arrayRef[methodName];
4946     lodash.prototype[methodName] = function() {
4947       return new lodash(func.apply(this.__wrapped__, arguments));
4948     };
4949   });
4950
4951   /*--------------------------------------------------------------------------*/
4952
4953   // expose Lo-Dash
4954   // some AMD build optimizers, like r.js, check for specific condition patterns like the following:
4955   if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
4956     // Expose Lo-Dash to the global object even when an AMD loader is present in
4957     // case Lo-Dash was injected by a third-party script and not intended to be
4958     // loaded as a module. The global assignment can be reverted in the Lo-Dash
4959     // module via its `noConflict()` method.
4960     window._ = lodash;
4961
4962     // define as an anonymous module so, through path mapping, it can be
4963     // referenced as the "underscore" module
4964     define(function() {
4965       return lodash;
4966     });
4967   }
4968   // check for `exports` after `define` in case a build optimizer adds an `exports` object
4969   else if (freeExports) {
4970     // in Node.js or RingoJS v0.8.0+
4971     if (freeModule) {
4972       (freeModule.exports = lodash)._ = lodash;
4973     }
4974     // in Narwhal or RingoJS v0.7.0-
4975     else {
4976       freeExports._ = lodash;
4977     }
4978   }
4979   else {
4980     // in a browser or Rhino
4981     window._ = lodash;
4982   }
4983 }(this));