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