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