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