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