d314acd0976e0087a4ddbffb9e665681ecdeedb3
[yaffs-website] / node_modules / grunt-legacy-log-utils / node_modules / lodash / lodash.js
1 /**
2  * @license
3  * lodash 4.3.0 (Custom Build) <https://lodash.com/>
4  * Build: `lodash -d -o ./foo/lodash.js`
5  * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
6  * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7  * Copyright 2009-2016 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 as the semantic version number. */
16   var VERSION = '4.3.0';
17
18   /** Used to compose bitmasks for wrapper metadata. */
19   var BIND_FLAG = 1,
20       BIND_KEY_FLAG = 2,
21       CURRY_BOUND_FLAG = 4,
22       CURRY_FLAG = 8,
23       CURRY_RIGHT_FLAG = 16,
24       PARTIAL_FLAG = 32,
25       PARTIAL_RIGHT_FLAG = 64,
26       ARY_FLAG = 128,
27       REARG_FLAG = 256,
28       FLIP_FLAG = 512;
29
30   /** Used to compose bitmasks for comparison styles. */
31   var UNORDERED_COMPARE_FLAG = 1,
32       PARTIAL_COMPARE_FLAG = 2;
33
34   /** Used as default options for `_.truncate`. */
35   var DEFAULT_TRUNC_LENGTH = 30,
36       DEFAULT_TRUNC_OMISSION = '...';
37
38   /** Used to detect hot functions by number of calls within a span of milliseconds. */
39   var HOT_COUNT = 150,
40       HOT_SPAN = 16;
41
42   /** Used as the size to enable large array optimizations. */
43   var LARGE_ARRAY_SIZE = 200;
44
45   /** Used to indicate the type of lazy iteratees. */
46   var LAZY_FILTER_FLAG = 1,
47       LAZY_MAP_FLAG = 2,
48       LAZY_WHILE_FLAG = 3;
49
50   /** Used as the `TypeError` message for "Functions" methods. */
51   var FUNC_ERROR_TEXT = 'Expected a function';
52
53   /** Used to stand-in for `undefined` hash values. */
54   var HASH_UNDEFINED = '__lodash_hash_undefined__';
55
56   /** Used as references for various `Number` constants. */
57   var INFINITY = 1 / 0,
58       MAX_SAFE_INTEGER = 9007199254740991,
59       MAX_INTEGER = 1.7976931348623157e+308,
60       NAN = 0 / 0;
61
62   /** Used as references for the maximum length and index of an array. */
63   var MAX_ARRAY_LENGTH = 4294967295,
64       MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
65       HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
66
67   /** Used as the internal argument placeholder. */
68   var PLACEHOLDER = '__lodash_placeholder__';
69
70   /** `Object#toString` result references. */
71   var argsTag = '[object Arguments]',
72       arrayTag = '[object Array]',
73       boolTag = '[object Boolean]',
74       dateTag = '[object Date]',
75       errorTag = '[object Error]',
76       funcTag = '[object Function]',
77       genTag = '[object GeneratorFunction]',
78       mapTag = '[object Map]',
79       numberTag = '[object Number]',
80       objectTag = '[object Object]',
81       regexpTag = '[object RegExp]',
82       setTag = '[object Set]',
83       stringTag = '[object String]',
84       symbolTag = '[object Symbol]',
85       weakMapTag = '[object WeakMap]',
86       weakSetTag = '[object WeakSet]';
87
88   var arrayBufferTag = '[object ArrayBuffer]',
89       float32Tag = '[object Float32Array]',
90       float64Tag = '[object Float64Array]',
91       int8Tag = '[object Int8Array]',
92       int16Tag = '[object Int16Array]',
93       int32Tag = '[object Int32Array]',
94       uint8Tag = '[object Uint8Array]',
95       uint8ClampedTag = '[object Uint8ClampedArray]',
96       uint16Tag = '[object Uint16Array]',
97       uint32Tag = '[object Uint32Array]';
98
99   /** Used to match empty string literals in compiled template source. */
100   var reEmptyStringLeading = /\b__p \+= '';/g,
101       reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
102       reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
103
104   /** Used to match HTML entities and HTML characters. */
105   var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
106       reUnescapedHtml = /[&<>"'`]/g,
107       reHasEscapedHtml = RegExp(reEscapedHtml.source),
108       reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
109
110   /** Used to match template delimiters. */
111   var reEscape = /<%-([\s\S]+?)%>/g,
112       reEvaluate = /<%([\s\S]+?)%>/g,
113       reInterpolate = /<%=([\s\S]+?)%>/g;
114
115   /** Used to match property names within property paths. */
116   var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
117       reIsPlainProp = /^\w*$/,
118       rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
119
120   /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */
121   var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
122       reHasRegExpChar = RegExp(reRegExpChar.source);
123
124   /** Used to match leading and trailing whitespace. */
125   var reTrim = /^\s+|\s+$/g,
126       reTrimStart = /^\s+/,
127       reTrimEnd = /\s+$/;
128
129   /** Used to match backslashes in property paths. */
130   var reEscapeChar = /\\(\\)?/g;
131
132   /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */
133   var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
134
135   /** Used to match `RegExp` flags from their coerced string values. */
136   var reFlags = /\w*$/;
137
138   /** Used to detect hexadecimal string values. */
139   var reHasHexPrefix = /^0x/i;
140
141   /** Used to detect bad signed hexadecimal string values. */
142   var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
143
144   /** Used to detect binary string values. */
145   var reIsBinary = /^0b[01]+$/i;
146
147   /** Used to detect host constructors (Safari > 5). */
148   var reIsHostCtor = /^\[object .+?Constructor\]$/;
149
150   /** Used to detect octal string values. */
151   var reIsOctal = /^0o[0-7]+$/i;
152
153   /** Used to detect unsigned integer values. */
154   var reIsUint = /^(?:0|[1-9]\d*)$/;
155
156   /** Used to match latin-1 supplementary letters (excluding mathematical operators). */
157   var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
158
159   /** Used to ensure capturing order of template delimiters. */
160   var reNoMatch = /($^)/;
161
162   /** Used to match unescaped characters in compiled string literals. */
163   var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
164
165   /** Used to compose unicode character classes. */
166   var rsAstralRange = '\\ud800-\\udfff',
167       rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
168       rsComboSymbolsRange = '\\u20d0-\\u20f0',
169       rsDingbatRange = '\\u2700-\\u27bf',
170       rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
171       rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
172       rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
173       rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d',
174       rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
175       rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
176       rsVarRange = '\\ufe0e\\ufe0f',
177       rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange;
178
179   /** Used to compose unicode capture groups. */
180   var rsAstral = '[' + rsAstralRange + ']',
181       rsBreak = '[' + rsBreakRange + ']',
182       rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
183       rsDigits = '\\d+',
184       rsDingbat = '[' + rsDingbatRange + ']',
185       rsLower = '[' + rsLowerRange + ']',
186       rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
187       rsFitz = '\\ud83c[\\udffb-\\udfff]',
188       rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
189       rsNonAstral = '[^' + rsAstralRange + ']',
190       rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
191       rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
192       rsUpper = '[' + rsUpperRange + ']',
193       rsZWJ = '\\u200d';
194
195   /** Used to compose unicode regexes. */
196   var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
197       rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
198       reOptMod = rsModifier + '?',
199       rsOptVar = '[' + rsVarRange + ']?',
200       rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
201       rsSeq = rsOptVar + reOptMod + rsOptJoin,
202       rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
203       rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
204
205   /**
206    * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
207    * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
208    */
209   var reComboMark = RegExp(rsCombo, 'g');
210
211   /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
212   var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
213
214   /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
215   var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange  + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
216
217   /** Used to match non-compound words composed of alphanumeric characters. */
218   var reBasicWord = /[a-zA-Z0-9]+/g;
219
220   /** Used to match complex or compound words. */
221   var reComplexWord = RegExp([
222     rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
223     rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
224     rsUpper + '?' + rsLowerMisc + '+',
225     rsUpper + '+',
226     rsDigits,
227     rsEmoji
228   ].join('|'), 'g');
229
230   /** Used to detect strings that need a more robust regexp to match words. */
231   var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
232
233   /** Used to assign default `context` object properties. */
234   var contextProps = [
235     'Array', 'Buffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
236     'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
237     'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
238     'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_',
239     'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
240   ];
241
242   /** Used to make template sourceURLs easier to identify. */
243   var templateCounter = -1;
244
245   /** Used to identify `toStringTag` values of typed arrays. */
246   var typedArrayTags = {};
247   typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
248   typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
249   typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
250   typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
251   typedArrayTags[uint32Tag] = true;
252   typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
253   typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
254   typedArrayTags[dateTag] = typedArrayTags[errorTag] =
255   typedArrayTags[funcTag] = typedArrayTags[mapTag] =
256   typedArrayTags[numberTag] = typedArrayTags[objectTag] =
257   typedArrayTags[regexpTag] = typedArrayTags[setTag] =
258   typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
259
260   /** Used to identify `toStringTag` values supported by `_.clone`. */
261   var cloneableTags = {};
262   cloneableTags[argsTag] = cloneableTags[arrayTag] =
263   cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
264   cloneableTags[dateTag] = cloneableTags[float32Tag] =
265   cloneableTags[float64Tag] = cloneableTags[int8Tag] =
266   cloneableTags[int16Tag] = cloneableTags[int32Tag] =
267   cloneableTags[mapTag] = cloneableTags[numberTag] =
268   cloneableTags[objectTag] = cloneableTags[regexpTag] =
269   cloneableTags[setTag] = cloneableTags[stringTag] =
270   cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
271   cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
272   cloneableTags[uint32Tag] = true;
273   cloneableTags[errorTag] = cloneableTags[funcTag] =
274   cloneableTags[weakMapTag] = false;
275
276   /** Used to map latin-1 supplementary letters to basic latin letters. */
277   var deburredLetters = {
278     '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
279     '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
280     '\xc7': 'C',  '\xe7': 'c',
281     '\xd0': 'D',  '\xf0': 'd',
282     '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
283     '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
284     '\xcC': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
285     '\xeC': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
286     '\xd1': 'N',  '\xf1': 'n',
287     '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
288     '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
289     '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
290     '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
291     '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
292     '\xc6': 'Ae', '\xe6': 'ae',
293     '\xde': 'Th', '\xfe': 'th',
294     '\xdf': 'ss'
295   };
296
297   /** Used to map characters to HTML entities. */
298   var htmlEscapes = {
299     '&': '&amp;',
300     '<': '&lt;',
301     '>': '&gt;',
302     '"': '&quot;',
303     "'": '&#39;',
304     '`': '&#96;'
305   };
306
307   /** Used to map HTML entities to characters. */
308   var htmlUnescapes = {
309     '&amp;': '&',
310     '&lt;': '<',
311     '&gt;': '>',
312     '&quot;': '"',
313     '&#39;': "'",
314     '&#96;': '`'
315   };
316
317   /** Used to determine if values are of the language type `Object`. */
318   var objectTypes = {
319     'function': true,
320     'object': true
321   };
322
323   /** Used to escape characters for inclusion in compiled string literals. */
324   var stringEscapes = {
325     '\\': '\\',
326     "'": "'",
327     '\n': 'n',
328     '\r': 'r',
329     '\u2028': 'u2028',
330     '\u2029': 'u2029'
331   };
332
333   /** Built-in method references without a dependency on `root`. */
334   var freeParseFloat = parseFloat,
335       freeParseInt = parseInt;
336
337   /** Detect free variable `exports`. */
338   var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
339
340   /** Detect free variable `module`. */
341   var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
342
343   /** Detect free variable `global` from Node.js. */
344   var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
345
346   /** Detect free variable `self`. */
347   var freeSelf = checkGlobal(objectTypes[typeof self] && self);
348
349   /** Detect free variable `window`. */
350   var freeWindow = checkGlobal(objectTypes[typeof window] && window);
351
352   /** Detect the popular CommonJS extension `module.exports`. */
353   var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
354
355   /** Detect `this` as the global object. */
356   var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
357
358   /**
359    * Used as a reference to the global object.
360    *
361    * The `this` value is used if it's the global object to avoid Greasemonkey's
362    * restricted `window` object, otherwise the `window` object is used.
363    */
364   var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
365
366   /*--------------------------------------------------------------------------*/
367
368   /**
369    * Adds the key-value `pair` to `map`.
370    *
371    * @private
372    * @param {Object} map The map to modify.
373    * @param {Array} pair The key-value pair to add.
374    * @returns {Object} Returns `map`.
375    */
376   function addMapEntry(map, pair) {
377     map.set(pair[0], pair[1]);
378     return map;
379   }
380
381   /**
382    * Adds `value` to `set`.
383    *
384    * @private
385    * @param {Object} set The set to modify.
386    * @param {*} value The value to add.
387    * @returns {Object} Returns `set`.
388    */
389   function addSetEntry(set, value) {
390     set.add(value);
391     return set;
392   }
393
394   /**
395    * A faster alternative to `Function#apply`, this function invokes `func`
396    * with the `this` binding of `thisArg` and the arguments of `args`.
397    *
398    * @private
399    * @param {Function} func The function to invoke.
400    * @param {*} thisArg The `this` binding of `func`.
401    * @param {...*} args The arguments to invoke `func` with.
402    * @returns {*} Returns the result of `func`.
403    */
404   function apply(func, thisArg, args) {
405     var length = args.length;
406     switch (length) {
407       case 0: return func.call(thisArg);
408       case 1: return func.call(thisArg, args[0]);
409       case 2: return func.call(thisArg, args[0], args[1]);
410       case 3: return func.call(thisArg, args[0], args[1], args[2]);
411     }
412     return func.apply(thisArg, args);
413   }
414
415   /**
416    * A specialized version of `baseAggregator` for arrays.
417    *
418    * @private
419    * @param {Array} array The array to iterate over.
420    * @param {Function} setter The function to set `accumulator` values.
421    * @param {Function} iteratee The iteratee to transform keys.
422    * @param {Object} accumulator The initial aggregated object.
423    * @returns {Function} Returns `accumulator`.
424    */
425   function arrayAggregator(array, setter, iteratee, accumulator) {
426     var index = -1,
427         length = array.length;
428
429     while (++index < length) {
430       var value = array[index];
431       setter(accumulator, value, iteratee(value), array);
432     }
433     return accumulator;
434   }
435
436   /**
437    * Creates a new array concatenating `array` with `other`.
438    *
439    * @private
440    * @param {Array} array The first array to concatenate.
441    * @param {Array} other The second array to concatenate.
442    * @returns {Array} Returns the new concatenated array.
443    */
444   function arrayConcat(array, other) {
445     var index = -1,
446         length = array.length,
447         othIndex = -1,
448         othLength = other.length,
449         result = Array(length + othLength);
450
451     while (++index < length) {
452       result[index] = array[index];
453     }
454     while (++othIndex < othLength) {
455       result[index++] = other[othIndex];
456     }
457     return result;
458   }
459
460   /**
461    * A specialized version of `_.forEach` for arrays without support for
462    * iteratee shorthands.
463    *
464    * @private
465    * @param {Array} array The array to iterate over.
466    * @param {Function} iteratee The function invoked per iteration.
467    * @returns {Array} Returns `array`.
468    */
469   function arrayEach(array, iteratee) {
470     var index = -1,
471         length = array.length;
472
473     while (++index < length) {
474       if (iteratee(array[index], index, array) === false) {
475         break;
476       }
477     }
478     return array;
479   }
480
481   /**
482    * A specialized version of `_.forEachRight` for arrays without support for
483    * iteratee shorthands.
484    *
485    * @private
486    * @param {Array} array The array to iterate over.
487    * @param {Function} iteratee The function invoked per iteration.
488    * @returns {Array} Returns `array`.
489    */
490   function arrayEachRight(array, iteratee) {
491     var length = array.length;
492
493     while (length--) {
494       if (iteratee(array[length], length, array) === false) {
495         break;
496       }
497     }
498     return array;
499   }
500
501   /**
502    * A specialized version of `_.every` for arrays without support for
503    * iteratee shorthands.
504    *
505    * @private
506    * @param {Array} array The array to iterate over.
507    * @param {Function} predicate The function invoked per iteration.
508    * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
509    */
510   function arrayEvery(array, predicate) {
511     var index = -1,
512         length = array.length;
513
514     while (++index < length) {
515       if (!predicate(array[index], index, array)) {
516         return false;
517       }
518     }
519     return true;
520   }
521
522   /**
523    * A specialized version of `_.filter` for arrays without support for
524    * iteratee shorthands.
525    *
526    * @private
527    * @param {Array} array The array to iterate over.
528    * @param {Function} predicate The function invoked per iteration.
529    * @returns {Array} Returns the new filtered array.
530    */
531   function arrayFilter(array, predicate) {
532     var index = -1,
533         length = array.length,
534         resIndex = -1,
535         result = [];
536
537     while (++index < length) {
538       var value = array[index];
539       if (predicate(value, index, array)) {
540         result[++resIndex] = value;
541       }
542     }
543     return result;
544   }
545
546   /**
547    * A specialized version of `_.includes` for arrays without support for
548    * specifying an index to search from.
549    *
550    * @private
551    * @param {Array} array The array to search.
552    * @param {*} target The value to search for.
553    * @returns {boolean} Returns `true` if `target` is found, else `false`.
554    */
555   function arrayIncludes(array, value) {
556     return !!array.length && baseIndexOf(array, value, 0) > -1;
557   }
558
559   /**
560    * A specialized version of `_.includesWith` for arrays without support for
561    * specifying an index to search from.
562    *
563    * @private
564    * @param {Array} array The array to search.
565    * @param {*} target The value to search for.
566    * @param {Function} comparator The comparator invoked per element.
567    * @returns {boolean} Returns `true` if `target` is found, else `false`.
568    */
569   function arrayIncludesWith(array, value, comparator) {
570     var index = -1,
571         length = array.length;
572
573     while (++index < length) {
574       if (comparator(value, array[index])) {
575         return true;
576       }
577     }
578     return false;
579   }
580
581   /**
582    * A specialized version of `_.map` for arrays without support for iteratee
583    * shorthands.
584    *
585    * @private
586    * @param {Array} array The array to iterate over.
587    * @param {Function} iteratee The function invoked per iteration.
588    * @returns {Array} Returns the new mapped array.
589    */
590   function arrayMap(array, iteratee) {
591     var index = -1,
592         length = array.length,
593         result = Array(length);
594
595     while (++index < length) {
596       result[index] = iteratee(array[index], index, array);
597     }
598     return result;
599   }
600
601   /**
602    * Appends the elements of `values` to `array`.
603    *
604    * @private
605    * @param {Array} array The array to modify.
606    * @param {Array} values The values to append.
607    * @returns {Array} Returns `array`.
608    */
609   function arrayPush(array, values) {
610     var index = -1,
611         length = values.length,
612         offset = array.length;
613
614     while (++index < length) {
615       array[offset + index] = values[index];
616     }
617     return array;
618   }
619
620   /**
621    * A specialized version of `_.reduce` for arrays without support for
622    * iteratee shorthands.
623    *
624    * @private
625    * @param {Array} array The array to iterate over.
626    * @param {Function} iteratee The function invoked per iteration.
627    * @param {*} [accumulator] The initial value.
628    * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value.
629    * @returns {*} Returns the accumulated value.
630    */
631   function arrayReduce(array, iteratee, accumulator, initAccum) {
632     var index = -1,
633         length = array.length;
634
635     if (initAccum && length) {
636       accumulator = array[++index];
637     }
638     while (++index < length) {
639       accumulator = iteratee(accumulator, array[index], index, array);
640     }
641     return accumulator;
642   }
643
644   /**
645    * A specialized version of `_.reduceRight` for arrays without support for
646    * iteratee shorthands.
647    *
648    * @private
649    * @param {Array} array The array to iterate over.
650    * @param {Function} iteratee The function invoked per iteration.
651    * @param {*} [accumulator] The initial value.
652    * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value.
653    * @returns {*} Returns the accumulated value.
654    */
655   function arrayReduceRight(array, iteratee, accumulator, initAccum) {
656     var length = array.length;
657     if (initAccum && length) {
658       accumulator = array[--length];
659     }
660     while (length--) {
661       accumulator = iteratee(accumulator, array[length], length, array);
662     }
663     return accumulator;
664   }
665
666   /**
667    * A specialized version of `_.some` for arrays without support for iteratee
668    * shorthands.
669    *
670    * @private
671    * @param {Array} array The array to iterate over.
672    * @param {Function} predicate The function invoked per iteration.
673    * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
674    */
675   function arraySome(array, predicate) {
676     var index = -1,
677         length = array.length;
678
679     while (++index < length) {
680       if (predicate(array[index], index, array)) {
681         return true;
682       }
683     }
684     return false;
685   }
686
687   /**
688    * The base implementation of methods like `_.max` and `_.min` which accepts a
689    * `comparator` to determine the extremum value.
690    *
691    * @private
692    * @param {Array} array The array to iterate over.
693    * @param {Function} iteratee The iteratee invoked per iteration.
694    * @param {Function} comparator The comparator used to compare values.
695    * @returns {*} Returns the extremum value.
696    */
697   function baseExtremum(array, iteratee, comparator) {
698     var index = -1,
699         length = array.length;
700
701     while (++index < length) {
702       var value = array[index],
703           current = iteratee(value);
704
705       if (current != null && (computed === undefined
706             ? current === current
707             : comparator(current, computed)
708           )) {
709         var computed = current,
710             result = value;
711       }
712     }
713     return result;
714   }
715
716   /**
717    * The base implementation of methods like `_.find` and `_.findKey`, without
718    * support for iteratee shorthands, which iterates over `collection` using
719    * `eachFunc`.
720    *
721    * @private
722    * @param {Array|Object} collection The collection to search.
723    * @param {Function} predicate The function invoked per iteration.
724    * @param {Function} eachFunc The function to iterate over `collection`.
725    * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself.
726    * @returns {*} Returns the found element or its key, else `undefined`.
727    */
728   function baseFind(collection, predicate, eachFunc, retKey) {
729     var result;
730     eachFunc(collection, function(value, key, collection) {
731       if (predicate(value, key, collection)) {
732         result = retKey ? key : value;
733         return false;
734       }
735     });
736     return result;
737   }
738
739   /**
740    * The base implementation of `_.findIndex` and `_.findLastIndex` without
741    * support for iteratee shorthands.
742    *
743    * @private
744    * @param {Array} array The array to search.
745    * @param {Function} predicate The function invoked per iteration.
746    * @param {boolean} [fromRight] Specify iterating from right to left.
747    * @returns {number} Returns the index of the matched value, else `-1`.
748    */
749   function baseFindIndex(array, predicate, fromRight) {
750     var length = array.length,
751         index = fromRight ? length : -1;
752
753     while ((fromRight ? index-- : ++index < length)) {
754       if (predicate(array[index], index, array)) {
755         return index;
756       }
757     }
758     return -1;
759   }
760
761   /**
762    * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
763    *
764    * @private
765    * @param {Array} array The array to search.
766    * @param {*} value The value to search for.
767    * @param {number} fromIndex The index to search from.
768    * @returns {number} Returns the index of the matched value, else `-1`.
769    */
770   function baseIndexOf(array, value, fromIndex) {
771     if (value !== value) {
772       return indexOfNaN(array, fromIndex);
773     }
774     var index = fromIndex - 1,
775         length = array.length;
776
777     while (++index < length) {
778       if (array[index] === value) {
779         return index;
780       }
781     }
782     return -1;
783   }
784
785   /**
786    * The base implementation of `_.reduce` and `_.reduceRight`, without support
787    * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
788    *
789    * @private
790    * @param {Array|Object} collection The collection to iterate over.
791    * @param {Function} iteratee The function invoked per iteration.
792    * @param {*} accumulator The initial value.
793    * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value.
794    * @param {Function} eachFunc The function to iterate over `collection`.
795    * @returns {*} Returns the accumulated value.
796    */
797   function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
798     eachFunc(collection, function(value, index, collection) {
799       accumulator = initAccum
800         ? (initAccum = false, value)
801         : iteratee(accumulator, value, index, collection);
802     });
803     return accumulator;
804   }
805
806   /**
807    * The base implementation of `_.sortBy` which uses `comparer` to define
808    * the sort order of `array` and replaces criteria objects with their
809    * corresponding values.
810    *
811    * @private
812    * @param {Array} array The array to sort.
813    * @param {Function} comparer The function to define sort order.
814    * @returns {Array} Returns `array`.
815    */
816   function baseSortBy(array, comparer) {
817     var length = array.length;
818
819     array.sort(comparer);
820     while (length--) {
821       array[length] = array[length].value;
822     }
823     return array;
824   }
825
826   /**
827    * The base implementation of `_.sum` without support for iteratee shorthands.
828    *
829    * @private
830    * @param {Array} array The array to iterate over.
831    * @param {Function} iteratee The function invoked per iteration.
832    * @returns {number} Returns the sum.
833    */
834   function baseSum(array, iteratee) {
835     var result,
836         index = -1,
837         length = array.length;
838
839     while (++index < length) {
840       var current = iteratee(array[index]);
841       if (current !== undefined) {
842         result = result === undefined ? current : (result + current);
843       }
844     }
845     return result;
846   }
847
848   /**
849    * The base implementation of `_.times` without support for iteratee shorthands
850    * or max array length checks.
851    *
852    * @private
853    * @param {number} n The number of times to invoke `iteratee`.
854    * @param {Function} iteratee The function invoked per iteration.
855    * @returns {Array} Returns the array of results.
856    */
857   function baseTimes(n, iteratee) {
858     var index = -1,
859         result = Array(n);
860
861     while (++index < n) {
862       result[index] = iteratee(index);
863     }
864     return result;
865   }
866
867   /**
868    * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
869    * of key-value pairs for `object` corresponding to the property names of `props`.
870    *
871    * @private
872    * @param {Object} object The object to query.
873    * @param {Array} props The property names to get values for.
874    * @returns {Object} Returns the new array of key-value pairs.
875    */
876   function baseToPairs(object, props) {
877     return arrayMap(props, function(key) {
878       return [key, object[key]];
879     });
880   }
881
882   /**
883    * The base implementation of `_.unary` without support for storing wrapper metadata.
884    *
885    * @private
886    * @param {Function} func The function to cap arguments for.
887    * @returns {Function} Returns the new function.
888    */
889   function baseUnary(func) {
890     return function(value) {
891       return func(value);
892     };
893   }
894
895   /**
896    * The base implementation of `_.values` and `_.valuesIn` which creates an
897    * array of `object` property values corresponding to the property names
898    * of `props`.
899    *
900    * @private
901    * @param {Object} object The object to query.
902    * @param {Array} props The property names to get values for.
903    * @returns {Object} Returns the array of property values.
904    */
905   function baseValues(object, props) {
906     return arrayMap(props, function(key) {
907       return object[key];
908     });
909   }
910
911   /**
912    * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
913    * that is not found in the character symbols.
914    *
915    * @private
916    * @param {Array} strSymbols The string symbols to inspect.
917    * @param {Array} chrSymbols The character symbols to find.
918    * @returns {number} Returns the index of the first unmatched string symbol.
919    */
920   function charsStartIndex(strSymbols, chrSymbols) {
921     var index = -1,
922         length = strSymbols.length;
923
924     while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
925     return index;
926   }
927
928   /**
929    * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
930    * that is not found in the character symbols.
931    *
932    * @private
933    * @param {Array} strSymbols The string symbols to inspect.
934    * @param {Array} chrSymbols The character symbols to find.
935    * @returns {number} Returns the index of the last unmatched string symbol.
936    */
937   function charsEndIndex(strSymbols, chrSymbols) {
938     var index = strSymbols.length;
939
940     while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
941     return index;
942   }
943
944   /**
945    * Checks if `value` is a global object.
946    *
947    * @private
948    * @param {*} value The value to check.
949    * @returns {null|Object} Returns `value` if it's a global object, else `null`.
950    */
951   function checkGlobal(value) {
952     return (value && value.Object === Object) ? value : null;
953   }
954
955   /**
956    * Compares values to sort them in ascending order.
957    *
958    * @private
959    * @param {*} value The value to compare.
960    * @param {*} other The other value to compare.
961    * @returns {number} Returns the sort order indicator for `value`.
962    */
963   function compareAscending(value, other) {
964     if (value !== other) {
965       var valIsNull = value === null,
966           valIsUndef = value === undefined,
967           valIsReflexive = value === value;
968
969       var othIsNull = other === null,
970           othIsUndef = other === undefined,
971           othIsReflexive = other === other;
972
973       if ((value > other && !othIsNull) || !valIsReflexive ||
974           (valIsNull && !othIsUndef && othIsReflexive) ||
975           (valIsUndef && othIsReflexive)) {
976         return 1;
977       }
978       if ((value < other && !valIsNull) || !othIsReflexive ||
979           (othIsNull && !valIsUndef && valIsReflexive) ||
980           (othIsUndef && valIsReflexive)) {
981         return -1;
982       }
983     }
984     return 0;
985   }
986
987   /**
988    * Used by `_.orderBy` to compare multiple properties of a value to another
989    * and stable sort them.
990    *
991    * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
992    * specify an order of "desc" for descending or "asc" for ascending sort order
993    * of corresponding values.
994    *
995    * @private
996    * @param {Object} object The object to compare.
997    * @param {Object} other The other object to compare.
998    * @param {boolean[]|string[]} orders The order to sort by for each property.
999    * @returns {number} Returns the sort order indicator for `object`.
1000    */
1001   function compareMultiple(object, other, orders) {
1002     var index = -1,
1003         objCriteria = object.criteria,
1004         othCriteria = other.criteria,
1005         length = objCriteria.length,
1006         ordersLength = orders.length;
1007
1008     while (++index < length) {
1009       var result = compareAscending(objCriteria[index], othCriteria[index]);
1010       if (result) {
1011         if (index >= ordersLength) {
1012           return result;
1013         }
1014         var order = orders[index];
1015         return result * (order == 'desc' ? -1 : 1);
1016       }
1017     }
1018     // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
1019     // that causes it, under certain circumstances, to provide the same value for
1020     // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
1021     // for more details.
1022     //
1023     // This also ensures a stable sort in V8 and other engines.
1024     // See https://code.google.com/p/v8/issues/detail?id=90 for more details.
1025     return object.index - other.index;
1026   }
1027
1028   /**
1029    * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
1030    *
1031    * @private
1032    * @param {string} letter The matched letter to deburr.
1033    * @returns {string} Returns the deburred letter.
1034    */
1035   function deburrLetter(letter) {
1036     return deburredLetters[letter];
1037   }
1038
1039   /**
1040    * Used by `_.escape` to convert characters to HTML entities.
1041    *
1042    * @private
1043    * @param {string} chr The matched character to escape.
1044    * @returns {string} Returns the escaped character.
1045    */
1046   function escapeHtmlChar(chr) {
1047     return htmlEscapes[chr];
1048   }
1049
1050   /**
1051    * Used by `_.template` to escape characters for inclusion in compiled string literals.
1052    *
1053    * @private
1054    * @param {string} chr The matched character to escape.
1055    * @returns {string} Returns the escaped character.
1056    */
1057   function escapeStringChar(chr) {
1058     return '\\' + stringEscapes[chr];
1059   }
1060
1061   /**
1062    * Gets the index at which the first occurrence of `NaN` is found in `array`.
1063    *
1064    * @private
1065    * @param {Array} array The array to search.
1066    * @param {number} fromIndex The index to search from.
1067    * @param {boolean} [fromRight] Specify iterating from right to left.
1068    * @returns {number} Returns the index of the matched `NaN`, else `-1`.
1069    */
1070   function indexOfNaN(array, fromIndex, fromRight) {
1071     var length = array.length,
1072         index = fromIndex + (fromRight ? 0 : -1);
1073
1074     while ((fromRight ? index-- : ++index < length)) {
1075       var other = array[index];
1076       if (other !== other) {
1077         return index;
1078       }
1079     }
1080     return -1;
1081   }
1082
1083   /**
1084    * Checks if `value` is a host object in IE < 9.
1085    *
1086    * @private
1087    * @param {*} value The value to check.
1088    * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
1089    */
1090   function isHostObject(value) {
1091     // Many host objects are `Object` objects that can coerce to strings
1092     // despite having improperly defined `toString` methods.
1093     var result = false;
1094     if (value != null && typeof value.toString != 'function') {
1095       try {
1096         result = !!(value + '');
1097       } catch (e) {}
1098     }
1099     return result;
1100   }
1101
1102   /**
1103    * Checks if `value` is a valid array-like index.
1104    *
1105    * @private
1106    * @param {*} value The value to check.
1107    * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
1108    * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
1109    */
1110   function isIndex(value, length) {
1111     value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
1112     length = length == null ? MAX_SAFE_INTEGER : length;
1113     return value > -1 && value % 1 == 0 && value < length;
1114   }
1115
1116   /**
1117    * Converts `iterator` to an array.
1118    *
1119    * @private
1120    * @param {Object} iterator The iterator to convert.
1121    * @returns {Array} Returns the converted array.
1122    */
1123   function iteratorToArray(iterator) {
1124     var data,
1125         result = [];
1126
1127     while (!(data = iterator.next()).done) {
1128       result.push(data.value);
1129     }
1130     return result;
1131   }
1132
1133   /**
1134    * Converts `map` to an array.
1135    *
1136    * @private
1137    * @param {Object} map The map to convert.
1138    * @returns {Array} Returns the converted array.
1139    */
1140   function mapToArray(map) {
1141     var index = -1,
1142         result = Array(map.size);
1143
1144     map.forEach(function(value, key) {
1145       result[++index] = [key, value];
1146     });
1147     return result;
1148   }
1149
1150   /**
1151    * Replaces all `placeholder` elements in `array` with an internal placeholder
1152    * and returns an array of their indexes.
1153    *
1154    * @private
1155    * @param {Array} array The array to modify.
1156    * @param {*} placeholder The placeholder to replace.
1157    * @returns {Array} Returns the new array of placeholder indexes.
1158    */
1159   function replaceHolders(array, placeholder) {
1160     var index = -1,
1161         length = array.length,
1162         resIndex = -1,
1163         result = [];
1164
1165     while (++index < length) {
1166       if (array[index] === placeholder) {
1167         array[index] = PLACEHOLDER;
1168         result[++resIndex] = index;
1169       }
1170     }
1171     return result;
1172   }
1173
1174   /**
1175    * Converts `set` to an array.
1176    *
1177    * @private
1178    * @param {Object} set The set to convert.
1179    * @returns {Array} Returns the converted array.
1180    */
1181   function setToArray(set) {
1182     var index = -1,
1183         result = Array(set.size);
1184
1185     set.forEach(function(value) {
1186       result[++index] = value;
1187     });
1188     return result;
1189   }
1190
1191   /**
1192    * Gets the number of symbols in `string`.
1193    *
1194    * @private
1195    * @param {string} string The string to inspect.
1196    * @returns {number} Returns the string size.
1197    */
1198   function stringSize(string) {
1199     if (!(string && reHasComplexSymbol.test(string))) {
1200       return string.length;
1201     }
1202     var result = reComplexSymbol.lastIndex = 0;
1203     while (reComplexSymbol.test(string)) {
1204       result++;
1205     }
1206     return result;
1207   }
1208
1209   /**
1210    * Converts `string` to an array.
1211    *
1212    * @private
1213    * @param {string} string The string to convert.
1214    * @returns {Array} Returns the converted array.
1215    */
1216   function stringToArray(string) {
1217     return string.match(reComplexSymbol);
1218   }
1219
1220   /**
1221    * Used by `_.unescape` to convert HTML entities to characters.
1222    *
1223    * @private
1224    * @param {string} chr The matched character to unescape.
1225    * @returns {string} Returns the unescaped character.
1226    */
1227   function unescapeHtmlChar(chr) {
1228     return htmlUnescapes[chr];
1229   }
1230
1231   /*--------------------------------------------------------------------------*/
1232
1233   /**
1234    * Create a new pristine `lodash` function using the `context` object.
1235    *
1236    * @static
1237    * @memberOf _
1238    * @category Util
1239    * @param {Object} [context=root] The context object.
1240    * @returns {Function} Returns a new `lodash` function.
1241    * @example
1242    *
1243    * _.mixin({ 'foo': _.constant('foo') });
1244    *
1245    * var lodash = _.runInContext();
1246    * lodash.mixin({ 'bar': lodash.constant('bar') });
1247    *
1248    * _.isFunction(_.foo);
1249    * // => true
1250    * _.isFunction(_.bar);
1251    * // => false
1252    *
1253    * lodash.isFunction(lodash.foo);
1254    * // => false
1255    * lodash.isFunction(lodash.bar);
1256    * // => true
1257    *
1258    * // Use `context` to mock `Date#getTime` use in `_.now`.
1259    * var mock = _.runInContext({
1260    *   'Date': function() {
1261    *     return { 'getTime': getTimeMock };
1262    *   }
1263    * });
1264    *
1265    * // Create a suped-up `defer` in Node.js.
1266    * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1267    */
1268   function runInContext(context) {
1269     context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
1270
1271     /** Built-in constructor references. */
1272     var Date = context.Date,
1273         Error = context.Error,
1274         Math = context.Math,
1275         RegExp = context.RegExp,
1276         TypeError = context.TypeError;
1277
1278     /** Used for built-in method references. */
1279     var arrayProto = context.Array.prototype,
1280         objectProto = context.Object.prototype;
1281
1282     /** Used to resolve the decompiled source of functions. */
1283     var funcToString = context.Function.prototype.toString;
1284
1285     /** Used to check objects for own properties. */
1286     var hasOwnProperty = objectProto.hasOwnProperty;
1287
1288     /** Used to generate unique IDs. */
1289     var idCounter = 0;
1290
1291     /** Used to infer the `Object` constructor. */
1292     var objectCtorString = funcToString.call(Object);
1293
1294     /**
1295      * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1296      * of values.
1297      */
1298     var objectToString = objectProto.toString;
1299
1300     /** Used to restore the original `_` reference in `_.noConflict`. */
1301     var oldDash = root._;
1302
1303     /** Used to detect if a method is native. */
1304     var reIsNative = RegExp('^' +
1305       funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1306       .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1307     );
1308
1309     /** Built-in value references. */
1310     var Buffer = moduleExports ? context.Buffer : undefined,
1311         Reflect = context.Reflect,
1312         Symbol = context.Symbol,
1313         Uint8Array = context.Uint8Array,
1314         clearTimeout = context.clearTimeout,
1315         enumerate = Reflect ? Reflect.enumerate : undefined,
1316         getPrototypeOf = Object.getPrototypeOf,
1317         getOwnPropertySymbols = Object.getOwnPropertySymbols,
1318         iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
1319         propertyIsEnumerable = objectProto.propertyIsEnumerable,
1320         setTimeout = context.setTimeout,
1321         splice = arrayProto.splice;
1322
1323     /* Built-in method references for those with the same name as other `lodash` methods. */
1324     var nativeCeil = Math.ceil,
1325         nativeFloor = Math.floor,
1326         nativeIsFinite = context.isFinite,
1327         nativeJoin = arrayProto.join,
1328         nativeKeys = Object.keys,
1329         nativeMax = Math.max,
1330         nativeMin = Math.min,
1331         nativeParseInt = context.parseInt,
1332         nativeRandom = Math.random,
1333         nativeReverse = arrayProto.reverse;
1334
1335     /* Built-in method references that are verified to be native. */
1336     var Map = getNative(context, 'Map'),
1337         Set = getNative(context, 'Set'),
1338         WeakMap = getNative(context, 'WeakMap'),
1339         nativeCreate = getNative(Object, 'create');
1340
1341     /** Used to store function metadata. */
1342     var metaMap = WeakMap && new WeakMap;
1343
1344     /** Used to detect maps, sets, and weakmaps. */
1345     var mapCtorString = Map ? funcToString.call(Map) : '',
1346         setCtorString = Set ? funcToString.call(Set) : '',
1347         weakMapCtorString = WeakMap ? funcToString.call(WeakMap) : '';
1348
1349     /** Used to convert symbols to primitives and strings. */
1350     var symbolProto = Symbol ? Symbol.prototype : undefined,
1351         symbolValueOf = Symbol ? symbolProto.valueOf : undefined,
1352         symbolToString = Symbol ? symbolProto.toString : undefined;
1353
1354     /** Used to lookup unminified function names. */
1355     var realNames = {};
1356
1357     /*------------------------------------------------------------------------*/
1358
1359     /**
1360      * Creates a `lodash` object which wraps `value` to enable implicit method
1361      * chaining. Methods that operate on and return arrays, collections, and
1362      * functions can be chained together. Methods that retrieve a single value or
1363      * may return a primitive value will automatically end the chain sequence and
1364      * return the unwrapped value. Otherwise, the value must be unwrapped with
1365      * `_#value`.
1366      *
1367      * Explicit chaining, which must be unwrapped with `_#value` in all cases,
1368      * may be enabled using `_.chain`.
1369      *
1370      * The execution of chained methods is lazy, that is, it's deferred until
1371      * `_#value` is implicitly or explicitly called.
1372      *
1373      * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
1374      * fusion is an optimization to merge iteratee calls; this avoids the creation
1375      * of intermediate arrays and can greatly reduce the number of iteratee executions.
1376      * Sections of a chain sequence qualify for shortcut fusion if the section is
1377      * applied to an array of at least two hundred elements and any iteratees
1378      * accept only one argument. The heuristic for whether a section qualifies
1379      * for shortcut fusion is subject to change.
1380      *
1381      * Chaining is supported in custom builds as long as the `_#value` method is
1382      * directly or indirectly included in the build.
1383      *
1384      * In addition to lodash methods, wrappers have `Array` and `String` methods.
1385      *
1386      * The wrapper `Array` methods are:
1387      * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1388      *
1389      * The wrapper `String` methods are:
1390      * `replace` and `split`
1391      *
1392      * The wrapper methods that support shortcut fusion are:
1393      * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1394      * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1395      * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1396      *
1397      * The chainable wrapper methods are:
1398      * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`,
1399      * `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`,
1400      * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
1401      * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
1402      * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
1403      * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`,
1404      * `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
1405      * `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invertBy`,
1406      * `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`,
1407      * `mapValues`, `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`,
1408      * `method`, `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`,
1409      * `orderBy`, `over`, `overArgs`, `overEvery`, `overSome`, `partial`,
1410      * `partialRight`, `partition`, `pick`, `pickBy`, `plant`, `property`,
1411      * `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`,
1412      * `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`,
1413      * `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`,
1414      * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`,
1415      * `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`,
1416      * `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`,
1417      * `uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`,
1418      * `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`,
1419      * `zipObjectDeep`, and `zipWith`
1420      *
1421      * The wrapper methods that are **not** chainable by default are:
1422      * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1423      * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
1424      * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
1425      * `findLast`, `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`,
1426      * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
1427      * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
1428      * `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`,
1429      * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`,
1430      * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`, `isMatchWith`,
1431      * `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`,
1432      * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isString`, `isUndefined`,
1433      * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`,
1434      * `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`,
1435      * `noConflict`, `noop`, `now`, `pad`, `padEnd`, `padStart`, `parseInt`,
1436      * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`,
1437      * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
1438      * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`,
1439      * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toLower`,
1440      * `toInteger`, `toLength`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`,
1441      * `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`,
1442      * `upperCase`, `upperFirst`, `value`, and `words`
1443      *
1444      * @name _
1445      * @constructor
1446      * @category Seq
1447      * @param {*} value The value to wrap in a `lodash` instance.
1448      * @returns {Object} Returns the new `lodash` wrapper instance.
1449      * @example
1450      *
1451      * function square(n) {
1452      *   return n * n;
1453      * }
1454      *
1455      * var wrapped = _([1, 2, 3]);
1456      *
1457      * // Returns an unwrapped value.
1458      * wrapped.reduce(_.add);
1459      * // => 6
1460      *
1461      * // Returns a wrapped value.
1462      * var squares = wrapped.map(square);
1463      *
1464      * _.isArray(squares);
1465      * // => false
1466      *
1467      * _.isArray(squares.value());
1468      * // => true
1469      */
1470     function lodash(value) {
1471       if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1472         if (value instanceof LodashWrapper) {
1473           return value;
1474         }
1475         if (hasOwnProperty.call(value, '__wrapped__')) {
1476           return wrapperClone(value);
1477         }
1478       }
1479       return new LodashWrapper(value);
1480     }
1481
1482     /**
1483      * The function whose prototype all chaining wrappers inherit from.
1484      *
1485      * @private
1486      */
1487     function baseLodash() {
1488       // No operation performed.
1489     }
1490
1491     /**
1492      * The base constructor for creating `lodash` wrapper objects.
1493      *
1494      * @private
1495      * @param {*} value The value to wrap.
1496      * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
1497      */
1498     function LodashWrapper(value, chainAll) {
1499       this.__wrapped__ = value;
1500       this.__actions__ = [];
1501       this.__chain__ = !!chainAll;
1502       this.__index__ = 0;
1503       this.__values__ = undefined;
1504     }
1505
1506     /**
1507      * By default, the template delimiters used by lodash are like those in
1508      * embedded Ruby (ERB). Change the following template settings to use
1509      * alternative delimiters.
1510      *
1511      * @static
1512      * @memberOf _
1513      * @type Object
1514      */
1515     lodash.templateSettings = {
1516
1517       /**
1518        * Used to detect `data` property values to be HTML-escaped.
1519        *
1520        * @memberOf _.templateSettings
1521        * @type RegExp
1522        */
1523       'escape': reEscape,
1524
1525       /**
1526        * Used to detect code to be evaluated.
1527        *
1528        * @memberOf _.templateSettings
1529        * @type RegExp
1530        */
1531       'evaluate': reEvaluate,
1532
1533       /**
1534        * Used to detect `data` property values to inject.
1535        *
1536        * @memberOf _.templateSettings
1537        * @type RegExp
1538        */
1539       'interpolate': reInterpolate,
1540
1541       /**
1542        * Used to reference the data object in the template text.
1543        *
1544        * @memberOf _.templateSettings
1545        * @type string
1546        */
1547       'variable': '',
1548
1549       /**
1550        * Used to import variables into the compiled template.
1551        *
1552        * @memberOf _.templateSettings
1553        * @type Object
1554        */
1555       'imports': {
1556
1557         /**
1558          * A reference to the `lodash` function.
1559          *
1560          * @memberOf _.templateSettings.imports
1561          * @type Function
1562          */
1563         '_': lodash
1564       }
1565     };
1566
1567     /*------------------------------------------------------------------------*/
1568
1569     /**
1570      * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1571      *
1572      * @private
1573      * @param {*} value The value to wrap.
1574      */
1575     function LazyWrapper(value) {
1576       this.__wrapped__ = value;
1577       this.__actions__ = [];
1578       this.__dir__ = 1;
1579       this.__filtered__ = false;
1580       this.__iteratees__ = [];
1581       this.__takeCount__ = MAX_ARRAY_LENGTH;
1582       this.__views__ = [];
1583     }
1584
1585     /**
1586      * Creates a clone of the lazy wrapper object.
1587      *
1588      * @private
1589      * @name clone
1590      * @memberOf LazyWrapper
1591      * @returns {Object} Returns the cloned `LazyWrapper` object.
1592      */
1593     function lazyClone() {
1594       var result = new LazyWrapper(this.__wrapped__);
1595       result.__actions__ = copyArray(this.__actions__);
1596       result.__dir__ = this.__dir__;
1597       result.__filtered__ = this.__filtered__;
1598       result.__iteratees__ = copyArray(this.__iteratees__);
1599       result.__takeCount__ = this.__takeCount__;
1600       result.__views__ = copyArray(this.__views__);
1601       return result;
1602     }
1603
1604     /**
1605      * Reverses the direction of lazy iteration.
1606      *
1607      * @private
1608      * @name reverse
1609      * @memberOf LazyWrapper
1610      * @returns {Object} Returns the new reversed `LazyWrapper` object.
1611      */
1612     function lazyReverse() {
1613       if (this.__filtered__) {
1614         var result = new LazyWrapper(this);
1615         result.__dir__ = -1;
1616         result.__filtered__ = true;
1617       } else {
1618         result = this.clone();
1619         result.__dir__ *= -1;
1620       }
1621       return result;
1622     }
1623
1624     /**
1625      * Extracts the unwrapped value from its lazy wrapper.
1626      *
1627      * @private
1628      * @name value
1629      * @memberOf LazyWrapper
1630      * @returns {*} Returns the unwrapped value.
1631      */
1632     function lazyValue() {
1633       var array = this.__wrapped__.value(),
1634           dir = this.__dir__,
1635           isArr = isArray(array),
1636           isRight = dir < 0,
1637           arrLength = isArr ? array.length : 0,
1638           view = getView(0, arrLength, this.__views__),
1639           start = view.start,
1640           end = view.end,
1641           length = end - start,
1642           index = isRight ? end : (start - 1),
1643           iteratees = this.__iteratees__,
1644           iterLength = iteratees.length,
1645           resIndex = 0,
1646           takeCount = nativeMin(length, this.__takeCount__);
1647
1648       if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) {
1649         return baseWrapperValue(array, this.__actions__);
1650       }
1651       var result = [];
1652
1653       outer:
1654       while (length-- && resIndex < takeCount) {
1655         index += dir;
1656
1657         var iterIndex = -1,
1658             value = array[index];
1659
1660         while (++iterIndex < iterLength) {
1661           var data = iteratees[iterIndex],
1662               iteratee = data.iteratee,
1663               type = data.type,
1664               computed = iteratee(value);
1665
1666           if (type == LAZY_MAP_FLAG) {
1667             value = computed;
1668           } else if (!computed) {
1669             if (type == LAZY_FILTER_FLAG) {
1670               continue outer;
1671             } else {
1672               break outer;
1673             }
1674           }
1675         }
1676         result[resIndex++] = value;
1677       }
1678       return result;
1679     }
1680
1681     /*------------------------------------------------------------------------*/
1682
1683     /**
1684      * Creates an hash object.
1685      *
1686      * @private
1687      * @returns {Object} Returns the new hash object.
1688      */
1689     function Hash() {}
1690
1691     /**
1692      * Removes `key` and its value from the hash.
1693      *
1694      * @private
1695      * @param {Object} hash The hash to modify.
1696      * @param {string} key The key of the value to remove.
1697      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1698      */
1699     function hashDelete(hash, key) {
1700       return hashHas(hash, key) && delete hash[key];
1701     }
1702
1703     /**
1704      * Gets the hash value for `key`.
1705      *
1706      * @private
1707      * @param {Object} hash The hash to query.
1708      * @param {string} key The key of the value to get.
1709      * @returns {*} Returns the entry value.
1710      */
1711     function hashGet(hash, key) {
1712       if (nativeCreate) {
1713         var result = hash[key];
1714         return result === HASH_UNDEFINED ? undefined : result;
1715       }
1716       return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
1717     }
1718
1719     /**
1720      * Checks if a hash value for `key` exists.
1721      *
1722      * @private
1723      * @param {Object} hash The hash to query.
1724      * @param {string} key The key of the entry to check.
1725      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1726      */
1727     function hashHas(hash, key) {
1728       return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
1729     }
1730
1731     /**
1732      * Sets the hash `key` to `value`.
1733      *
1734      * @private
1735      * @param {Object} hash The hash to modify.
1736      * @param {string} key The key of the value to set.
1737      * @param {*} value The value to set.
1738      */
1739     function hashSet(hash, key, value) {
1740       hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
1741     }
1742
1743     /*------------------------------------------------------------------------*/
1744
1745     /**
1746      * Creates a map cache object to store key-value pairs.
1747      *
1748      * @private
1749      * @param {Array} [values] The values to cache.
1750      */
1751     function MapCache(values) {
1752       var index = -1,
1753           length = values ? values.length : 0;
1754
1755       this.clear();
1756       while (++index < length) {
1757         var entry = values[index];
1758         this.set(entry[0], entry[1]);
1759       }
1760     }
1761
1762     /**
1763      * Removes all key-value entries from the map.
1764      *
1765      * @private
1766      * @name clear
1767      * @memberOf MapCache
1768      */
1769     function mapClear() {
1770       this.__data__ = { 'hash': new Hash, 'map': Map ? new Map : [], 'string': new Hash };
1771     }
1772
1773     /**
1774      * Removes `key` and its value from the map.
1775      *
1776      * @private
1777      * @name delete
1778      * @memberOf MapCache
1779      * @param {string} key The key of the value to remove.
1780      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1781      */
1782     function mapDelete(key) {
1783       var data = this.__data__;
1784       if (isKeyable(key)) {
1785         return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
1786       }
1787       return Map ? data.map['delete'](key) : assocDelete(data.map, key);
1788     }
1789
1790     /**
1791      * Gets the map value for `key`.
1792      *
1793      * @private
1794      * @name get
1795      * @memberOf MapCache
1796      * @param {string} key The key of the value to get.
1797      * @returns {*} Returns the entry value.
1798      */
1799     function mapGet(key) {
1800       var data = this.__data__;
1801       if (isKeyable(key)) {
1802         return hashGet(typeof key == 'string' ? data.string : data.hash, key);
1803       }
1804       return Map ? data.map.get(key) : assocGet(data.map, key);
1805     }
1806
1807     /**
1808      * Checks if a map value for `key` exists.
1809      *
1810      * @private
1811      * @name has
1812      * @memberOf MapCache
1813      * @param {string} key The key of the entry to check.
1814      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1815      */
1816     function mapHas(key) {
1817       var data = this.__data__;
1818       if (isKeyable(key)) {
1819         return hashHas(typeof key == 'string' ? data.string : data.hash, key);
1820       }
1821       return Map ? data.map.has(key) : assocHas(data.map, key);
1822     }
1823
1824     /**
1825      * Sets the map `key` to `value`.
1826      *
1827      * @private
1828      * @name set
1829      * @memberOf MapCache
1830      * @param {string} key The key of the value to set.
1831      * @param {*} value The value to set.
1832      * @returns {Object} Returns the map cache object.
1833      */
1834     function mapSet(key, value) {
1835       var data = this.__data__;
1836       if (isKeyable(key)) {
1837         hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
1838       } else if (Map) {
1839         data.map.set(key, value);
1840       } else {
1841         assocSet(data.map, key, value);
1842       }
1843       return this;
1844     }
1845
1846     /*------------------------------------------------------------------------*/
1847
1848     /**
1849      *
1850      * Creates a set cache object to store unique values.
1851      *
1852      * @private
1853      * @param {Array} [values] The values to cache.
1854      */
1855     function SetCache(values) {
1856       var index = -1,
1857           length = values ? values.length : 0;
1858
1859       this.__data__ = new MapCache;
1860       while (++index < length) {
1861         this.push(values[index]);
1862       }
1863     }
1864
1865     /**
1866      * Checks if `value` is in `cache`.
1867      *
1868      * @private
1869      * @param {Object} cache The set cache to search.
1870      * @param {*} value The value to search for.
1871      * @returns {number} Returns `true` if `value` is found, else `false`.
1872      */
1873     function cacheHas(cache, value) {
1874       var map = cache.__data__;
1875       if (isKeyable(value)) {
1876         var data = map.__data__,
1877             hash = typeof value == 'string' ? data.string : data.hash;
1878
1879         return hash[value] === HASH_UNDEFINED;
1880       }
1881       return map.has(value);
1882     }
1883
1884     /**
1885      * Adds `value` to the set cache.
1886      *
1887      * @private
1888      * @name push
1889      * @memberOf SetCache
1890      * @param {*} value The value to cache.
1891      */
1892     function cachePush(value) {
1893       var map = this.__data__;
1894       if (isKeyable(value)) {
1895         var data = map.__data__,
1896             hash = typeof value == 'string' ? data.string : data.hash;
1897
1898         hash[value] = HASH_UNDEFINED;
1899       }
1900       else {
1901         map.set(value, HASH_UNDEFINED);
1902       }
1903     }
1904
1905     /*------------------------------------------------------------------------*/
1906
1907     /**
1908      * Creates a stack cache object to store key-value pairs.
1909      *
1910      * @private
1911      * @param {Array} [values] The values to cache.
1912      */
1913     function Stack(values) {
1914       var index = -1,
1915           length = values ? values.length : 0;
1916
1917       this.clear();
1918       while (++index < length) {
1919         var entry = values[index];
1920         this.set(entry[0], entry[1]);
1921       }
1922     }
1923
1924     /**
1925      * Removes all key-value entries from the stack.
1926      *
1927      * @private
1928      * @name clear
1929      * @memberOf Stack
1930      */
1931     function stackClear() {
1932       this.__data__ = { 'array': [], 'map': null };
1933     }
1934
1935     /**
1936      * Removes `key` and its value from the stack.
1937      *
1938      * @private
1939      * @name delete
1940      * @memberOf Stack
1941      * @param {string} key The key of the value to remove.
1942      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1943      */
1944     function stackDelete(key) {
1945       var data = this.__data__,
1946           array = data.array;
1947
1948       return array ? assocDelete(array, key) : data.map['delete'](key);
1949     }
1950
1951     /**
1952      * Gets the stack value for `key`.
1953      *
1954      * @private
1955      * @name get
1956      * @memberOf Stack
1957      * @param {string} key The key of the value to get.
1958      * @returns {*} Returns the entry value.
1959      */
1960     function stackGet(key) {
1961       var data = this.__data__,
1962           array = data.array;
1963
1964       return array ? assocGet(array, key) : data.map.get(key);
1965     }
1966
1967     /**
1968      * Checks if a stack value for `key` exists.
1969      *
1970      * @private
1971      * @name has
1972      * @memberOf Stack
1973      * @param {string} key The key of the entry to check.
1974      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1975      */
1976     function stackHas(key) {
1977       var data = this.__data__,
1978           array = data.array;
1979
1980       return array ? assocHas(array, key) : data.map.has(key);
1981     }
1982
1983     /**
1984      * Sets the stack `key` to `value`.
1985      *
1986      * @private
1987      * @name set
1988      * @memberOf Stack
1989      * @param {string} key The key of the value to set.
1990      * @param {*} value The value to set.
1991      * @returns {Object} Returns the stack cache object.
1992      */
1993     function stackSet(key, value) {
1994       var data = this.__data__,
1995           array = data.array;
1996
1997       if (array) {
1998         if (array.length < (LARGE_ARRAY_SIZE - 1)) {
1999           assocSet(array, key, value);
2000         } else {
2001           data.array = null;
2002           data.map = new MapCache(array);
2003         }
2004       }
2005       var map = data.map;
2006       if (map) {
2007         map.set(key, value);
2008       }
2009       return this;
2010     }
2011
2012     /*------------------------------------------------------------------------*/
2013
2014     /**
2015      * Removes `key` and its value from the associative array.
2016      *
2017      * @private
2018      * @param {Array} array The array to query.
2019      * @param {string} key The key of the value to remove.
2020      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2021      */
2022     function assocDelete(array, key) {
2023       var index = assocIndexOf(array, key);
2024       if (index < 0) {
2025         return false;
2026       }
2027       var lastIndex = array.length - 1;
2028       if (index == lastIndex) {
2029         array.pop();
2030       } else {
2031         splice.call(array, index, 1);
2032       }
2033       return true;
2034     }
2035
2036     /**
2037      * Gets the associative array value for `key`.
2038      *
2039      * @private
2040      * @param {Array} array The array to query.
2041      * @param {string} key The key of the value to get.
2042      * @returns {*} Returns the entry value.
2043      */
2044     function assocGet(array, key) {
2045       var index = assocIndexOf(array, key);
2046       return index < 0 ? undefined : array[index][1];
2047     }
2048
2049     /**
2050      * Checks if an associative array value for `key` exists.
2051      *
2052      * @private
2053      * @param {Array} array The array to query.
2054      * @param {string} key The key of the entry to check.
2055      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2056      */
2057     function assocHas(array, key) {
2058       return assocIndexOf(array, key) > -1;
2059     }
2060
2061     /**
2062      * Gets the index at which the first occurrence of `key` is found in `array`
2063      * of key-value pairs.
2064      *
2065      * @private
2066      * @param {Array} array The array to search.
2067      * @param {*} key The key to search for.
2068      * @returns {number} Returns the index of the matched value, else `-1`.
2069      */
2070     function assocIndexOf(array, key) {
2071       var length = array.length;
2072       while (length--) {
2073         if (eq(array[length][0], key)) {
2074           return length;
2075         }
2076       }
2077       return -1;
2078     }
2079
2080     /**
2081      * Sets the associative array `key` to `value`.
2082      *
2083      * @private
2084      * @param {Array} array The array to modify.
2085      * @param {string} key The key of the value to set.
2086      * @param {*} value The value to set.
2087      */
2088     function assocSet(array, key, value) {
2089       var index = assocIndexOf(array, key);
2090       if (index < 0) {
2091         array.push([key, value]);
2092       } else {
2093         array[index][1] = value;
2094       }
2095     }
2096
2097     /*------------------------------------------------------------------------*/
2098
2099     /**
2100      * Used by `_.defaults` to customize its `_.assignIn` use.
2101      *
2102      * @private
2103      * @param {*} objValue The destination value.
2104      * @param {*} srcValue The source value.
2105      * @param {string} key The key of the property to assign.
2106      * @param {Object} object The parent object of `objValue`.
2107      * @returns {*} Returns the value to assign.
2108      */
2109     function assignInDefaults(objValue, srcValue, key, object) {
2110       if (objValue === undefined ||
2111           (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
2112         return srcValue;
2113       }
2114       return objValue;
2115     }
2116
2117     /**
2118      * This function is like `assignValue` except that it doesn't assign `undefined` values.
2119      *
2120      * @private
2121      * @param {Object} object The object to modify.
2122      * @param {string} key The key of the property to assign.
2123      * @param {*} value The value to assign.
2124      */
2125     function assignMergeValue(object, key, value) {
2126       if ((value !== undefined && !eq(object[key], value)) ||
2127           (typeof key == 'number' && value === undefined && !(key in object))) {
2128         object[key] = value;
2129       }
2130     }
2131
2132     /**
2133      * Assigns `value` to `key` of `object` if the existing value is not equivalent
2134      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
2135      * for equality comparisons.
2136      *
2137      * @private
2138      * @param {Object} object The object to modify.
2139      * @param {string} key The key of the property to assign.
2140      * @param {*} value The value to assign.
2141      */
2142     function assignValue(object, key, value) {
2143       var objValue = object[key];
2144       if ((!eq(objValue, value) ||
2145             (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) ||
2146           (value === undefined && !(key in object))) {
2147         object[key] = value;
2148       }
2149     }
2150
2151     /**
2152      * Aggregates elements of `collection` on `accumulator` with keys transformed
2153      * by `iteratee` and values set by `setter`.
2154      *
2155      * @private
2156      * @param {Array|Object} collection The collection to iterate over.
2157      * @param {Function} setter The function to set `accumulator` values.
2158      * @param {Function} iteratee The iteratee to transform keys.
2159      * @param {Object} accumulator The initial aggregated object.
2160      * @returns {Function} Returns `accumulator`.
2161      */
2162     function baseAggregator(collection, setter, iteratee, accumulator) {
2163       baseEach(collection, function(value, key, collection) {
2164         setter(accumulator, value, iteratee(value), collection);
2165       });
2166       return accumulator;
2167     }
2168
2169     /**
2170      * The base implementation of `_.assign` without support for multiple sources
2171      * or `customizer` functions.
2172      *
2173      * @private
2174      * @param {Object} object The destination object.
2175      * @param {Object} source The source object.
2176      * @returns {Object} Returns `object`.
2177      */
2178     function baseAssign(object, source) {
2179       return object && copyObject(source, keys(source), object);
2180     }
2181
2182     /**
2183      * The base implementation of `_.at` without support for individual paths.
2184      *
2185      * @private
2186      * @param {Object} object The object to iterate over.
2187      * @param {string[]} paths The property paths of elements to pick.
2188      * @returns {Array} Returns the new array of picked elements.
2189      */
2190     function baseAt(object, paths) {
2191       var index = -1,
2192           isNil = object == null,
2193           length = paths.length,
2194           result = Array(length);
2195
2196       while (++index < length) {
2197         result[index] = isNil ? undefined : get(object, paths[index]);
2198       }
2199       return result;
2200     }
2201
2202     /**
2203      * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
2204      *
2205      * @private
2206      * @param {number} number The number to clamp.
2207      * @param {number} [lower] The lower bound.
2208      * @param {number} upper The upper bound.
2209      * @returns {number} Returns the clamped number.
2210      */
2211     function baseClamp(number, lower, upper) {
2212       if (number === number) {
2213         if (upper !== undefined) {
2214           number = number <= upper ? number : upper;
2215         }
2216         if (lower !== undefined) {
2217           number = number >= lower ? number : lower;
2218         }
2219       }
2220       return number;
2221     }
2222
2223     /**
2224      * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2225      * traversed objects.
2226      *
2227      * @private
2228      * @param {*} value The value to clone.
2229      * @param {boolean} [isDeep] Specify a deep clone.
2230      * @param {Function} [customizer] The function to customize cloning.
2231      * @param {string} [key] The key of `value`.
2232      * @param {Object} [object] The parent object of `value`.
2233      * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2234      * @returns {*} Returns the cloned value.
2235      */
2236     function baseClone(value, isDeep, customizer, key, object, stack) {
2237       var result;
2238       if (customizer) {
2239         result = object ? customizer(value, key, object, stack) : customizer(value);
2240       }
2241       if (result !== undefined) {
2242         return result;
2243       }
2244       if (!isObject(value)) {
2245         return value;
2246       }
2247       var isArr = isArray(value);
2248       if (isArr) {
2249         result = initCloneArray(value);
2250         if (!isDeep) {
2251           return copyArray(value, result);
2252         }
2253       } else {
2254         var tag = getTag(value),
2255             isFunc = tag == funcTag || tag == genTag;
2256
2257         if (isBuffer(value)) {
2258           return cloneBuffer(value, isDeep);
2259         }
2260         if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2261           if (isHostObject(value)) {
2262             return object ? value : {};
2263           }
2264           result = initCloneObject(isFunc ? {} : value);
2265           if (!isDeep) {
2266             return copySymbols(value, baseAssign(result, value));
2267           }
2268         } else {
2269           return cloneableTags[tag]
2270             ? initCloneByTag(value, tag, isDeep)
2271             : (object ? value : {});
2272         }
2273       }
2274       // Check for circular references and return its corresponding clone.
2275       stack || (stack = new Stack);
2276       var stacked = stack.get(value);
2277       if (stacked) {
2278         return stacked;
2279       }
2280       stack.set(value, result);
2281
2282       // Recursively populate clone (susceptible to call stack limits).
2283       (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
2284         assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack));
2285       });
2286       return isArr ? result : copySymbols(value, result);
2287     }
2288
2289     /**
2290      * The base implementation of `_.conforms` which doesn't clone `source`.
2291      *
2292      * @private
2293      * @param {Object} source The object of property predicates to conform to.
2294      * @returns {Function} Returns the new function.
2295      */
2296     function baseConforms(source) {
2297       var props = keys(source),
2298           length = props.length;
2299
2300       return function(object) {
2301         if (object == null) {
2302           return !length;
2303         }
2304         var index = length;
2305         while (index--) {
2306           var key = props[index],
2307               predicate = source[key],
2308               value = object[key];
2309
2310           if ((value === undefined && !(key in Object(object))) || !predicate(value)) {
2311             return false;
2312           }
2313         }
2314         return true;
2315       };
2316     }
2317
2318     /**
2319      * The base implementation of `_.create` without support for assigning
2320      * properties to the created object.
2321      *
2322      * @private
2323      * @param {Object} prototype The object to inherit from.
2324      * @returns {Object} Returns the new object.
2325      */
2326     var baseCreate = (function() {
2327       function object() {}
2328       return function(prototype) {
2329         if (isObject(prototype)) {
2330           object.prototype = prototype;
2331           var result = new object;
2332           object.prototype = undefined;
2333         }
2334         return result || {};
2335       };
2336     }());
2337
2338     /**
2339      * The base implementation of `_.delay` and `_.defer` which accepts an array
2340      * of `func` arguments.
2341      *
2342      * @private
2343      * @param {Function} func The function to delay.
2344      * @param {number} wait The number of milliseconds to delay invocation.
2345      * @param {Object} args The arguments to provide to `func`.
2346      * @returns {number} Returns the timer id.
2347      */
2348     function baseDelay(func, wait, args) {
2349       if (typeof func != 'function') {
2350         throw new TypeError(FUNC_ERROR_TEXT);
2351       }
2352       return setTimeout(function() { func.apply(undefined, args); }, wait);
2353     }
2354
2355     /**
2356      * The base implementation of methods like `_.difference` without support for
2357      * excluding multiple arrays or iteratee shorthands.
2358      *
2359      * @private
2360      * @param {Array} array The array to inspect.
2361      * @param {Array} values The values to exclude.
2362      * @param {Function} [iteratee] The iteratee invoked per element.
2363      * @param {Function} [comparator] The comparator invoked per element.
2364      * @returns {Array} Returns the new array of filtered values.
2365      */
2366     function baseDifference(array, values, iteratee, comparator) {
2367       var index = -1,
2368           includes = arrayIncludes,
2369           isCommon = true,
2370           length = array.length,
2371           result = [],
2372           valuesLength = values.length;
2373
2374       if (!length) {
2375         return result;
2376       }
2377       if (iteratee) {
2378         values = arrayMap(values, baseUnary(iteratee));
2379       }
2380       if (comparator) {
2381         includes = arrayIncludesWith;
2382         isCommon = false;
2383       }
2384       else if (values.length >= LARGE_ARRAY_SIZE) {
2385         includes = cacheHas;
2386         isCommon = false;
2387         values = new SetCache(values);
2388       }
2389       outer:
2390       while (++index < length) {
2391         var value = array[index],
2392             computed = iteratee ? iteratee(value) : value;
2393
2394         if (isCommon && computed === computed) {
2395           var valuesIndex = valuesLength;
2396           while (valuesIndex--) {
2397             if (values[valuesIndex] === computed) {
2398               continue outer;
2399             }
2400           }
2401           result.push(value);
2402         }
2403         else if (!includes(values, computed, comparator)) {
2404           result.push(value);
2405         }
2406       }
2407       return result;
2408     }
2409
2410     /**
2411      * The base implementation of `_.forEach` without support for iteratee shorthands.
2412      *
2413      * @private
2414      * @param {Array|Object} collection The collection to iterate over.
2415      * @param {Function} iteratee The function invoked per iteration.
2416      * @returns {Array|Object} Returns `collection`.
2417      */
2418     var baseEach = createBaseEach(baseForOwn);
2419
2420     /**
2421      * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2422      *
2423      * @private
2424      * @param {Array|Object} collection The collection to iterate over.
2425      * @param {Function} iteratee The function invoked per iteration.
2426      * @returns {Array|Object} Returns `collection`.
2427      */
2428     var baseEachRight = createBaseEach(baseForOwnRight, true);
2429
2430     /**
2431      * The base implementation of `_.every` without support for iteratee shorthands.
2432      *
2433      * @private
2434      * @param {Array|Object} collection The collection to iterate over.
2435      * @param {Function} predicate The function invoked per iteration.
2436      * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`
2437      */
2438     function baseEvery(collection, predicate) {
2439       var result = true;
2440       baseEach(collection, function(value, index, collection) {
2441         result = !!predicate(value, index, collection);
2442         return result;
2443       });
2444       return result;
2445     }
2446
2447     /**
2448      * The base implementation of `_.fill` without an iteratee call guard.
2449      *
2450      * @private
2451      * @param {Array} array The array to fill.
2452      * @param {*} value The value to fill `array` with.
2453      * @param {number} [start=0] The start position.
2454      * @param {number} [end=array.length] The end position.
2455      * @returns {Array} Returns `array`.
2456      */
2457     function baseFill(array, value, start, end) {
2458       var length = array.length;
2459
2460       start = toInteger(start);
2461       if (start < 0) {
2462         start = -start > length ? 0 : (length + start);
2463       }
2464       end = (end === undefined || end > length) ? length : toInteger(end);
2465       if (end < 0) {
2466         end += length;
2467       }
2468       end = start > end ? 0 : toLength(end);
2469       while (start < end) {
2470         array[start++] = value;
2471       }
2472       return array;
2473     }
2474
2475     /**
2476      * The base implementation of `_.filter` without support for iteratee shorthands.
2477      *
2478      * @private
2479      * @param {Array|Object} collection The collection to iterate over.
2480      * @param {Function} predicate The function invoked per iteration.
2481      * @returns {Array} Returns the new filtered array.
2482      */
2483     function baseFilter(collection, predicate) {
2484       var result = [];
2485       baseEach(collection, function(value, index, collection) {
2486         if (predicate(value, index, collection)) {
2487           result.push(value);
2488         }
2489       });
2490       return result;
2491     }
2492
2493     /**
2494      * The base implementation of `_.flatten` with support for restricting flattening.
2495      *
2496      * @private
2497      * @param {Array} array The array to flatten.
2498      * @param {boolean} [isDeep] Specify a deep flatten.
2499      * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
2500      * @param {Array} [result=[]] The initial result value.
2501      * @returns {Array} Returns the new flattened array.
2502      */
2503     function baseFlatten(array, isDeep, isStrict, result) {
2504       result || (result = []);
2505
2506       var index = -1,
2507           length = array.length;
2508
2509       while (++index < length) {
2510         var value = array[index];
2511         if (isArrayLikeObject(value) &&
2512             (isStrict || isArray(value) || isArguments(value))) {
2513           if (isDeep) {
2514             // Recursively flatten arrays (susceptible to call stack limits).
2515             baseFlatten(value, isDeep, isStrict, result);
2516           } else {
2517             arrayPush(result, value);
2518           }
2519         } else if (!isStrict) {
2520           result[result.length] = value;
2521         }
2522       }
2523       return result;
2524     }
2525
2526     /**
2527      * The base implementation of `baseForIn` and `baseForOwn` which iterates
2528      * over `object` properties returned by `keysFunc` invoking `iteratee` for
2529      * each property. Iteratee functions may exit iteration early by explicitly
2530      * returning `false`.
2531      *
2532      * @private
2533      * @param {Object} object The object to iterate over.
2534      * @param {Function} iteratee The function invoked per iteration.
2535      * @param {Function} keysFunc The function to get the keys of `object`.
2536      * @returns {Object} Returns `object`.
2537      */
2538     var baseFor = createBaseFor();
2539
2540     /**
2541      * This function is like `baseFor` except that it iterates over properties
2542      * in the opposite order.
2543      *
2544      * @private
2545      * @param {Object} object The object to iterate over.
2546      * @param {Function} iteratee The function invoked per iteration.
2547      * @param {Function} keysFunc The function to get the keys of `object`.
2548      * @returns {Object} Returns `object`.
2549      */
2550     var baseForRight = createBaseFor(true);
2551
2552     /**
2553      * The base implementation of `_.forIn` without support for iteratee shorthands.
2554      *
2555      * @private
2556      * @param {Object} object The object to iterate over.
2557      * @param {Function} iteratee The function invoked per iteration.
2558      * @returns {Object} Returns `object`.
2559      */
2560     function baseForIn(object, iteratee) {
2561       return object == null ? object : baseFor(object, iteratee, keysIn);
2562     }
2563
2564     /**
2565      * The base implementation of `_.forOwn` without support for iteratee shorthands.
2566      *
2567      * @private
2568      * @param {Object} object The object to iterate over.
2569      * @param {Function} iteratee The function invoked per iteration.
2570      * @returns {Object} Returns `object`.
2571      */
2572     function baseForOwn(object, iteratee) {
2573       return object && baseFor(object, iteratee, keys);
2574     }
2575
2576     /**
2577      * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
2578      *
2579      * @private
2580      * @param {Object} object The object to iterate over.
2581      * @param {Function} iteratee The function invoked per iteration.
2582      * @returns {Object} Returns `object`.
2583      */
2584     function baseForOwnRight(object, iteratee) {
2585       return object && baseForRight(object, iteratee, keys);
2586     }
2587
2588     /**
2589      * The base implementation of `_.functions` which creates an array of
2590      * `object` function property names filtered from `props`.
2591      *
2592      * @private
2593      * @param {Object} object The object to inspect.
2594      * @param {Array} props The property names to filter.
2595      * @returns {Array} Returns the new array of filtered property names.
2596      */
2597     function baseFunctions(object, props) {
2598       return arrayFilter(props, function(key) {
2599         return isFunction(object[key]);
2600       });
2601     }
2602
2603     /**
2604      * The base implementation of `_.get` without support for default values.
2605      *
2606      * @private
2607      * @param {Object} object The object to query.
2608      * @param {Array|string} path The path of the property to get.
2609      * @returns {*} Returns the resolved value.
2610      */
2611     function baseGet(object, path) {
2612       path = isKey(path, object) ? [path + ''] : baseToPath(path);
2613
2614       var index = 0,
2615           length = path.length;
2616
2617       while (object != null && index < length) {
2618         object = object[path[index++]];
2619       }
2620       return (index && index == length) ? object : undefined;
2621     }
2622
2623     /**
2624      * The base implementation of `_.has` without support for deep paths.
2625      *
2626      * @private
2627      * @param {Object} object The object to query.
2628      * @param {Array|string} key The key to check.
2629      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2630      */
2631     function baseHas(object, key) {
2632       // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
2633       // that are composed entirely of index properties, return `false` for
2634       // `hasOwnProperty` checks of them.
2635       return hasOwnProperty.call(object, key) ||
2636         (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
2637     }
2638
2639     /**
2640      * The base implementation of `_.hasIn` without support for deep paths.
2641      *
2642      * @private
2643      * @param {Object} object The object to query.
2644      * @param {Array|string} key The key to check.
2645      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2646      */
2647     function baseHasIn(object, key) {
2648       return key in Object(object);
2649     }
2650
2651     /**
2652      * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
2653      *
2654      * @private
2655      * @param {number} number The number to check.
2656      * @param {number} start The start of the range.
2657      * @param {number} end The end of the range.
2658      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
2659      */
2660     function baseInRange(number, start, end) {
2661       return number >= nativeMin(start, end) && number < nativeMax(start, end);
2662     }
2663
2664     /**
2665      * The base implementation of methods like `_.intersection`, without support
2666      * for iteratee shorthands, that accepts an array of arrays to inspect.
2667      *
2668      * @private
2669      * @param {Array} arrays The arrays to inspect.
2670      * @param {Function} [iteratee] The iteratee invoked per element.
2671      * @param {Function} [comparator] The comparator invoked per element.
2672      * @returns {Array} Returns the new array of shared values.
2673      */
2674     function baseIntersection(arrays, iteratee, comparator) {
2675       var includes = comparator ? arrayIncludesWith : arrayIncludes,
2676           othLength = arrays.length,
2677           othIndex = othLength,
2678           caches = Array(othLength),
2679           result = [];
2680
2681       while (othIndex--) {
2682         var array = arrays[othIndex];
2683         if (othIndex && iteratee) {
2684           array = arrayMap(array, baseUnary(iteratee));
2685         }
2686         caches[othIndex] = !comparator && (iteratee || array.length >= 120)
2687           ? new SetCache(othIndex && array)
2688           : undefined;
2689       }
2690       array = arrays[0];
2691
2692       var index = -1,
2693           length = array.length,
2694           seen = caches[0];
2695
2696       outer:
2697       while (++index < length) {
2698         var value = array[index],
2699             computed = iteratee ? iteratee(value) : value;
2700
2701         if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) {
2702           var othIndex = othLength;
2703           while (--othIndex) {
2704             var cache = caches[othIndex];
2705             if (!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator))) {
2706               continue outer;
2707             }
2708           }
2709           if (seen) {
2710             seen.push(computed);
2711           }
2712           result.push(value);
2713         }
2714       }
2715       return result;
2716     }
2717
2718     /**
2719      * The base implementation of `_.invert` and `_.invertBy` which inverts
2720      * `object` with values transformed by `iteratee` and set by `setter`.
2721      *
2722      * @private
2723      * @param {Object} object The object to iterate over.
2724      * @param {Function} setter The function to set `accumulator` values.
2725      * @param {Function} iteratee The iteratee to transform values.
2726      * @param {Object} accumulator The initial inverted object.
2727      * @returns {Function} Returns `accumulator`.
2728      */
2729     function baseInverter(object, setter, iteratee, accumulator) {
2730       baseForOwn(object, function(value, key, object) {
2731         setter(accumulator, iteratee(value), key, object);
2732       });
2733       return accumulator;
2734     }
2735
2736     /**
2737      * The base implementation of `_.invoke` without support for individual
2738      * method arguments.
2739      *
2740      * @private
2741      * @param {Object} object The object to query.
2742      * @param {Array|string} path The path of the method to invoke.
2743      * @param {Array} args The arguments to invoke the method with.
2744      * @returns {*} Returns the result of the invoked method.
2745      */
2746     function baseInvoke(object, path, args) {
2747       if (!isKey(path, object)) {
2748         path = baseToPath(path);
2749         object = parent(object, path);
2750         path = last(path);
2751       }
2752       var func = object == null ? object : object[path];
2753       return func == null ? undefined : apply(func, object, args);
2754     }
2755
2756     /**
2757      * The base implementation of `_.isEqual` which supports partial comparisons
2758      * and tracks traversed objects.
2759      *
2760      * @private
2761      * @param {*} value The value to compare.
2762      * @param {*} other The other value to compare.
2763      * @param {Function} [customizer] The function to customize comparisons.
2764      * @param {boolean} [bitmask] The bitmask of comparison flags.
2765      *  The bitmask may be composed of the following flags:
2766      *     1 - Unordered comparison
2767      *     2 - Partial comparison
2768      * @param {Object} [stack] Tracks traversed `value` and `other` objects.
2769      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2770      */
2771     function baseIsEqual(value, other, customizer, bitmask, stack) {
2772       if (value === other) {
2773         return true;
2774       }
2775       if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
2776         return value !== value && other !== other;
2777       }
2778       return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
2779     }
2780
2781     /**
2782      * A specialized version of `baseIsEqual` for arrays and objects which performs
2783      * deep comparisons and tracks traversed objects enabling objects with circular
2784      * references to be compared.
2785      *
2786      * @private
2787      * @param {Object} object The object to compare.
2788      * @param {Object} other The other object to compare.
2789      * @param {Function} equalFunc The function to determine equivalents of values.
2790      * @param {Function} [customizer] The function to customize comparisons.
2791      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
2792      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
2793      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
2794      */
2795     function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
2796       var objIsArr = isArray(object),
2797           othIsArr = isArray(other),
2798           objTag = arrayTag,
2799           othTag = arrayTag;
2800
2801       if (!objIsArr) {
2802         objTag = getTag(object);
2803         if (objTag == argsTag) {
2804           objTag = objectTag;
2805         } else if (objTag != objectTag) {
2806           objIsArr = isTypedArray(object);
2807         }
2808       }
2809       if (!othIsArr) {
2810         othTag = getTag(other);
2811         if (othTag == argsTag) {
2812           othTag = objectTag;
2813         } else if (othTag != objectTag) {
2814           othIsArr = isTypedArray(other);
2815         }
2816       }
2817       var objIsObj = objTag == objectTag && !isHostObject(object),
2818           othIsObj = othTag == objectTag && !isHostObject(other),
2819           isSameTag = objTag == othTag;
2820
2821       if (isSameTag && !(objIsArr || objIsObj)) {
2822         return equalByTag(object, other, objTag, equalFunc, customizer, bitmask);
2823       }
2824       var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
2825       if (!isPartial) {
2826         var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
2827             othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
2828
2829         if (objIsWrapped || othIsWrapped) {
2830           return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack);
2831         }
2832       }
2833       if (!isSameTag) {
2834         return false;
2835       }
2836       stack || (stack = new Stack);
2837       return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack);
2838     }
2839
2840     /**
2841      * The base implementation of `_.isMatch` without support for iteratee shorthands.
2842      *
2843      * @private
2844      * @param {Object} object The object to inspect.
2845      * @param {Object} source The object of property values to match.
2846      * @param {Array} matchData The property names, values, and compare flags to match.
2847      * @param {Function} [customizer] The function to customize comparisons.
2848      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
2849      */
2850     function baseIsMatch(object, source, matchData, customizer) {
2851       var index = matchData.length,
2852           length = index,
2853           noCustomizer = !customizer;
2854
2855       if (object == null) {
2856         return !length;
2857       }
2858       object = Object(object);
2859       while (index--) {
2860         var data = matchData[index];
2861         if ((noCustomizer && data[2])
2862               ? data[1] !== object[data[0]]
2863               : !(data[0] in object)
2864             ) {
2865           return false;
2866         }
2867       }
2868       while (++index < length) {
2869         data = matchData[index];
2870         var key = data[0],
2871             objValue = object[key],
2872             srcValue = data[1];
2873
2874         if (noCustomizer && data[2]) {
2875           if (objValue === undefined && !(key in object)) {
2876             return false;
2877           }
2878         } else {
2879           var stack = new Stack,
2880               result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
2881
2882           if (!(result === undefined
2883                 ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
2884                 : result
2885               )) {
2886             return false;
2887           }
2888         }
2889       }
2890       return true;
2891     }
2892
2893     /**
2894      * The base implementation of `_.iteratee`.
2895      *
2896      * @private
2897      * @param {*} [value=_.identity] The value to convert to an iteratee.
2898      * @returns {Function} Returns the iteratee.
2899      */
2900     function baseIteratee(value) {
2901       var type = typeof value;
2902       if (type == 'function') {
2903         return value;
2904       }
2905       if (value == null) {
2906         return identity;
2907       }
2908       if (type == 'object') {
2909         return isArray(value)
2910           ? baseMatchesProperty(value[0], value[1])
2911           : baseMatches(value);
2912       }
2913       return property(value);
2914     }
2915
2916     /**
2917      * The base implementation of `_.keys` which doesn't skip the constructor
2918      * property of prototypes or treat sparse arrays as dense.
2919      *
2920      * @private
2921      * @type Function
2922      * @param {Object} object The object to query.
2923      * @returns {Array} Returns the array of property names.
2924      */
2925     function baseKeys(object) {
2926       return nativeKeys(Object(object));
2927     }
2928
2929     /**
2930      * The base implementation of `_.keysIn` which doesn't skip the constructor
2931      * property of prototypes or treat sparse arrays as dense.
2932      *
2933      * @private
2934      * @param {Object} object The object to query.
2935      * @returns {Array} Returns the array of property names.
2936      */
2937     function baseKeysIn(object) {
2938       object = object == null ? object : Object(object);
2939
2940       var result = [];
2941       for (var key in object) {
2942         result.push(key);
2943       }
2944       return result;
2945     }
2946
2947     // Fallback for IE < 9 with es6-shim.
2948     if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
2949       baseKeysIn = function(object) {
2950         return iteratorToArray(enumerate(object));
2951       };
2952     }
2953
2954     /**
2955      * The base implementation of `_.map` without support for iteratee shorthands.
2956      *
2957      * @private
2958      * @param {Array|Object} collection The collection to iterate over.
2959      * @param {Function} iteratee The function invoked per iteration.
2960      * @returns {Array} Returns the new mapped array.
2961      */
2962     function baseMap(collection, iteratee) {
2963       var index = -1,
2964           result = isArrayLike(collection) ? Array(collection.length) : [];
2965
2966       baseEach(collection, function(value, key, collection) {
2967         result[++index] = iteratee(value, key, collection);
2968       });
2969       return result;
2970     }
2971
2972     /**
2973      * The base implementation of `_.matches` which doesn't clone `source`.
2974      *
2975      * @private
2976      * @param {Object} source The object of property values to match.
2977      * @returns {Function} Returns the new function.
2978      */
2979     function baseMatches(source) {
2980       var matchData = getMatchData(source);
2981       if (matchData.length == 1 && matchData[0][2]) {
2982         var key = matchData[0][0],
2983             value = matchData[0][1];
2984
2985         return function(object) {
2986           if (object == null) {
2987             return false;
2988           }
2989           return object[key] === value &&
2990             (value !== undefined || (key in Object(object)));
2991         };
2992       }
2993       return function(object) {
2994         return object === source || baseIsMatch(object, source, matchData);
2995       };
2996     }
2997
2998     /**
2999      * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3000      *
3001      * @private
3002      * @param {string} path The path of the property to get.
3003      * @param {*} srcValue The value to match.
3004      * @returns {Function} Returns the new function.
3005      */
3006     function baseMatchesProperty(path, srcValue) {
3007       return function(object) {
3008         var objValue = get(object, path);
3009         return (objValue === undefined && objValue === srcValue)
3010           ? hasIn(object, path)
3011           : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
3012       };
3013     }
3014
3015     /**
3016      * The base implementation of `_.merge` without support for multiple sources.
3017      *
3018      * @private
3019      * @param {Object} object The destination object.
3020      * @param {Object} source The source object.
3021      * @param {number} srcIndex The index of `source`.
3022      * @param {Function} [customizer] The function to customize merged values.
3023      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
3024      */
3025     function baseMerge(object, source, srcIndex, customizer, stack) {
3026       if (object === source) {
3027         return;
3028       }
3029       var props = (isArray(source) || isTypedArray(source)) ? undefined : keysIn(source);
3030       arrayEach(props || source, function(srcValue, key) {
3031         if (props) {
3032           key = srcValue;
3033           srcValue = source[key];
3034         }
3035         if (isObject(srcValue)) {
3036           stack || (stack = new Stack);
3037           baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3038         }
3039         else {
3040           var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stack) : undefined;
3041           if (newValue === undefined) {
3042             newValue = srcValue;
3043           }
3044           assignMergeValue(object, key, newValue);
3045         }
3046       });
3047     }
3048
3049     /**
3050      * A specialized version of `baseMerge` for arrays and objects which performs
3051      * deep merges and tracks traversed objects enabling objects with circular
3052      * references to be merged.
3053      *
3054      * @private
3055      * @param {Object} object The destination object.
3056      * @param {Object} source The source object.
3057      * @param {string} key The key of the value to merge.
3058      * @param {number} srcIndex The index of `source`.
3059      * @param {Function} mergeFunc The function to merge values.
3060      * @param {Function} [customizer] The function to customize assigned values.
3061      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
3062      */
3063     function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3064       var objValue = object[key],
3065           srcValue = source[key],
3066           stacked = stack.get(srcValue);
3067
3068       if (stacked) {
3069         assignMergeValue(object, key, stacked);
3070         return;
3071       }
3072       var newValue = customizer ? customizer(objValue, srcValue, (key + ''), object, source, stack) : undefined,
3073           isCommon = newValue === undefined;
3074
3075       if (isCommon) {
3076         newValue = srcValue;
3077         if (isArray(srcValue) || isTypedArray(srcValue)) {
3078           if (isArray(objValue)) {
3079             newValue = srcIndex ? copyArray(objValue) : objValue;
3080           }
3081           else if (isArrayLikeObject(objValue)) {
3082             newValue = copyArray(objValue);
3083           }
3084           else {
3085             isCommon = false;
3086             newValue = baseClone(srcValue);
3087           }
3088         }
3089         else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3090           if (isArguments(objValue)) {
3091             newValue = toPlainObject(objValue);
3092           }
3093           else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
3094             isCommon = false;
3095             newValue = baseClone(srcValue);
3096           }
3097           else {
3098             newValue = srcIndex ? baseClone(objValue) : objValue;
3099           }
3100         }
3101         else {
3102           isCommon = false;
3103         }
3104       }
3105       stack.set(srcValue, newValue);
3106
3107       if (isCommon) {
3108         // Recursively merge objects and arrays (susceptible to call stack limits).
3109         mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3110       }
3111       assignMergeValue(object, key, newValue);
3112     }
3113
3114     /**
3115      * The base implementation of `_.orderBy` without param guards.
3116      *
3117      * @private
3118      * @param {Array|Object} collection The collection to iterate over.
3119      * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3120      * @param {string[]} orders The sort orders of `iteratees`.
3121      * @returns {Array} Returns the new sorted array.
3122      */
3123     function baseOrderBy(collection, iteratees, orders) {
3124       var index = -1,
3125           toIteratee = getIteratee();
3126
3127       iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) {
3128         return toIteratee(iteratee);
3129       });
3130
3131       var result = baseMap(collection, function(value, key, collection) {
3132         var criteria = arrayMap(iteratees, function(iteratee) {
3133           return iteratee(value);
3134         });
3135         return { 'criteria': criteria, 'index': ++index, 'value': value };
3136       });
3137
3138       return baseSortBy(result, function(object, other) {
3139         return compareMultiple(object, other, orders);
3140       });
3141     }
3142
3143     /**
3144      * The base implementation of `_.pick` without support for individual
3145      * property names.
3146      *
3147      * @private
3148      * @param {Object} object The source object.
3149      * @param {string[]} props The property names to pick.
3150      * @returns {Object} Returns the new object.
3151      */
3152     function basePick(object, props) {
3153       object = Object(object);
3154       return arrayReduce(props, function(result, key) {
3155         if (key in object) {
3156           result[key] = object[key];
3157         }
3158         return result;
3159       }, {});
3160     }
3161
3162     /**
3163      * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3164      *
3165      * @private
3166      * @param {Object} object The source object.
3167      * @param {Function} predicate The function invoked per property.
3168      * @returns {Object} Returns the new object.
3169      */
3170     function basePickBy(object, predicate) {
3171       var result = {};
3172       baseForIn(object, function(value, key) {
3173         if (predicate(value, key)) {
3174           result[key] = value;
3175         }
3176       });
3177       return result;
3178     }
3179
3180     /**
3181      * The base implementation of `_.property` without support for deep paths.
3182      *
3183      * @private
3184      * @param {string} key The key of the property to get.
3185      * @returns {Function} Returns the new function.
3186      */
3187     function baseProperty(key) {
3188       return function(object) {
3189         return object == null ? undefined : object[key];
3190       };
3191     }
3192
3193     /**
3194      * A specialized version of `baseProperty` which supports deep paths.
3195      *
3196      * @private
3197      * @param {Array|string} path The path of the property to get.
3198      * @returns {Function} Returns the new function.
3199      */
3200     function basePropertyDeep(path) {
3201       return function(object) {
3202         return baseGet(object, path);
3203       };
3204     }
3205
3206     /**
3207      * The base implementation of `_.pullAll`.
3208      *
3209      * @private
3210      * @param {Array} array The array to modify.
3211      * @param {Array} values The values to remove.
3212      * @returns {Array} Returns `array`.
3213      */
3214     function basePullAll(array, values) {
3215       return basePullAllBy(array, values);
3216     }
3217
3218     /**
3219      * The base implementation of `_.pullAllBy` without support for iteratee
3220      * shorthands.
3221      *
3222      * @private
3223      * @param {Array} array The array to modify.
3224      * @param {Array} values The values to remove.
3225      * @param {Function} [iteratee] The iteratee invoked per element.
3226      * @returns {Array} Returns `array`.
3227      */
3228     function basePullAllBy(array, values, iteratee) {
3229       var index = -1,
3230           length = values.length,
3231           seen = array;
3232
3233       if (iteratee) {
3234         seen = arrayMap(array, function(value) { return iteratee(value); });
3235       }
3236       while (++index < length) {
3237         var fromIndex = 0,
3238             value = values[index],
3239             computed = iteratee ? iteratee(value) : value;
3240
3241         while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) {
3242           if (seen !== array) {
3243             splice.call(seen, fromIndex, 1);
3244           }
3245           splice.call(array, fromIndex, 1);
3246         }
3247       }
3248       return array;
3249     }
3250
3251     /**
3252      * The base implementation of `_.pullAt` without support for individual
3253      * indexes or capturing the removed elements.
3254      *
3255      * @private
3256      * @param {Array} array The array to modify.
3257      * @param {number[]} indexes The indexes of elements to remove.
3258      * @returns {Array} Returns `array`.
3259      */
3260     function basePullAt(array, indexes) {
3261       var length = array ? indexes.length : 0,
3262           lastIndex = length - 1;
3263
3264       while (length--) {
3265         var index = indexes[length];
3266         if (lastIndex == length || index != previous) {
3267           var previous = index;
3268           if (isIndex(index)) {
3269             splice.call(array, index, 1);
3270           }
3271           else if (!isKey(index, array)) {
3272             var path = baseToPath(index),
3273                 object = parent(array, path);
3274
3275             if (object != null) {
3276               delete object[last(path)];
3277             }
3278           }
3279           else {
3280             delete array[index];
3281           }
3282         }
3283       }
3284       return array;
3285     }
3286
3287     /**
3288      * The base implementation of `_.random` without support for returning
3289      * floating-point numbers.
3290      *
3291      * @private
3292      * @param {number} lower The lower bound.
3293      * @param {number} upper The upper bound.
3294      * @returns {number} Returns the random number.
3295      */
3296     function baseRandom(lower, upper) {
3297       return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3298     }
3299
3300     /**
3301      * The base implementation of `_.range` and `_.rangeRight` which doesn't
3302      * coerce arguments to numbers.
3303      *
3304      * @private
3305      * @param {number} start The start of the range.
3306      * @param {number} end The end of the range.
3307      * @param {number} step The value to increment or decrement by.
3308      * @param {boolean} [fromRight] Specify iterating from right to left.
3309      * @returns {Array} Returns the new array of numbers.
3310      */
3311     function baseRange(start, end, step, fromRight) {
3312       var index = -1,
3313           length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3314           result = Array(length);
3315
3316       while (length--) {
3317         result[fromRight ? length : ++index] = start;
3318         start += step;
3319       }
3320       return result;
3321     }
3322
3323     /**
3324      * The base implementation of `_.set`.
3325      *
3326      * @private
3327      * @param {Object} object The object to query.
3328      * @param {Array|string} path The path of the property to set.
3329      * @param {*} value The value to set.
3330      * @param {Function} [customizer] The function to customize path creation.
3331      * @returns {Object} Returns `object`.
3332      */
3333     function baseSet(object, path, value, customizer) {
3334       path = isKey(path, object) ? [path + ''] : baseToPath(path);
3335
3336       var index = -1,
3337           length = path.length,
3338           lastIndex = length - 1,
3339           nested = object;
3340
3341       while (nested != null && ++index < length) {
3342         var key = path[index];
3343         if (isObject(nested)) {
3344           var newValue = value;
3345           if (index != lastIndex) {
3346             var objValue = nested[key];
3347             newValue = customizer ? customizer(objValue, key, nested) : undefined;
3348             if (newValue === undefined) {
3349               newValue = objValue == null ? (isIndex(path[index + 1]) ? [] : {}) : objValue;
3350             }
3351           }
3352           assignValue(nested, key, newValue);
3353         }
3354         nested = nested[key];
3355       }
3356       return object;
3357     }
3358
3359     /**
3360      * The base implementation of `setData` without support for hot loop detection.
3361      *
3362      * @private
3363      * @param {Function} func The function to associate metadata with.
3364      * @param {*} data The metadata.
3365      * @returns {Function} Returns `func`.
3366      */
3367     var baseSetData = !metaMap ? identity : function(func, data) {
3368       metaMap.set(func, data);
3369       return func;
3370     };
3371
3372     /**
3373      * The base implementation of `_.slice` without an iteratee call guard.
3374      *
3375      * @private
3376      * @param {Array} array The array to slice.
3377      * @param {number} [start=0] The start position.
3378      * @param {number} [end=array.length] The end position.
3379      * @returns {Array} Returns the slice of `array`.
3380      */
3381     function baseSlice(array, start, end) {
3382       var index = -1,
3383           length = array.length;
3384
3385       if (start < 0) {
3386         start = -start > length ? 0 : (length + start);
3387       }
3388       end = end > length ? length : end;
3389       if (end < 0) {
3390         end += length;
3391       }
3392       length = start > end ? 0 : ((end - start) >>> 0);
3393       start >>>= 0;
3394
3395       var result = Array(length);
3396       while (++index < length) {
3397         result[index] = array[index + start];
3398       }
3399       return result;
3400     }
3401
3402     /**
3403      * The base implementation of `_.some` without support for iteratee shorthands.
3404      *
3405      * @private
3406      * @param {Array|Object} collection The collection to iterate over.
3407      * @param {Function} predicate The function invoked per iteration.
3408      * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
3409      */
3410     function baseSome(collection, predicate) {
3411       var result;
3412
3413       baseEach(collection, function(value, index, collection) {
3414         result = predicate(value, index, collection);
3415         return !result;
3416       });
3417       return !!result;
3418     }
3419
3420     /**
3421      * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
3422      * performs a binary search of `array` to determine the index at which `value`
3423      * should be inserted into `array` in order to maintain its sort order.
3424      *
3425      * @private
3426      * @param {Array} array The sorted array to inspect.
3427      * @param {*} value The value to evaluate.
3428      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3429      * @returns {number} Returns the index at which `value` should be inserted
3430      *  into `array`.
3431      */
3432     function baseSortedIndex(array, value, retHighest) {
3433       var low = 0,
3434           high = array ? array.length : low;
3435
3436       if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
3437         while (low < high) {
3438           var mid = (low + high) >>> 1,
3439               computed = array[mid];
3440
3441           if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
3442             low = mid + 1;
3443           } else {
3444             high = mid;
3445           }
3446         }
3447         return high;
3448       }
3449       return baseSortedIndexBy(array, value, identity, retHighest);
3450     }
3451
3452     /**
3453      * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
3454      * which invokes `iteratee` for `value` and each element of `array` to compute
3455      * their sort ranking. The iteratee is invoked with one argument; (value).
3456      *
3457      * @private
3458      * @param {Array} array The sorted array to inspect.
3459      * @param {*} value The value to evaluate.
3460      * @param {Function} iteratee The iteratee invoked per element.
3461      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3462      * @returns {number} Returns the index at which `value` should be inserted into `array`.
3463      */
3464     function baseSortedIndexBy(array, value, iteratee, retHighest) {
3465       value = iteratee(value);
3466
3467       var low = 0,
3468           high = array ? array.length : 0,
3469           valIsNaN = value !== value,
3470           valIsNull = value === null,
3471           valIsUndef = value === undefined;
3472
3473       while (low < high) {
3474         var mid = nativeFloor((low + high) / 2),
3475             computed = iteratee(array[mid]),
3476             isDef = computed !== undefined,
3477             isReflexive = computed === computed;
3478
3479         if (valIsNaN) {
3480           var setLow = isReflexive || retHighest;
3481         } else if (valIsNull) {
3482           setLow = isReflexive && isDef && (retHighest || computed != null);
3483         } else if (valIsUndef) {
3484           setLow = isReflexive && (retHighest || isDef);
3485         } else if (computed == null) {
3486           setLow = false;
3487         } else {
3488           setLow = retHighest ? (computed <= value) : (computed < value);
3489         }
3490         if (setLow) {
3491           low = mid + 1;
3492         } else {
3493           high = mid;
3494         }
3495       }
3496       return nativeMin(high, MAX_ARRAY_INDEX);
3497     }
3498
3499     /**
3500      * The base implementation of `_.sortedUniq`.
3501      *
3502      * @private
3503      * @param {Array} array The array to inspect.
3504      * @returns {Array} Returns the new duplicate free array.
3505      */
3506     function baseSortedUniq(array) {
3507       return baseSortedUniqBy(array);
3508     }
3509
3510     /**
3511      * The base implementation of `_.sortedUniqBy` without support for iteratee
3512      * shorthands.
3513      *
3514      * @private
3515      * @param {Array} array The array to inspect.
3516      * @param {Function} [iteratee] The iteratee invoked per element.
3517      * @returns {Array} Returns the new duplicate free array.
3518      */
3519     function baseSortedUniqBy(array, iteratee) {
3520       var index = 0,
3521           length = array.length,
3522           value = array[0],
3523           computed = iteratee ? iteratee(value) : value,
3524           seen = computed,
3525           resIndex = 0,
3526           result = [value];
3527
3528       while (++index < length) {
3529         value = array[index],
3530         computed = iteratee ? iteratee(value) : value;
3531
3532         if (!eq(computed, seen)) {
3533           seen = computed;
3534           result[++resIndex] = value;
3535         }
3536       }
3537       return result;
3538     }
3539
3540     /**
3541      * The base implementation of `_.toPath` which only converts `value` to a
3542      * path if it's not one.
3543      *
3544      * @private
3545      * @param {*} value The value to process.
3546      * @returns {Array} Returns the property path array.
3547      */
3548     function baseToPath(value) {
3549       return isArray(value) ? value : stringToPath(value);
3550     }
3551
3552     /**
3553      * The base implementation of `_.uniqBy` without support for iteratee shorthands.
3554      *
3555      * @private
3556      * @param {Array} array The array to inspect.
3557      * @param {Function} [iteratee] The iteratee invoked per element.
3558      * @param {Function} [comparator] The comparator invoked per element.
3559      * @returns {Array} Returns the new duplicate free array.
3560      */
3561     function baseUniq(array, iteratee, comparator) {
3562       var index = -1,
3563           includes = arrayIncludes,
3564           length = array.length,
3565           isCommon = true,
3566           result = [],
3567           seen = result;
3568
3569       if (comparator) {
3570         isCommon = false;
3571         includes = arrayIncludesWith;
3572       }
3573       else if (length >= LARGE_ARRAY_SIZE) {
3574         var set = iteratee ? null : createSet(array);
3575         if (set) {
3576           return setToArray(set);
3577         }
3578         isCommon = false;
3579         includes = cacheHas;
3580         seen = new SetCache;
3581       }
3582       else {
3583         seen = iteratee ? [] : result;
3584       }
3585       outer:
3586       while (++index < length) {
3587         var value = array[index],
3588             computed = iteratee ? iteratee(value) : value;
3589
3590         if (isCommon && computed === computed) {
3591           var seenIndex = seen.length;
3592           while (seenIndex--) {
3593             if (seen[seenIndex] === computed) {
3594               continue outer;
3595             }
3596           }
3597           if (iteratee) {
3598             seen.push(computed);
3599           }
3600           result.push(value);
3601         }
3602         else if (!includes(seen, computed, comparator)) {
3603           if (seen !== result) {
3604             seen.push(computed);
3605           }
3606           result.push(value);
3607         }
3608       }
3609       return result;
3610     }
3611
3612     /**
3613      * The base implementation of `_.unset`.
3614      *
3615      * @private
3616      * @param {Object} object The object to modify.
3617      * @param {Array|string} path The path of the property to unset.
3618      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
3619      */
3620     function baseUnset(object, path) {
3621       path = isKey(path, object) ? [path + ''] : baseToPath(path);
3622       object = parent(object, path);
3623       var key = last(path);
3624       return (object != null && has(object, key)) ? delete object[key] : true;
3625     }
3626
3627     /**
3628      * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
3629      * without support for iteratee shorthands.
3630      *
3631      * @private
3632      * @param {Array} array The array to query.
3633      * @param {Function} predicate The function invoked per iteration.
3634      * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
3635      * @param {boolean} [fromRight] Specify iterating from right to left.
3636      * @returns {Array} Returns the slice of `array`.
3637      */
3638     function baseWhile(array, predicate, isDrop, fromRight) {
3639       var length = array.length,
3640           index = fromRight ? length : -1;
3641
3642       while ((fromRight ? index-- : ++index < length) &&
3643         predicate(array[index], index, array)) {}
3644
3645       return isDrop
3646         ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
3647         : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
3648     }
3649
3650     /**
3651      * The base implementation of `wrapperValue` which returns the result of
3652      * performing a sequence of actions on the unwrapped `value`, where each
3653      * successive action is supplied the return value of the previous.
3654      *
3655      * @private
3656      * @param {*} value The unwrapped value.
3657      * @param {Array} actions Actions to perform to resolve the unwrapped value.
3658      * @returns {*} Returns the resolved value.
3659      */
3660     function baseWrapperValue(value, actions) {
3661       var result = value;
3662       if (result instanceof LazyWrapper) {
3663         result = result.value();
3664       }
3665       return arrayReduce(actions, function(result, action) {
3666         return action.func.apply(action.thisArg, arrayPush([result], action.args));
3667       }, result);
3668     }
3669
3670     /**
3671      * The base implementation of methods like `_.xor`, without support for
3672      * iteratee shorthands, that accepts an array of arrays to inspect.
3673      *
3674      * @private
3675      * @param {Array} arrays The arrays to inspect.
3676      * @param {Function} [iteratee] The iteratee invoked per element.
3677      * @param {Function} [comparator] The comparator invoked per element.
3678      * @returns {Array} Returns the new array of values.
3679      */
3680     function baseXor(arrays, iteratee, comparator) {
3681       var index = -1,
3682           length = arrays.length;
3683
3684       while (++index < length) {
3685         var result = result
3686           ? arrayPush(
3687               baseDifference(result, arrays[index], iteratee, comparator),
3688               baseDifference(arrays[index], result, iteratee, comparator)
3689             )
3690           : arrays[index];
3691       }
3692       return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
3693     }
3694
3695     /**
3696      * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
3697      *
3698      * @private
3699      * @param {Array} props The property names.
3700      * @param {Array} values The property values.
3701      * @param {Function} assignFunc The function to assign values.
3702      * @returns {Object} Returns the new object.
3703      */
3704     function baseZipObject(props, values, assignFunc) {
3705       var index = -1,
3706           length = props.length,
3707           valsLength = values.length,
3708           result = {};
3709
3710       while (++index < length) {
3711         assignFunc(result, props[index], index < valsLength ? values[index] : undefined);
3712       }
3713       return result;
3714     }
3715
3716     /**
3717      * Creates a clone of  `buffer`.
3718      *
3719      * @private
3720      * @param {Buffer} buffer The buffer to clone.
3721      * @param {boolean} [isDeep] Specify a deep clone.
3722      * @returns {Buffer} Returns the cloned buffer.
3723      */
3724     function cloneBuffer(buffer, isDeep) {
3725       if (isDeep) {
3726         return buffer.slice();
3727       }
3728       var Ctor = buffer.constructor,
3729           result = new Ctor(buffer.length);
3730
3731       buffer.copy(result);
3732       return result;
3733     }
3734
3735     /**
3736      * Creates a clone of `arrayBuffer`.
3737      *
3738      * @private
3739      * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
3740      * @returns {ArrayBuffer} Returns the cloned array buffer.
3741      */
3742     function cloneArrayBuffer(arrayBuffer) {
3743       var Ctor = arrayBuffer.constructor,
3744           result = new Ctor(arrayBuffer.byteLength),
3745           view = new Uint8Array(result);
3746
3747       view.set(new Uint8Array(arrayBuffer));
3748       return result;
3749     }
3750
3751     /**
3752      * Creates a clone of `map`.
3753      *
3754      * @private
3755      * @param {Object} map The map to clone.
3756      * @returns {Object} Returns the cloned map.
3757      */
3758     function cloneMap(map) {
3759       var Ctor = map.constructor;
3760       return arrayReduce(mapToArray(map), addMapEntry, new Ctor);
3761     }
3762
3763     /**
3764      * Creates a clone of `regexp`.
3765      *
3766      * @private
3767      * @param {Object} regexp The regexp to clone.
3768      * @returns {Object} Returns the cloned regexp.
3769      */
3770     function cloneRegExp(regexp) {
3771       var Ctor = regexp.constructor,
3772           result = new Ctor(regexp.source, reFlags.exec(regexp));
3773
3774       result.lastIndex = regexp.lastIndex;
3775       return result;
3776     }
3777
3778     /**
3779      * Creates a clone of `set`.
3780      *
3781      * @private
3782      * @param {Object} set The set to clone.
3783      * @returns {Object} Returns the cloned set.
3784      */
3785     function cloneSet(set) {
3786       var Ctor = set.constructor;
3787       return arrayReduce(setToArray(set), addSetEntry, new Ctor);
3788     }
3789
3790     /**
3791      * Creates a clone of the `symbol` object.
3792      *
3793      * @private
3794      * @param {Object} symbol The symbol object to clone.
3795      * @returns {Object} Returns the cloned symbol object.
3796      */
3797     function cloneSymbol(symbol) {
3798       return Symbol ? Object(symbolValueOf.call(symbol)) : {};
3799     }
3800
3801     /**
3802      * Creates a clone of `typedArray`.
3803      *
3804      * @private
3805      * @param {Object} typedArray The typed array to clone.
3806      * @param {boolean} [isDeep] Specify a deep clone.
3807      * @returns {Object} Returns the cloned typed array.
3808      */
3809     function cloneTypedArray(typedArray, isDeep) {
3810       var buffer = typedArray.buffer,
3811           Ctor = typedArray.constructor;
3812
3813       return new Ctor(isDeep ? cloneArrayBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length);
3814     }
3815
3816     /**
3817      * Creates an array that is the composition of partially applied arguments,
3818      * placeholders, and provided arguments into a single array of arguments.
3819      *
3820      * @private
3821      * @param {Array|Object} args The provided arguments.
3822      * @param {Array} partials The arguments to prepend to those provided.
3823      * @param {Array} holders The `partials` placeholder indexes.
3824      * @returns {Array} Returns the new array of composed arguments.
3825      */
3826     function composeArgs(args, partials, holders) {
3827       var holdersLength = holders.length,
3828           argsIndex = -1,
3829           argsLength = nativeMax(args.length - holdersLength, 0),
3830           leftIndex = -1,
3831           leftLength = partials.length,
3832           result = Array(leftLength + argsLength);
3833
3834       while (++leftIndex < leftLength) {
3835         result[leftIndex] = partials[leftIndex];
3836       }
3837       while (++argsIndex < holdersLength) {
3838         result[holders[argsIndex]] = args[argsIndex];
3839       }
3840       while (argsLength--) {
3841         result[leftIndex++] = args[argsIndex++];
3842       }
3843       return result;
3844     }
3845
3846     /**
3847      * This function is like `composeArgs` except that the arguments composition
3848      * is tailored for `_.partialRight`.
3849      *
3850      * @private
3851      * @param {Array|Object} args The provided arguments.
3852      * @param {Array} partials The arguments to append to those provided.
3853      * @param {Array} holders The `partials` placeholder indexes.
3854      * @returns {Array} Returns the new array of composed arguments.
3855      */
3856     function composeArgsRight(args, partials, holders) {
3857       var holdersIndex = -1,
3858           holdersLength = holders.length,
3859           argsIndex = -1,
3860           argsLength = nativeMax(args.length - holdersLength, 0),
3861           rightIndex = -1,
3862           rightLength = partials.length,
3863           result = Array(argsLength + rightLength);
3864
3865       while (++argsIndex < argsLength) {
3866         result[argsIndex] = args[argsIndex];
3867       }
3868       var offset = argsIndex;
3869       while (++rightIndex < rightLength) {
3870         result[offset + rightIndex] = partials[rightIndex];
3871       }
3872       while (++holdersIndex < holdersLength) {
3873         result[offset + holders[holdersIndex]] = args[argsIndex++];
3874       }
3875       return result;
3876     }
3877
3878     /**
3879      * Copies the values of `source` to `array`.
3880      *
3881      * @private
3882      * @param {Array} source The array to copy values from.
3883      * @param {Array} [array=[]] The array to copy values to.
3884      * @returns {Array} Returns `array`.
3885      */
3886     function copyArray(source, array) {
3887       var index = -1,
3888           length = source.length;
3889
3890       array || (array = Array(length));
3891       while (++index < length) {
3892         array[index] = source[index];
3893       }
3894       return array;
3895     }
3896
3897     /**
3898      * Copies properties of `source` to `object`.
3899      *
3900      * @private
3901      * @param {Object} source The object to copy properties from.
3902      * @param {Array} props The property names to copy.
3903      * @param {Object} [object={}] The object to copy properties to.
3904      * @returns {Object} Returns `object`.
3905      */
3906     function copyObject(source, props, object) {
3907       return copyObjectWith(source, props, object);
3908     }
3909
3910     /**
3911      * This function is like `copyObject` except that it accepts a function to
3912      * customize copied values.
3913      *
3914      * @private
3915      * @param {Object} source The object to copy properties from.
3916      * @param {Array} props The property names to copy.
3917      * @param {Object} [object={}] The object to copy properties to.
3918      * @param {Function} [customizer] The function to customize copied values.
3919      * @returns {Object} Returns `object`.
3920      */
3921     function copyObjectWith(source, props, object, customizer) {
3922       object || (object = {});
3923
3924       var index = -1,
3925           length = props.length;
3926
3927       while (++index < length) {
3928         var key = props[index],
3929             newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key];
3930
3931         assignValue(object, key, newValue);
3932       }
3933       return object;
3934     }
3935
3936     /**
3937      * Copies own symbol properties of `source` to `object`.
3938      *
3939      * @private
3940      * @param {Object} source The object to copy symbols from.
3941      * @param {Object} [object={}] The object to copy symbols to.
3942      * @returns {Object} Returns `object`.
3943      */
3944     function copySymbols(source, object) {
3945       return copyObject(source, getSymbols(source), object);
3946     }
3947
3948     /**
3949      * Creates a function like `_.groupBy`.
3950      *
3951      * @private
3952      * @param {Function} setter The function to set accumulator values.
3953      * @param {Function} [initializer] The accumulator object initializer.
3954      * @returns {Function} Returns the new aggregator function.
3955      */
3956     function createAggregator(setter, initializer) {
3957       return function(collection, iteratee) {
3958         var func = isArray(collection) ? arrayAggregator : baseAggregator,
3959             accumulator = initializer ? initializer() : {};
3960
3961         return func(collection, setter, getIteratee(iteratee), accumulator);
3962       };
3963     }
3964
3965     /**
3966      * Creates a function like `_.assign`.
3967      *
3968      * @private
3969      * @param {Function} assigner The function to assign values.
3970      * @returns {Function} Returns the new assigner function.
3971      */
3972     function createAssigner(assigner) {
3973       return rest(function(object, sources) {
3974         var index = -1,
3975             length = sources.length,
3976             customizer = length > 1 ? sources[length - 1] : undefined,
3977             guard = length > 2 ? sources[2] : undefined;
3978
3979         customizer = typeof customizer == 'function' ? (length--, customizer) : undefined;
3980         if (guard && isIterateeCall(sources[0], sources[1], guard)) {
3981           customizer = length < 3 ? undefined : customizer;
3982           length = 1;
3983         }
3984         object = Object(object);
3985         while (++index < length) {
3986           var source = sources[index];
3987           if (source) {
3988             assigner(object, source, index, customizer);
3989           }
3990         }
3991         return object;
3992       });
3993     }
3994
3995     /**
3996      * Creates a `baseEach` or `baseEachRight` function.
3997      *
3998      * @private
3999      * @param {Function} eachFunc The function to iterate over a collection.
4000      * @param {boolean} [fromRight] Specify iterating from right to left.
4001      * @returns {Function} Returns the new base function.
4002      */
4003     function createBaseEach(eachFunc, fromRight) {
4004       return function(collection, iteratee) {
4005         if (collection == null) {
4006           return collection;
4007         }
4008         if (!isArrayLike(collection)) {
4009           return eachFunc(collection, iteratee);
4010         }
4011         var length = collection.length,
4012             index = fromRight ? length : -1,
4013             iterable = Object(collection);
4014
4015         while ((fromRight ? index-- : ++index < length)) {
4016           if (iteratee(iterable[index], index, iterable) === false) {
4017             break;
4018           }
4019         }
4020         return collection;
4021       };
4022     }
4023
4024     /**
4025      * Creates a base function for methods like `_.forIn`.
4026      *
4027      * @private
4028      * @param {boolean} [fromRight] Specify iterating from right to left.
4029      * @returns {Function} Returns the new base function.
4030      */
4031     function createBaseFor(fromRight) {
4032       return function(object, iteratee, keysFunc) {
4033         var index = -1,
4034             iterable = Object(object),
4035             props = keysFunc(object),
4036             length = props.length;
4037
4038         while (length--) {
4039           var key = props[fromRight ? length : ++index];
4040           if (iteratee(iterable[key], key, iterable) === false) {
4041             break;
4042           }
4043         }
4044         return object;
4045       };
4046     }
4047
4048     /**
4049      * Creates a function that wraps `func` to invoke it with the optional `this`
4050      * binding of `thisArg`.
4051      *
4052      * @private
4053      * @param {Function} func The function to wrap.
4054      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4055      * @param {*} [thisArg] The `this` binding of `func`.
4056      * @returns {Function} Returns the new wrapped function.
4057      */
4058     function createBaseWrapper(func, bitmask, thisArg) {
4059       var isBind = bitmask & BIND_FLAG,
4060           Ctor = createCtorWrapper(func);
4061
4062       function wrapper() {
4063         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4064         return fn.apply(isBind ? thisArg : this, arguments);
4065       }
4066       return wrapper;
4067     }
4068
4069     /**
4070      * Creates a function like `_.lowerFirst`.
4071      *
4072      * @private
4073      * @param {string} methodName The name of the `String` case method to use.
4074      * @returns {Function} Returns the new function.
4075      */
4076     function createCaseFirst(methodName) {
4077       return function(string) {
4078         string = toString(string);
4079
4080         var strSymbols = reHasComplexSymbol.test(string) ? stringToArray(string) : undefined,
4081             chr = strSymbols ? strSymbols[0] : string.charAt(0),
4082             trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1);
4083
4084         return chr[methodName]() + trailing;
4085       };
4086     }
4087
4088     /**
4089      * Creates a function like `_.camelCase`.
4090      *
4091      * @private
4092      * @param {Function} callback The function to combine each word.
4093      * @returns {Function} Returns the new compounder function.
4094      */
4095     function createCompounder(callback) {
4096       return function(string) {
4097         return arrayReduce(words(deburr(string)), callback, '');
4098       };
4099     }
4100
4101     /**
4102      * Creates a function that produces an instance of `Ctor` regardless of
4103      * whether it was invoked as part of a `new` expression or by `call` or `apply`.
4104      *
4105      * @private
4106      * @param {Function} Ctor The constructor to wrap.
4107      * @returns {Function} Returns the new wrapped function.
4108      */
4109     function createCtorWrapper(Ctor) {
4110       return function() {
4111         // Use a `switch` statement to work with class constructors.
4112         // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
4113         // for more details.
4114         var args = arguments;
4115         switch (args.length) {
4116           case 0: return new Ctor;
4117           case 1: return new Ctor(args[0]);
4118           case 2: return new Ctor(args[0], args[1]);
4119           case 3: return new Ctor(args[0], args[1], args[2]);
4120           case 4: return new Ctor(args[0], args[1], args[2], args[3]);
4121           case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
4122           case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
4123           case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
4124         }
4125         var thisBinding = baseCreate(Ctor.prototype),
4126             result = Ctor.apply(thisBinding, args);
4127
4128         // Mimic the constructor's `return` behavior.
4129         // See https://es5.github.io/#x13.2.2 for more details.
4130         return isObject(result) ? result : thisBinding;
4131       };
4132     }
4133
4134     /**
4135      * Creates a function that wraps `func` to enable currying.
4136      *
4137      * @private
4138      * @param {Function} func The function to wrap.
4139      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4140      * @param {number} arity The arity of `func`.
4141      * @returns {Function} Returns the new wrapped function.
4142      */
4143     function createCurryWrapper(func, bitmask, arity) {
4144       var Ctor = createCtorWrapper(func);
4145
4146       function wrapper() {
4147         var length = arguments.length,
4148             index = length,
4149             args = Array(length),
4150             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func,
4151             placeholder = lodash.placeholder || wrapper.placeholder;
4152
4153         while (index--) {
4154           args[index] = arguments[index];
4155         }
4156         var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
4157           ? []
4158           : replaceHolders(args, placeholder);
4159
4160         length -= holders.length;
4161         return length < arity
4162           ? createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, undefined, args, holders, undefined, undefined, arity - length)
4163           : apply(fn, this, args);
4164       }
4165       return wrapper;
4166     }
4167
4168     /**
4169      * Creates a `_.flow` or `_.flowRight` function.
4170      *
4171      * @private
4172      * @param {boolean} [fromRight] Specify iterating from right to left.
4173      * @returns {Function} Returns the new flow function.
4174      */
4175     function createFlow(fromRight) {
4176       return rest(function(funcs) {
4177         funcs = baseFlatten(funcs);
4178
4179         var length = funcs.length,
4180             index = length,
4181             prereq = LodashWrapper.prototype.thru;
4182
4183         if (fromRight) {
4184           funcs.reverse();
4185         }
4186         while (index--) {
4187           var func = funcs[index];
4188           if (typeof func != 'function') {
4189             throw new TypeError(FUNC_ERROR_TEXT);
4190           }
4191           if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
4192             var wrapper = new LodashWrapper([], true);
4193           }
4194         }
4195         index = wrapper ? index : length;
4196         while (++index < length) {
4197           func = funcs[index];
4198
4199           var funcName = getFuncName(func),
4200               data = funcName == 'wrapper' ? getData(func) : undefined;
4201
4202           if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) {
4203             wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
4204           } else {
4205             wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);
4206           }
4207         }
4208         return function() {
4209           var args = arguments,
4210               value = args[0];
4211
4212           if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
4213             return wrapper.plant(value).value();
4214           }
4215           var index = 0,
4216               result = length ? funcs[index].apply(this, args) : value;
4217
4218           while (++index < length) {
4219             result = funcs[index].call(this, result);
4220           }
4221           return result;
4222         };
4223       });
4224     }
4225
4226     /**
4227      * Creates a function that wraps `func` to invoke it with optional `this`
4228      * binding of `thisArg`, partial application, and currying.
4229      *
4230      * @private
4231      * @param {Function|string} func The function or method name to wrap.
4232      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4233      * @param {*} [thisArg] The `this` binding of `func`.
4234      * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4235      * @param {Array} [holders] The `partials` placeholder indexes.
4236      * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
4237      * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
4238      * @param {Array} [argPos] The argument positions of the new function.
4239      * @param {number} [ary] The arity cap of `func`.
4240      * @param {number} [arity] The arity of `func`.
4241      * @returns {Function} Returns the new wrapped function.
4242      */
4243     function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
4244       var isAry = bitmask & ARY_FLAG,
4245           isBind = bitmask & BIND_FLAG,
4246           isBindKey = bitmask & BIND_KEY_FLAG,
4247           isCurry = bitmask & CURRY_FLAG,
4248           isCurryRight = bitmask & CURRY_RIGHT_FLAG,
4249           isFlip = bitmask & FLIP_FLAG,
4250           Ctor = isBindKey ? undefined : createCtorWrapper(func);
4251
4252       function wrapper() {
4253         var length = arguments.length,
4254             index = length,
4255             args = Array(length);
4256
4257         while (index--) {
4258           args[index] = arguments[index];
4259         }
4260         if (partials) {
4261           args = composeArgs(args, partials, holders);
4262         }
4263         if (partialsRight) {
4264           args = composeArgsRight(args, partialsRight, holdersRight);
4265         }
4266         if (isCurry || isCurryRight) {
4267           var placeholder = lodash.placeholder || wrapper.placeholder,
4268               argsHolders = replaceHolders(args, placeholder);
4269
4270           length -= argsHolders.length;
4271           if (length < arity) {
4272             return createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, thisArg, args, argsHolders, argPos, ary, arity - length);
4273           }
4274         }
4275         var thisBinding = isBind ? thisArg : this,
4276             fn = isBindKey ? thisBinding[func] : func;
4277
4278         if (argPos) {
4279           args = reorder(args, argPos);
4280         } else if (isFlip && args.length > 1) {
4281           args.reverse();
4282         }
4283         if (isAry && ary < args.length) {
4284           args.length = ary;
4285         }
4286         if (this && this !== root && this instanceof wrapper) {
4287           fn = Ctor || createCtorWrapper(fn);
4288         }
4289         return fn.apply(thisBinding, args);
4290       }
4291       return wrapper;
4292     }
4293
4294     /**
4295      * Creates a function like `_.invertBy`.
4296      *
4297      * @private
4298      * @param {Function} setter The function to set accumulator values.
4299      * @param {Function} toIteratee The function to resolve iteratees.
4300      * @returns {Function} Returns the new inverter function.
4301      */
4302     function createInverter(setter, toIteratee) {
4303       return function(object, iteratee) {
4304         return baseInverter(object, setter, toIteratee(iteratee), {});
4305       };
4306     }
4307
4308     /**
4309      * Creates a function like `_.over`.
4310      *
4311      * @private
4312      * @param {Function} arrayFunc The function to iterate over iteratees.
4313      * @returns {Function} Returns the new invoker function.
4314      */
4315     function createOver(arrayFunc) {
4316       return rest(function(iteratees) {
4317         iteratees = arrayMap(baseFlatten(iteratees), getIteratee());
4318         return rest(function(args) {
4319           var thisArg = this;
4320           return arrayFunc(iteratees, function(iteratee) {
4321             return apply(iteratee, thisArg, args);
4322           });
4323         });
4324       });
4325     }
4326
4327     /**
4328      * Creates the padding for `string` based on `length`. The `chars` string
4329      * is truncated if the number of characters exceeds `length`.
4330      *
4331      * @private
4332      * @param {string} string The string to create padding for.
4333      * @param {number} [length=0] The padding length.
4334      * @param {string} [chars=' '] The string used as padding.
4335      * @returns {string} Returns the padding for `string`.
4336      */
4337     function createPadding(string, length, chars) {
4338       length = toInteger(length);
4339
4340       var strLength = stringSize(string);
4341       if (!length || strLength >= length) {
4342         return '';
4343       }
4344       var padLength = length - strLength;
4345       chars = chars === undefined ? ' ' : (chars + '');
4346
4347       var result = repeat(chars, nativeCeil(padLength / stringSize(chars)));
4348       return reHasComplexSymbol.test(chars)
4349         ? stringToArray(result).slice(0, padLength).join('')
4350         : result.slice(0, padLength);
4351     }
4352
4353     /**
4354      * Creates a function that wraps `func` to invoke it with the optional `this`
4355      * binding of `thisArg` and the `partials` prepended to those provided to
4356      * the wrapper.
4357      *
4358      * @private
4359      * @param {Function} func The function to wrap.
4360      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4361      * @param {*} thisArg The `this` binding of `func`.
4362      * @param {Array} partials The arguments to prepend to those provided to the new function.
4363      * @returns {Function} Returns the new wrapped function.
4364      */
4365     function createPartialWrapper(func, bitmask, thisArg, partials) {
4366       var isBind = bitmask & BIND_FLAG,
4367           Ctor = createCtorWrapper(func);
4368
4369       function wrapper() {
4370         var argsIndex = -1,
4371             argsLength = arguments.length,
4372             leftIndex = -1,
4373             leftLength = partials.length,
4374             args = Array(leftLength + argsLength),
4375             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4376
4377         while (++leftIndex < leftLength) {
4378           args[leftIndex] = partials[leftIndex];
4379         }
4380         while (argsLength--) {
4381           args[leftIndex++] = arguments[++argsIndex];
4382         }
4383         return apply(fn, isBind ? thisArg : this, args);
4384       }
4385       return wrapper;
4386     }
4387
4388     /**
4389      * Creates a `_.range` or `_.rangeRight` function.
4390      *
4391      * @private
4392      * @param {boolean} [fromRight] Specify iterating from right to left.
4393      * @returns {Function} Returns the new range function.
4394      */
4395     function createRange(fromRight) {
4396       return function(start, end, step) {
4397         if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
4398           end = step = undefined;
4399         }
4400         // Ensure the sign of `-0` is preserved.
4401         start = toNumber(start);
4402         start = start === start ? start : 0;
4403         if (end === undefined) {
4404           end = start;
4405           start = 0;
4406         } else {
4407           end = toNumber(end) || 0;
4408         }
4409         step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
4410         return baseRange(start, end, step, fromRight);
4411       };
4412     }
4413
4414     /**
4415      * Creates a function that wraps `func` to continue currying.
4416      *
4417      * @private
4418      * @param {Function} func The function to wrap.
4419      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4420      * @param {Function} wrapFunc The function to create the `func` wrapper.
4421      * @param {*} placeholder The placeholder to replace.
4422      * @param {*} [thisArg] The `this` binding of `func`.
4423      * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4424      * @param {Array} [holders] The `partials` placeholder indexes.
4425      * @param {Array} [argPos] The argument positions of the new function.
4426      * @param {number} [ary] The arity cap of `func`.
4427      * @param {number} [arity] The arity of `func`.
4428      * @returns {Function} Returns the new wrapped function.
4429      */
4430     function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
4431       var isCurry = bitmask & CURRY_FLAG,
4432           newArgPos = argPos ? copyArray(argPos) : undefined,
4433           newsHolders = isCurry ? holders : undefined,
4434           newHoldersRight = isCurry ? undefined : holders,
4435           newPartials = isCurry ? partials : undefined,
4436           newPartialsRight = isCurry ? undefined : partials;
4437
4438       bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
4439       bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
4440
4441       if (!(bitmask & CURRY_BOUND_FLAG)) {
4442         bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
4443       }
4444       var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, arity],
4445           result = wrapFunc.apply(undefined, newData);
4446
4447       if (isLaziable(func)) {
4448         setData(result, newData);
4449       }
4450       result.placeholder = placeholder;
4451       return result;
4452     }
4453
4454     /**
4455      * Creates a function like `_.round`.
4456      *
4457      * @private
4458      * @param {string} methodName The name of the `Math` method to use when rounding.
4459      * @returns {Function} Returns the new round function.
4460      */
4461     function createRound(methodName) {
4462       var func = Math[methodName];
4463       return function(number, precision) {
4464         number = toNumber(number);
4465         precision = toInteger(precision);
4466         if (precision) {
4467           // Shift with exponential notation to avoid floating-point issues.
4468           // See [MDN](https://mdn.io/round#Examples) for more details.
4469           var pair = (toString(number) + 'e').split('e'),
4470               value = func(pair[0] + 'e' + (+pair[1] + precision));
4471
4472           pair = (toString(value) + 'e').split('e');
4473           return +(pair[0] + 'e' + (+pair[1] - precision));
4474         }
4475         return func(number);
4476       };
4477     }
4478
4479     /**
4480      * Creates a set of `values`.
4481      *
4482      * @private
4483      * @param {Array} values The values to add to the set.
4484      * @returns {Object} Returns the new set.
4485      */
4486     var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) {
4487       return new Set(values);
4488     };
4489
4490     /**
4491      * Creates a function that either curries or invokes `func` with optional
4492      * `this` binding and partially applied arguments.
4493      *
4494      * @private
4495      * @param {Function|string} func The function or method name to wrap.
4496      * @param {number} bitmask The bitmask of wrapper flags.
4497      *  The bitmask may be composed of the following flags:
4498      *     1 - `_.bind`
4499      *     2 - `_.bindKey`
4500      *     4 - `_.curry` or `_.curryRight` of a bound function
4501      *     8 - `_.curry`
4502      *    16 - `_.curryRight`
4503      *    32 - `_.partial`
4504      *    64 - `_.partialRight`
4505      *   128 - `_.rearg`
4506      *   256 - `_.ary`
4507      * @param {*} [thisArg] The `this` binding of `func`.
4508      * @param {Array} [partials] The arguments to be partially applied.
4509      * @param {Array} [holders] The `partials` placeholder indexes.
4510      * @param {Array} [argPos] The argument positions of the new function.
4511      * @param {number} [ary] The arity cap of `func`.
4512      * @param {number} [arity] The arity of `func`.
4513      * @returns {Function} Returns the new wrapped function.
4514      */
4515     function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
4516       var isBindKey = bitmask & BIND_KEY_FLAG;
4517       if (!isBindKey && typeof func != 'function') {
4518         throw new TypeError(FUNC_ERROR_TEXT);
4519       }
4520       var length = partials ? partials.length : 0;
4521       if (!length) {
4522         bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
4523         partials = holders = undefined;
4524       }
4525       ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
4526       arity = arity === undefined ? arity : toInteger(arity);
4527       length -= holders ? holders.length : 0;
4528
4529       if (bitmask & PARTIAL_RIGHT_FLAG) {
4530         var partialsRight = partials,
4531             holdersRight = holders;
4532
4533         partials = holders = undefined;
4534       }
4535       var data = isBindKey ? undefined : getData(func),
4536           newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
4537
4538       if (data) {
4539         mergeData(newData, data);
4540       }
4541       func = newData[0];
4542       bitmask = newData[1];
4543       thisArg = newData[2];
4544       partials = newData[3];
4545       holders = newData[4];
4546       arity = newData[9] = newData[9] == null
4547         ? (isBindKey ? 0 : func.length)
4548         : nativeMax(newData[9] - length, 0);
4549
4550       if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
4551         bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
4552       }
4553       if (!bitmask || bitmask == BIND_FLAG) {
4554         var result = createBaseWrapper(func, bitmask, thisArg);
4555       } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
4556         result = createCurryWrapper(func, bitmask, arity);
4557       } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
4558         result = createPartialWrapper(func, bitmask, thisArg, partials);
4559       } else {
4560         result = createHybridWrapper.apply(undefined, newData);
4561       }
4562       var setter = data ? baseSetData : setData;
4563       return setter(result, newData);
4564     }
4565
4566     /**
4567      * A specialized version of `baseIsEqualDeep` for arrays with support for
4568      * partial deep comparisons.
4569      *
4570      * @private
4571      * @param {Array} array The array to compare.
4572      * @param {Array} other The other array to compare.
4573      * @param {Function} equalFunc The function to determine equivalents of values.
4574      * @param {Function} [customizer] The function to customize comparisons.
4575      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4576      * @param {Object} [stack] Tracks traversed `array` and `other` objects.
4577      * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
4578      */
4579     function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
4580       var index = -1,
4581           isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4582           isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
4583           arrLength = array.length,
4584           othLength = other.length;
4585
4586       if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
4587         return false;
4588       }
4589       // Assume cyclic values are equal.
4590       var stacked = stack.get(array);
4591       if (stacked) {
4592         return stacked == other;
4593       }
4594       var result = true;
4595       stack.set(array, other);
4596
4597       // Ignore non-index properties.
4598       while (++index < arrLength) {
4599         var arrValue = array[index],
4600             othValue = other[index];
4601
4602         if (customizer) {
4603           var compared = isPartial
4604             ? customizer(othValue, arrValue, index, other, array, stack)
4605             : customizer(arrValue, othValue, index, array, other, stack);
4606         }
4607         if (compared !== undefined) {
4608           if (compared) {
4609             continue;
4610           }
4611           result = false;
4612           break;
4613         }
4614         // Recursively compare arrays (susceptible to call stack limits).
4615         if (isUnordered) {
4616           if (!arraySome(other, function(othValue) {
4617                 return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack);
4618               })) {
4619             result = false;
4620             break;
4621           }
4622         } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
4623           result = false;
4624           break;
4625         }
4626       }
4627       stack['delete'](array);
4628       return result;
4629     }
4630
4631     /**
4632      * A specialized version of `baseIsEqualDeep` for comparing objects of
4633      * the same `toStringTag`.
4634      *
4635      * **Note:** This function only supports comparing values with tags of
4636      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
4637      *
4638      * @private
4639      * @param {Object} object The object to compare.
4640      * @param {Object} other The other object to compare.
4641      * @param {string} tag The `toStringTag` of the objects to compare.
4642      * @param {Function} equalFunc The function to determine equivalents of values.
4643      * @param {Function} [customizer] The function to customize comparisons.
4644      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4645      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4646      */
4647     function equalByTag(object, other, tag, equalFunc, customizer, bitmask) {
4648       switch (tag) {
4649         case arrayBufferTag:
4650           if ((object.byteLength != other.byteLength) ||
4651               !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
4652             return false;
4653           }
4654           return true;
4655
4656         case boolTag:
4657         case dateTag:
4658           // Coerce dates and booleans to numbers, dates to milliseconds and booleans
4659           // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
4660           return +object == +other;
4661
4662         case errorTag:
4663           return object.name == other.name && object.message == other.message;
4664
4665         case numberTag:
4666           // Treat `NaN` vs. `NaN` as equal.
4667           return (object != +object) ? other != +other : object == +other;
4668
4669         case regexpTag:
4670         case stringTag:
4671           // Coerce regexes to strings and treat strings primitives and string
4672           // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
4673           return object == (other + '');
4674
4675         case mapTag:
4676           var convert = mapToArray;
4677
4678         case setTag:
4679           var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
4680           convert || (convert = setToArray);
4681
4682           // Recursively compare objects (susceptible to call stack limits).
4683           return (isPartial || object.size == other.size) &&
4684             equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
4685
4686         case symbolTag:
4687           return !!Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
4688       }
4689       return false;
4690     }
4691
4692     /**
4693      * A specialized version of `baseIsEqualDeep` for objects with support for
4694      * partial deep comparisons.
4695      *
4696      * @private
4697      * @param {Object} object The object to compare.
4698      * @param {Object} other The other object to compare.
4699      * @param {Function} equalFunc The function to determine equivalents of values.
4700      * @param {Function} [customizer] The function to customize comparisons.
4701      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4702      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
4703      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4704      */
4705     function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
4706       var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4707           objProps = keys(object),
4708           objLength = objProps.length,
4709           othProps = keys(other),
4710           othLength = othProps.length;
4711
4712       if (objLength != othLength && !isPartial) {
4713         return false;
4714       }
4715       var index = objLength;
4716       while (index--) {
4717         var key = objProps[index];
4718         if (!(isPartial ? key in other : baseHas(other, key))) {
4719           return false;
4720         }
4721       }
4722       // Assume cyclic values are equal.
4723       var stacked = stack.get(object);
4724       if (stacked) {
4725         return stacked == other;
4726       }
4727       var result = true;
4728       stack.set(object, other);
4729
4730       var skipCtor = isPartial;
4731       while (++index < objLength) {
4732         key = objProps[index];
4733         var objValue = object[key],
4734             othValue = other[key];
4735
4736         if (customizer) {
4737           var compared = isPartial
4738             ? customizer(othValue, objValue, key, other, object, stack)
4739             : customizer(objValue, othValue, key, object, other, stack);
4740         }
4741         // Recursively compare objects (susceptible to call stack limits).
4742         if (!(compared === undefined
4743               ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
4744               : compared
4745             )) {
4746           result = false;
4747           break;
4748         }
4749         skipCtor || (skipCtor = key == 'constructor');
4750       }
4751       if (result && !skipCtor) {
4752         var objCtor = object.constructor,
4753             othCtor = other.constructor;
4754
4755         // Non `Object` object instances with different constructors are not equal.
4756         if (objCtor != othCtor &&
4757             ('constructor' in object && 'constructor' in other) &&
4758             !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
4759               typeof othCtor == 'function' && othCtor instanceof othCtor)) {
4760           result = false;
4761         }
4762       }
4763       stack['delete'](object);
4764       return result;
4765     }
4766
4767     /**
4768      * Gets metadata for `func`.
4769      *
4770      * @private
4771      * @param {Function} func The function to query.
4772      * @returns {*} Returns the metadata for `func`.
4773      */
4774     var getData = !metaMap ? noop : function(func) {
4775       return metaMap.get(func);
4776     };
4777
4778     /**
4779      * Gets the name of `func`.
4780      *
4781      * @private
4782      * @param {Function} func The function to query.
4783      * @returns {string} Returns the function name.
4784      */
4785     function getFuncName(func) {
4786       var result = (func.name + ''),
4787           array = realNames[result],
4788           length = hasOwnProperty.call(realNames, result) ? array.length : 0;
4789
4790       while (length--) {
4791         var data = array[length],
4792             otherFunc = data.func;
4793         if (otherFunc == null || otherFunc == func) {
4794           return data.name;
4795         }
4796       }
4797       return result;
4798     }
4799
4800     /**
4801      * Gets the appropriate "iteratee" function. If the `_.iteratee` method is
4802      * customized this function returns the custom method, otherwise it returns
4803      * `baseIteratee`. If arguments are provided the chosen function is invoked
4804      * with them and its result is returned.
4805      *
4806      * @private
4807      * @param {*} [value] The value to convert to an iteratee.
4808      * @param {number} [arity] The arity of the created iteratee.
4809      * @returns {Function} Returns the chosen function or its result.
4810      */
4811     function getIteratee() {
4812       var result = lodash.iteratee || iteratee;
4813       result = result === iteratee ? baseIteratee : result;
4814       return arguments.length ? result(arguments[0], arguments[1]) : result;
4815     }
4816
4817     /**
4818      * Gets the "length" property value of `object`.
4819      *
4820      * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
4821      * that affects Safari on at least iOS 8.1-8.3 ARM64.
4822      *
4823      * @private
4824      * @param {Object} object The object to query.
4825      * @returns {*} Returns the "length" value.
4826      */
4827     var getLength = baseProperty('length');
4828
4829     /**
4830      * Gets the property names, values, and compare flags of `object`.
4831      *
4832      * @private
4833      * @param {Object} object The object to query.
4834      * @returns {Array} Returns the match data of `object`.
4835      */
4836     function getMatchData(object) {
4837       var result = toPairs(object),
4838           length = result.length;
4839
4840       while (length--) {
4841         result[length][2] = isStrictComparable(result[length][1]);
4842       }
4843       return result;
4844     }
4845
4846     /**
4847      * Gets the native function at `key` of `object`.
4848      *
4849      * @private
4850      * @param {Object} object The object to query.
4851      * @param {string} key The key of the method to get.
4852      * @returns {*} Returns the function if it's native, else `undefined`.
4853      */
4854     function getNative(object, key) {
4855       var value = object == null ? undefined : object[key];
4856       return isNative(value) ? value : undefined;
4857     }
4858
4859     /**
4860      * Creates an array of the own symbol properties of `object`.
4861      *
4862      * @private
4863      * @param {Object} object The object to query.
4864      * @returns {Array} Returns the array of symbols.
4865      */
4866     var getSymbols = getOwnPropertySymbols || function() {
4867       return [];
4868     };
4869
4870     /**
4871      * Gets the `toStringTag` of `value`.
4872      *
4873      * @private
4874      * @param {*} value The value to query.
4875      * @returns {string} Returns the `toStringTag`.
4876      */
4877     function getTag(value) {
4878       return objectToString.call(value);
4879     }
4880
4881     // Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps.
4882     if ((Map && getTag(new Map) != mapTag) ||
4883         (Set && getTag(new Set) != setTag) ||
4884         (WeakMap && getTag(new WeakMap) != weakMapTag)) {
4885       getTag = function(value) {
4886         var result = objectToString.call(value),
4887             Ctor = result == objectTag ? value.constructor : null,
4888             ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : '';
4889
4890         if (ctorString) {
4891           switch (ctorString) {
4892             case mapCtorString: return mapTag;
4893             case setCtorString: return setTag;
4894             case weakMapCtorString: return weakMapTag;
4895           }
4896         }
4897         return result;
4898       };
4899     }
4900
4901     /**
4902      * Gets the view, applying any `transforms` to the `start` and `end` positions.
4903      *
4904      * @private
4905      * @param {number} start The start of the view.
4906      * @param {number} end The end of the view.
4907      * @param {Array} transforms The transformations to apply to the view.
4908      * @returns {Object} Returns an object containing the `start` and `end`
4909      *  positions of the view.
4910      */
4911     function getView(start, end, transforms) {
4912       var index = -1,
4913           length = transforms.length;
4914
4915       while (++index < length) {
4916         var data = transforms[index],
4917             size = data.size;
4918
4919         switch (data.type) {
4920           case 'drop':      start += size; break;
4921           case 'dropRight': end -= size; break;
4922           case 'take':      end = nativeMin(end, start + size); break;
4923           case 'takeRight': start = nativeMax(start, end - size); break;
4924         }
4925       }
4926       return { 'start': start, 'end': end };
4927     }
4928
4929     /**
4930      * Checks if `path` exists on `object`.
4931      *
4932      * @private
4933      * @param {Object} object The object to query.
4934      * @param {Array|string} path The path to check.
4935      * @param {Function} hasFunc The function to check properties.
4936      * @returns {boolean} Returns `true` if `path` exists, else `false`.
4937      */
4938     function hasPath(object, path, hasFunc) {
4939       if (object == null) {
4940         return false;
4941       }
4942       var result = hasFunc(object, path);
4943       if (!result && !isKey(path)) {
4944         path = baseToPath(path);
4945         object = parent(object, path);
4946         if (object != null) {
4947           path = last(path);
4948           result = hasFunc(object, path);
4949         }
4950       }
4951       var length = object ? object.length : undefined;
4952       return result || (
4953         !!length && isLength(length) && isIndex(path, length) &&
4954         (isArray(object) || isString(object) || isArguments(object))
4955       );
4956     }
4957
4958     /**
4959      * Initializes an array clone.
4960      *
4961      * @private
4962      * @param {Array} array The array to clone.
4963      * @returns {Array} Returns the initialized clone.
4964      */
4965     function initCloneArray(array) {
4966       var length = array.length,
4967           result = array.constructor(length);
4968
4969       // Add properties assigned by `RegExp#exec`.
4970       if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
4971         result.index = array.index;
4972         result.input = array.input;
4973       }
4974       return result;
4975     }
4976
4977     /**
4978      * Initializes an object clone.
4979      *
4980      * @private
4981      * @param {Object} object The object to clone.
4982      * @returns {Object} Returns the initialized clone.
4983      */
4984     function initCloneObject(object) {
4985       if (isPrototype(object)) {
4986         return {};
4987       }
4988       var Ctor = object.constructor;
4989       return baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
4990     }
4991
4992     /**
4993      * Initializes an object clone based on its `toStringTag`.
4994      *
4995      * **Note:** This function only supports cloning values with tags of
4996      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
4997      *
4998      * @private
4999      * @param {Object} object The object to clone.
5000      * @param {string} tag The `toStringTag` of the object to clone.
5001      * @param {boolean} [isDeep] Specify a deep clone.
5002      * @returns {Object} Returns the initialized clone.
5003      */
5004     function initCloneByTag(object, tag, isDeep) {
5005       var Ctor = object.constructor;
5006       switch (tag) {
5007         case arrayBufferTag:
5008           return cloneArrayBuffer(object);
5009
5010         case boolTag:
5011         case dateTag:
5012           return new Ctor(+object);
5013
5014         case float32Tag: case float64Tag:
5015         case int8Tag: case int16Tag: case int32Tag:
5016         case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
5017           return cloneTypedArray(object, isDeep);
5018
5019         case mapTag:
5020           return cloneMap(object);
5021
5022         case numberTag:
5023         case stringTag:
5024           return new Ctor(object);
5025
5026         case regexpTag:
5027           return cloneRegExp(object);
5028
5029         case setTag:
5030           return cloneSet(object);
5031
5032         case symbolTag:
5033           return cloneSymbol(object);
5034       }
5035     }
5036
5037     /**
5038      * Creates an array of index keys for `object` values of arrays,
5039      * `arguments` objects, and strings, otherwise `null` is returned.
5040      *
5041      * @private
5042      * @param {Object} object The object to query.
5043      * @returns {Array|null} Returns index keys, else `null`.
5044      */
5045     function indexKeys(object) {
5046       var length = object ? object.length : undefined;
5047       if (isLength(length) &&
5048           (isArray(object) || isString(object) || isArguments(object))) {
5049         return baseTimes(length, String);
5050       }
5051       return null;
5052     }
5053
5054     /**
5055      * Checks if the given arguments are from an iteratee call.
5056      *
5057      * @private
5058      * @param {*} value The potential iteratee value argument.
5059      * @param {*} index The potential iteratee index or key argument.
5060      * @param {*} object The potential iteratee object argument.
5061      * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
5062      */
5063     function isIterateeCall(value, index, object) {
5064       if (!isObject(object)) {
5065         return false;
5066       }
5067       var type = typeof index;
5068       if (type == 'number'
5069           ? (isArrayLike(object) && isIndex(index, object.length))
5070           : (type == 'string' && index in object)) {
5071         return eq(object[index], value);
5072       }
5073       return false;
5074     }
5075
5076     /**
5077      * Checks if `value` is a property name and not a property path.
5078      *
5079      * @private
5080      * @param {*} value The value to check.
5081      * @param {Object} [object] The object to query keys on.
5082      * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
5083      */
5084     function isKey(value, object) {
5085       if (typeof value == 'number') {
5086         return true;
5087       }
5088       return !isArray(value) &&
5089         (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
5090           (object != null && value in Object(object)));
5091     }
5092
5093     /**
5094      * Checks if `value` is suitable for use as unique object key.
5095      *
5096      * @private
5097      * @param {*} value The value to check.
5098      * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
5099      */
5100     function isKeyable(value) {
5101       var type = typeof value;
5102       return type == 'number' || type == 'boolean' ||
5103         (type == 'string' && value !== '__proto__') || value == null;
5104     }
5105
5106     /**
5107      * Checks if `func` has a lazy counterpart.
5108      *
5109      * @private
5110      * @param {Function} func The function to check.
5111      * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
5112      */
5113     function isLaziable(func) {
5114       var funcName = getFuncName(func),
5115           other = lodash[funcName];
5116
5117       if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
5118         return false;
5119       }
5120       if (func === other) {
5121         return true;
5122       }
5123       var data = getData(other);
5124       return !!data && func === data[0];
5125     }
5126
5127     /**
5128      * Checks if `value` is likely a prototype object.
5129      *
5130      * @private
5131      * @param {*} value The value to check.
5132      * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
5133      */
5134     function isPrototype(value) {
5135       var Ctor = value && value.constructor,
5136           proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
5137
5138       return value === proto;
5139     }
5140
5141     /**
5142      * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
5143      *
5144      * @private
5145      * @param {*} value The value to check.
5146      * @returns {boolean} Returns `true` if `value` if suitable for strict
5147      *  equality comparisons, else `false`.
5148      */
5149     function isStrictComparable(value) {
5150       return value === value && !isObject(value);
5151     }
5152
5153     /**
5154      * Merges the function metadata of `source` into `data`.
5155      *
5156      * Merging metadata reduces the number of wrappers used to invoke a function.
5157      * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
5158      * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
5159      * modify function arguments, making the order in which they are executed important,
5160      * preventing the merging of metadata. However, we make an exception for a safe
5161      * combined case where curried functions have `_.ary` and or `_.rearg` applied.
5162      *
5163      * @private
5164      * @param {Array} data The destination metadata.
5165      * @param {Array} source The source metadata.
5166      * @returns {Array} Returns `data`.
5167      */
5168     function mergeData(data, source) {
5169       var bitmask = data[1],
5170           srcBitmask = source[1],
5171           newBitmask = bitmask | srcBitmask,
5172           isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
5173
5174       var isCombo =
5175         (srcBitmask == ARY_FLAG && (bitmask == CURRY_FLAG)) ||
5176         (srcBitmask == ARY_FLAG && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
5177         (srcBitmask == (ARY_FLAG | REARG_FLAG) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
5178
5179       // Exit early if metadata can't be merged.
5180       if (!(isCommon || isCombo)) {
5181         return data;
5182       }
5183       // Use source `thisArg` if available.
5184       if (srcBitmask & BIND_FLAG) {
5185         data[2] = source[2];
5186         // Set when currying a bound function.
5187         newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
5188       }
5189       // Compose partial arguments.
5190       var value = source[3];
5191       if (value) {
5192         var partials = data[3];
5193         data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value);
5194         data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]);
5195       }
5196       // Compose partial right arguments.
5197       value = source[5];
5198       if (value) {
5199         partials = data[5];
5200         data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value);
5201         data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]);
5202       }
5203       // Use source `argPos` if available.
5204       value = source[7];
5205       if (value) {
5206         data[7] = copyArray(value);
5207       }
5208       // Use source `ary` if it's smaller.
5209       if (srcBitmask & ARY_FLAG) {
5210         data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
5211       }
5212       // Use source `arity` if one is not provided.
5213       if (data[9] == null) {
5214         data[9] = source[9];
5215       }
5216       // Use source `func` and merge bitmasks.
5217       data[0] = source[0];
5218       data[1] = newBitmask;
5219
5220       return data;
5221     }
5222
5223     /**
5224      * Used by `_.defaultsDeep` to customize its `_.merge` use.
5225      *
5226      * @private
5227      * @param {*} objValue The destination value.
5228      * @param {*} srcValue The source value.
5229      * @param {string} key The key of the property to merge.
5230      * @param {Object} object The parent object of `objValue`.
5231      * @param {Object} source The parent object of `srcValue`.
5232      * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
5233      * @returns {*} Returns the value to assign.
5234      */
5235     function mergeDefaults(objValue, srcValue, key, object, source, stack) {
5236       if (isObject(objValue) && isObject(srcValue)) {
5237         stack.set(srcValue, objValue);
5238         baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
5239       }
5240       return objValue;
5241     }
5242
5243     /**
5244      * Gets the parent value at `path` of `object`.
5245      *
5246      * @private
5247      * @param {Object} object The object to query.
5248      * @param {Array} path The path to get the parent value of.
5249      * @returns {*} Returns the parent value.
5250      */
5251     function parent(object, path) {
5252       return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
5253     }
5254
5255     /**
5256      * Reorder `array` according to the specified indexes where the element at
5257      * the first index is assigned as the first element, the element at
5258      * the second index is assigned as the second element, and so on.
5259      *
5260      * @private
5261      * @param {Array} array The array to reorder.
5262      * @param {Array} indexes The arranged array indexes.
5263      * @returns {Array} Returns `array`.
5264      */
5265     function reorder(array, indexes) {
5266       var arrLength = array.length,
5267           length = nativeMin(indexes.length, arrLength),
5268           oldArray = copyArray(array);
5269
5270       while (length--) {
5271         var index = indexes[length];
5272         array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
5273       }
5274       return array;
5275     }
5276
5277     /**
5278      * Sets metadata for `func`.
5279      *
5280      * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
5281      * period of time, it will trip its breaker and transition to an identity function
5282      * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
5283      * for more details.
5284      *
5285      * @private
5286      * @param {Function} func The function to associate metadata with.
5287      * @param {*} data The metadata.
5288      * @returns {Function} Returns `func`.
5289      */
5290     var setData = (function() {
5291       var count = 0,
5292           lastCalled = 0;
5293
5294       return function(key, value) {
5295         var stamp = now(),
5296             remaining = HOT_SPAN - (stamp - lastCalled);
5297
5298         lastCalled = stamp;
5299         if (remaining > 0) {
5300           if (++count >= HOT_COUNT) {
5301             return key;
5302           }
5303         } else {
5304           count = 0;
5305         }
5306         return baseSetData(key, value);
5307       };
5308     }());
5309
5310     /**
5311      * Converts `string` to a property path array.
5312      *
5313      * @private
5314      * @param {string} string The string to convert.
5315      * @returns {Array} Returns the property path array.
5316      */
5317     function stringToPath(string) {
5318       var result = [];
5319       toString(string).replace(rePropName, function(match, number, quote, string) {
5320         result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
5321       });
5322       return result;
5323     }
5324
5325     /**
5326      * Converts `value` to an array-like object if it's not one.
5327      *
5328      * @private
5329      * @param {*} value The value to process.
5330      * @returns {Array} Returns the array-like object.
5331      */
5332     function toArrayLikeObject(value) {
5333       return isArrayLikeObject(value) ? value : [];
5334     }
5335
5336     /**
5337      * Converts `value` to a function if it's not one.
5338      *
5339      * @private
5340      * @param {*} value The value to process.
5341      * @returns {Function} Returns the function.
5342      */
5343     function toFunction(value) {
5344       return typeof value == 'function' ? value : identity;
5345     }
5346
5347     /**
5348      * Creates a clone of `wrapper`.
5349      *
5350      * @private
5351      * @param {Object} wrapper The wrapper to clone.
5352      * @returns {Object} Returns the cloned wrapper.
5353      */
5354     function wrapperClone(wrapper) {
5355       if (wrapper instanceof LazyWrapper) {
5356         return wrapper.clone();
5357       }
5358       var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
5359       result.__actions__ = copyArray(wrapper.__actions__);
5360       result.__index__  = wrapper.__index__;
5361       result.__values__ = wrapper.__values__;
5362       return result;
5363     }
5364
5365     /*------------------------------------------------------------------------*/
5366
5367     /**
5368      * Creates an array of elements split into groups the length of `size`.
5369      * If `array` can't be split evenly, the final chunk will be the remaining
5370      * elements.
5371      *
5372      * @static
5373      * @memberOf _
5374      * @category Array
5375      * @param {Array} array The array to process.
5376      * @param {number} [size=0] The length of each chunk.
5377      * @returns {Array} Returns the new array containing chunks.
5378      * @example
5379      *
5380      * _.chunk(['a', 'b', 'c', 'd'], 2);
5381      * // => [['a', 'b'], ['c', 'd']]
5382      *
5383      * _.chunk(['a', 'b', 'c', 'd'], 3);
5384      * // => [['a', 'b', 'c'], ['d']]
5385      */
5386     function chunk(array, size) {
5387       size = nativeMax(toInteger(size), 0);
5388
5389       var length = array ? array.length : 0;
5390       if (!length || size < 1) {
5391         return [];
5392       }
5393       var index = 0,
5394           resIndex = -1,
5395           result = Array(nativeCeil(length / size));
5396
5397       while (index < length) {
5398         result[++resIndex] = baseSlice(array, index, (index += size));
5399       }
5400       return result;
5401     }
5402
5403     /**
5404      * Creates an array with all falsey values removed. The values `false`, `null`,
5405      * `0`, `""`, `undefined`, and `NaN` are falsey.
5406      *
5407      * @static
5408      * @memberOf _
5409      * @category Array
5410      * @param {Array} array The array to compact.
5411      * @returns {Array} Returns the new array of filtered values.
5412      * @example
5413      *
5414      * _.compact([0, 1, false, 2, '', 3]);
5415      * // => [1, 2, 3]
5416      */
5417     function compact(array) {
5418       var index = -1,
5419           length = array ? array.length : 0,
5420           resIndex = -1,
5421           result = [];
5422
5423       while (++index < length) {
5424         var value = array[index];
5425         if (value) {
5426           result[++resIndex] = value;
5427         }
5428       }
5429       return result;
5430     }
5431
5432     /**
5433      * Creates a new array concatenating `array` with any additional arrays
5434      * and/or values.
5435      *
5436      * @static
5437      * @memberOf _
5438      * @category Array
5439      * @param {Array} array The array to concatenate.
5440      * @param {...*} [values] The values to concatenate.
5441      * @returns {Array} Returns the new concatenated array.
5442      * @example
5443      *
5444      * var array = [1];
5445      * var other = _.concat(array, 2, [3], [[4]]);
5446      *
5447      * console.log(other);
5448      * // => [1, 2, 3, [4]]
5449      *
5450      * console.log(array);
5451      * // => [1]
5452      */
5453     var concat = rest(function(array, values) {
5454       if (!isArray(array)) {
5455         array = array == null ? [] : [Object(array)];
5456       }
5457       values = baseFlatten(values);
5458       return arrayConcat(array, values);
5459     });
5460
5461     /**
5462      * Creates an array of unique `array` values not included in the other
5463      * given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5464      * for equality comparisons.
5465      *
5466      * @static
5467      * @memberOf _
5468      * @category Array
5469      * @param {Array} array The array to inspect.
5470      * @param {...Array} [values] The values to exclude.
5471      * @returns {Array} Returns the new array of filtered values.
5472      * @example
5473      *
5474      * _.difference([3, 2, 1], [4, 2]);
5475      * // => [3, 1]
5476      */
5477     var difference = rest(function(array, values) {
5478       return isArrayLikeObject(array)
5479         ? baseDifference(array, baseFlatten(values, false, true))
5480         : [];
5481     });
5482
5483     /**
5484      * This method is like `_.difference` except that it accepts `iteratee` which
5485      * is invoked for each element of `array` and `values` to generate the criterion
5486      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
5487      *
5488      * @static
5489      * @memberOf _
5490      * @category Array
5491      * @param {Array} array The array to inspect.
5492      * @param {...Array} [values] The values to exclude.
5493      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
5494      * @returns {Array} Returns the new array of filtered values.
5495      * @example
5496      *
5497      * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
5498      * // => [3.1, 1.3]
5499      *
5500      * // The `_.property` iteratee shorthand.
5501      * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
5502      * // => [{ 'x': 2 }]
5503      */
5504     var differenceBy = rest(function(array, values) {
5505       var iteratee = last(values);
5506       if (isArrayLikeObject(iteratee)) {
5507         iteratee = undefined;
5508       }
5509       return isArrayLikeObject(array)
5510         ? baseDifference(array, baseFlatten(values, false, true), getIteratee(iteratee))
5511         : [];
5512     });
5513
5514     /**
5515      * This method is like `_.difference` except that it accepts `comparator`
5516      * which is invoked to compare elements of `array` to `values`. The comparator
5517      * is invoked with two arguments: (arrVal, othVal).
5518      *
5519      * @static
5520      * @memberOf _
5521      * @category Array
5522      * @param {Array} array The array to inspect.
5523      * @param {...Array} [values] The values to exclude.
5524      * @param {Function} [comparator] The comparator invoked per element.
5525      * @returns {Array} Returns the new array of filtered values.
5526      * @example
5527      *
5528      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
5529      *
5530      * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
5531      * // => [{ 'x': 2, 'y': 1 }]
5532      */
5533     var differenceWith = rest(function(array, values) {
5534       var comparator = last(values);
5535       if (isArrayLikeObject(comparator)) {
5536         comparator = undefined;
5537       }
5538       return isArrayLikeObject(array)
5539         ? baseDifference(array, baseFlatten(values, false, true), undefined, comparator)
5540         : [];
5541     });
5542
5543     /**
5544      * Creates a slice of `array` with `n` elements dropped from the beginning.
5545      *
5546      * @static
5547      * @memberOf _
5548      * @category Array
5549      * @param {Array} array The array to query.
5550      * @param {number} [n=1] The number of elements to drop.
5551      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5552      * @returns {Array} Returns the slice of `array`.
5553      * @example
5554      *
5555      * _.drop([1, 2, 3]);
5556      * // => [2, 3]
5557      *
5558      * _.drop([1, 2, 3], 2);
5559      * // => [3]
5560      *
5561      * _.drop([1, 2, 3], 5);
5562      * // => []
5563      *
5564      * _.drop([1, 2, 3], 0);
5565      * // => [1, 2, 3]
5566      */
5567     function drop(array, n, guard) {
5568       var length = array ? array.length : 0;
5569       if (!length) {
5570         return [];
5571       }
5572       n = (guard || n === undefined) ? 1 : toInteger(n);
5573       return baseSlice(array, n < 0 ? 0 : n, length);
5574     }
5575
5576     /**
5577      * Creates a slice of `array` with `n` elements dropped from the end.
5578      *
5579      * @static
5580      * @memberOf _
5581      * @category Array
5582      * @param {Array} array The array to query.
5583      * @param {number} [n=1] The number of elements to drop.
5584      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5585      * @returns {Array} Returns the slice of `array`.
5586      * @example
5587      *
5588      * _.dropRight([1, 2, 3]);
5589      * // => [1, 2]
5590      *
5591      * _.dropRight([1, 2, 3], 2);
5592      * // => [1]
5593      *
5594      * _.dropRight([1, 2, 3], 5);
5595      * // => []
5596      *
5597      * _.dropRight([1, 2, 3], 0);
5598      * // => [1, 2, 3]
5599      */
5600     function dropRight(array, n, guard) {
5601       var length = array ? array.length : 0;
5602       if (!length) {
5603         return [];
5604       }
5605       n = (guard || n === undefined) ? 1 : toInteger(n);
5606       n = length - n;
5607       return baseSlice(array, 0, n < 0 ? 0 : n);
5608     }
5609
5610     /**
5611      * Creates a slice of `array` excluding elements dropped from the end.
5612      * Elements are dropped until `predicate` returns falsey. The predicate is
5613      * invoked with three arguments: (value, index, array).
5614      *
5615      * @static
5616      * @memberOf _
5617      * @category Array
5618      * @param {Array} array The array to query.
5619      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5620      * @returns {Array} Returns the slice of `array`.
5621      * @example
5622      *
5623      * var users = [
5624      *   { 'user': 'barney',  'active': true },
5625      *   { 'user': 'fred',    'active': false },
5626      *   { 'user': 'pebbles', 'active': false }
5627      * ];
5628      *
5629      * _.dropRightWhile(users, function(o) { return !o.active; });
5630      * // => objects for ['barney']
5631      *
5632      * // The `_.matches` iteratee shorthand.
5633      * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
5634      * // => objects for ['barney', 'fred']
5635      *
5636      * // The `_.matchesProperty` iteratee shorthand.
5637      * _.dropRightWhile(users, ['active', false]);
5638      * // => objects for ['barney']
5639      *
5640      * // The `_.property` iteratee shorthand.
5641      * _.dropRightWhile(users, 'active');
5642      * // => objects for ['barney', 'fred', 'pebbles']
5643      */
5644     function dropRightWhile(array, predicate) {
5645       return (array && array.length)
5646         ? baseWhile(array, getIteratee(predicate, 3), true, true)
5647         : [];
5648     }
5649
5650     /**
5651      * Creates a slice of `array` excluding elements dropped from the beginning.
5652      * Elements are dropped until `predicate` returns falsey. The predicate is
5653      * invoked with three arguments: (value, index, array).
5654      *
5655      * @static
5656      * @memberOf _
5657      * @category Array
5658      * @param {Array} array The array to query.
5659      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5660      * @returns {Array} Returns the slice of `array`.
5661      * @example
5662      *
5663      * var users = [
5664      *   { 'user': 'barney',  'active': false },
5665      *   { 'user': 'fred',    'active': false },
5666      *   { 'user': 'pebbles', 'active': true }
5667      * ];
5668      *
5669      * _.dropWhile(users, function(o) { return !o.active; });
5670      * // => objects for ['pebbles']
5671      *
5672      * // The `_.matches` iteratee shorthand.
5673      * _.dropWhile(users, { 'user': 'barney', 'active': false });
5674      * // => objects for ['fred', 'pebbles']
5675      *
5676      * // The `_.matchesProperty` iteratee shorthand.
5677      * _.dropWhile(users, ['active', false]);
5678      * // => objects for ['pebbles']
5679      *
5680      * // The `_.property` iteratee shorthand.
5681      * _.dropWhile(users, 'active');
5682      * // => objects for ['barney', 'fred', 'pebbles']
5683      */
5684     function dropWhile(array, predicate) {
5685       return (array && array.length)
5686         ? baseWhile(array, getIteratee(predicate, 3), true)
5687         : [];
5688     }
5689
5690     /**
5691      * Fills elements of `array` with `value` from `start` up to, but not
5692      * including, `end`.
5693      *
5694      * **Note:** This method mutates `array`.
5695      *
5696      * @static
5697      * @memberOf _
5698      * @category Array
5699      * @param {Array} array The array to fill.
5700      * @param {*} value The value to fill `array` with.
5701      * @param {number} [start=0] The start position.
5702      * @param {number} [end=array.length] The end position.
5703      * @returns {Array} Returns `array`.
5704      * @example
5705      *
5706      * var array = [1, 2, 3];
5707      *
5708      * _.fill(array, 'a');
5709      * console.log(array);
5710      * // => ['a', 'a', 'a']
5711      *
5712      * _.fill(Array(3), 2);
5713      * // => [2, 2, 2]
5714      *
5715      * _.fill([4, 6, 8, 10], '*', 1, 3);
5716      * // => [4, '*', '*', 10]
5717      */
5718     function fill(array, value, start, end) {
5719       var length = array ? array.length : 0;
5720       if (!length) {
5721         return [];
5722       }
5723       if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
5724         start = 0;
5725         end = length;
5726       }
5727       return baseFill(array, value, start, end);
5728     }
5729
5730     /**
5731      * This method is like `_.find` except that it returns the index of the first
5732      * element `predicate` returns truthy for instead of the element itself.
5733      *
5734      * @static
5735      * @memberOf _
5736      * @category Array
5737      * @param {Array} array The array to search.
5738      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5739      * @returns {number} Returns the index of the found element, else `-1`.
5740      * @example
5741      *
5742      * var users = [
5743      *   { 'user': 'barney',  'active': false },
5744      *   { 'user': 'fred',    'active': false },
5745      *   { 'user': 'pebbles', 'active': true }
5746      * ];
5747      *
5748      * _.findIndex(users, function(o) { return o.user == 'barney'; });
5749      * // => 0
5750      *
5751      * // The `_.matches` iteratee shorthand.
5752      * _.findIndex(users, { 'user': 'fred', 'active': false });
5753      * // => 1
5754      *
5755      * // The `_.matchesProperty` iteratee shorthand.
5756      * _.findIndex(users, ['active', false]);
5757      * // => 0
5758      *
5759      * // The `_.property` iteratee shorthand.
5760      * _.findIndex(users, 'active');
5761      * // => 2
5762      */
5763     function findIndex(array, predicate) {
5764       return (array && array.length)
5765         ? baseFindIndex(array, getIteratee(predicate, 3))
5766         : -1;
5767     }
5768
5769     /**
5770      * This method is like `_.findIndex` except that it iterates over elements
5771      * of `collection` from right to left.
5772      *
5773      * @static
5774      * @memberOf _
5775      * @category Array
5776      * @param {Array} array The array to search.
5777      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5778      * @returns {number} Returns the index of the found element, else `-1`.
5779      * @example
5780      *
5781      * var users = [
5782      *   { 'user': 'barney',  'active': true },
5783      *   { 'user': 'fred',    'active': false },
5784      *   { 'user': 'pebbles', 'active': false }
5785      * ];
5786      *
5787      * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
5788      * // => 2
5789      *
5790      * // The `_.matches` iteratee shorthand.
5791      * _.findLastIndex(users, { 'user': 'barney', 'active': true });
5792      * // => 0
5793      *
5794      * // The `_.matchesProperty` iteratee shorthand.
5795      * _.findLastIndex(users, ['active', false]);
5796      * // => 2
5797      *
5798      * // The `_.property` iteratee shorthand.
5799      * _.findLastIndex(users, 'active');
5800      * // => 0
5801      */
5802     function findLastIndex(array, predicate) {
5803       return (array && array.length)
5804         ? baseFindIndex(array, getIteratee(predicate, 3), true)
5805         : -1;
5806     }
5807
5808     /**
5809      * Flattens `array` a single level.
5810      *
5811      * @static
5812      * @memberOf _
5813      * @category Array
5814      * @param {Array} array The array to flatten.
5815      * @returns {Array} Returns the new flattened array.
5816      * @example
5817      *
5818      * _.flatten([1, [2, 3, [4]]]);
5819      * // => [1, 2, 3, [4]]
5820      */
5821     function flatten(array) {
5822       var length = array ? array.length : 0;
5823       return length ? baseFlatten(array) : [];
5824     }
5825
5826     /**
5827      * This method is like `_.flatten` except that it recursively flattens `array`.
5828      *
5829      * @static
5830      * @memberOf _
5831      * @category Array
5832      * @param {Array} array The array to recursively flatten.
5833      * @returns {Array} Returns the new flattened array.
5834      * @example
5835      *
5836      * _.flattenDeep([1, [2, 3, [4]]]);
5837      * // => [1, 2, 3, 4]
5838      */
5839     function flattenDeep(array) {
5840       var length = array ? array.length : 0;
5841       return length ? baseFlatten(array, true) : [];
5842     }
5843
5844     /**
5845      * The inverse of `_.toPairs`; this method returns an object composed
5846      * from key-value `pairs`.
5847      *
5848      * @static
5849      * @memberOf _
5850      * @category Array
5851      * @param {Array} pairs The key-value pairs.
5852      * @returns {Object} Returns the new object.
5853      * @example
5854      *
5855      * _.fromPairs([['fred', 30], ['barney', 40]]);
5856      * // => { 'fred': 30, 'barney': 40 }
5857      */
5858     function fromPairs(pairs) {
5859       var index = -1,
5860           length = pairs ? pairs.length : 0,
5861           result = {};
5862
5863       while (++index < length) {
5864         var pair = pairs[index];
5865         result[pair[0]] = pair[1];
5866       }
5867       return result;
5868     }
5869
5870     /**
5871      * Gets the first element of `array`.
5872      *
5873      * @static
5874      * @memberOf _
5875      * @alias first
5876      * @category Array
5877      * @param {Array} array The array to query.
5878      * @returns {*} Returns the first element of `array`.
5879      * @example
5880      *
5881      * _.head([1, 2, 3]);
5882      * // => 1
5883      *
5884      * _.head([]);
5885      * // => undefined
5886      */
5887     function head(array) {
5888       return array ? array[0] : undefined;
5889     }
5890
5891     /**
5892      * Gets the index at which the first occurrence of `value` is found in `array`
5893      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5894      * for equality comparisons. If `fromIndex` is negative, it's used as the offset
5895      * from the end of `array`.
5896      *
5897      * @static
5898      * @memberOf _
5899      * @category Array
5900      * @param {Array} array The array to search.
5901      * @param {*} value The value to search for.
5902      * @param {number} [fromIndex=0] The index to search from.
5903      * @returns {number} Returns the index of the matched value, else `-1`.
5904      * @example
5905      *
5906      * _.indexOf([1, 2, 1, 2], 2);
5907      * // => 1
5908      *
5909      * // Search from the `fromIndex`.
5910      * _.indexOf([1, 2, 1, 2], 2, 2);
5911      * // => 3
5912      */
5913     function indexOf(array, value, fromIndex) {
5914       var length = array ? array.length : 0;
5915       if (!length) {
5916         return -1;
5917       }
5918       fromIndex = toInteger(fromIndex);
5919       if (fromIndex < 0) {
5920         fromIndex = nativeMax(length + fromIndex, 0);
5921       }
5922       return baseIndexOf(array, value, fromIndex);
5923     }
5924
5925     /**
5926      * Gets all but the last element of `array`.
5927      *
5928      * @static
5929      * @memberOf _
5930      * @category Array
5931      * @param {Array} array The array to query.
5932      * @returns {Array} Returns the slice of `array`.
5933      * @example
5934      *
5935      * _.initial([1, 2, 3]);
5936      * // => [1, 2]
5937      */
5938     function initial(array) {
5939       return dropRight(array, 1);
5940     }
5941
5942     /**
5943      * Creates an array of unique values that are included in all given arrays
5944      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5945      * for equality comparisons.
5946      *
5947      * @static
5948      * @memberOf _
5949      * @category Array
5950      * @param {...Array} [arrays] The arrays to inspect.
5951      * @returns {Array} Returns the new array of shared values.
5952      * @example
5953      *
5954      * _.intersection([2, 1], [4, 2], [1, 2]);
5955      * // => [2]
5956      */
5957     var intersection = rest(function(arrays) {
5958       var mapped = arrayMap(arrays, toArrayLikeObject);
5959       return (mapped.length && mapped[0] === arrays[0])
5960         ? baseIntersection(mapped)
5961         : [];
5962     });
5963
5964     /**
5965      * This method is like `_.intersection` except that it accepts `iteratee`
5966      * which is invoked for each element of each `arrays` to generate the criterion
5967      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
5968      *
5969      * @static
5970      * @memberOf _
5971      * @category Array
5972      * @param {...Array} [arrays] The arrays to inspect.
5973      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
5974      * @returns {Array} Returns the new array of shared values.
5975      * @example
5976      *
5977      * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
5978      * // => [2.1]
5979      *
5980      * // The `_.property` iteratee shorthand.
5981      * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
5982      * // => [{ 'x': 1 }]
5983      */
5984     var intersectionBy = rest(function(arrays) {
5985       var iteratee = last(arrays),
5986           mapped = arrayMap(arrays, toArrayLikeObject);
5987
5988       if (iteratee === last(mapped)) {
5989         iteratee = undefined;
5990       } else {
5991         mapped.pop();
5992       }
5993       return (mapped.length && mapped[0] === arrays[0])
5994         ? baseIntersection(mapped, getIteratee(iteratee))
5995         : [];
5996     });
5997
5998     /**
5999      * This method is like `_.intersection` except that it accepts `comparator`
6000      * which is invoked to compare elements of `arrays`. The comparator is invoked
6001      * with two arguments: (arrVal, othVal).
6002      *
6003      * @static
6004      * @memberOf _
6005      * @category Array
6006      * @param {...Array} [arrays] The arrays to inspect.
6007      * @param {Function} [comparator] The comparator invoked per element.
6008      * @returns {Array} Returns the new array of shared values.
6009      * @example
6010      *
6011      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6012      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6013      *
6014      * _.intersectionWith(objects, others, _.isEqual);
6015      * // => [{ 'x': 1, 'y': 2 }]
6016      */
6017     var intersectionWith = rest(function(arrays) {
6018       var comparator = last(arrays),
6019           mapped = arrayMap(arrays, toArrayLikeObject);
6020
6021       if (comparator === last(mapped)) {
6022         comparator = undefined;
6023       } else {
6024         mapped.pop();
6025       }
6026       return (mapped.length && mapped[0] === arrays[0])
6027         ? baseIntersection(mapped, undefined, comparator)
6028         : [];
6029     });
6030
6031     /**
6032      * Converts all elements in `array` into a string separated by `separator`.
6033      *
6034      * @static
6035      * @memberOf _
6036      * @category Array
6037      * @param {Array} array The array to convert.
6038      * @param {string} [separator=','] The element separator.
6039      * @returns {string} Returns the joined string.
6040      * @example
6041      *
6042      * _.join(['a', 'b', 'c'], '~');
6043      * // => 'a~b~c'
6044      */
6045     function join(array, separator) {
6046       return array ? nativeJoin.call(array, separator) : '';
6047     }
6048
6049     /**
6050      * Gets the last element of `array`.
6051      *
6052      * @static
6053      * @memberOf _
6054      * @category Array
6055      * @param {Array} array The array to query.
6056      * @returns {*} Returns the last element of `array`.
6057      * @example
6058      *
6059      * _.last([1, 2, 3]);
6060      * // => 3
6061      */
6062     function last(array) {
6063       var length = array ? array.length : 0;
6064       return length ? array[length - 1] : undefined;
6065     }
6066
6067     /**
6068      * This method is like `_.indexOf` except that it iterates over elements of
6069      * `array` from right to left.
6070      *
6071      * @static
6072      * @memberOf _
6073      * @category Array
6074      * @param {Array} array The array to search.
6075      * @param {*} value The value to search for.
6076      * @param {number} [fromIndex=array.length-1] The index to search from.
6077      * @returns {number} Returns the index of the matched value, else `-1`.
6078      * @example
6079      *
6080      * _.lastIndexOf([1, 2, 1, 2], 2);
6081      * // => 3
6082      *
6083      * // Search from the `fromIndex`.
6084      * _.lastIndexOf([1, 2, 1, 2], 2, 2);
6085      * // => 1
6086      */
6087     function lastIndexOf(array, value, fromIndex) {
6088       var length = array ? array.length : 0;
6089       if (!length) {
6090         return -1;
6091       }
6092       var index = length;
6093       if (fromIndex !== undefined) {
6094         index = toInteger(fromIndex);
6095         index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1;
6096       }
6097       if (value !== value) {
6098         return indexOfNaN(array, index, true);
6099       }
6100       while (index--) {
6101         if (array[index] === value) {
6102           return index;
6103         }
6104       }
6105       return -1;
6106     }
6107
6108     /**
6109      * Removes all given values from `array` using
6110      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6111      * for equality comparisons.
6112      *
6113      * **Note:** Unlike `_.without`, this method mutates `array`.
6114      *
6115      * @static
6116      * @memberOf _
6117      * @category Array
6118      * @param {Array} array The array to modify.
6119      * @param {...*} [values] The values to remove.
6120      * @returns {Array} Returns `array`.
6121      * @example
6122      *
6123      * var array = [1, 2, 3, 1, 2, 3];
6124      *
6125      * _.pull(array, 2, 3);
6126      * console.log(array);
6127      * // => [1, 1]
6128      */
6129     var pull = rest(pullAll);
6130
6131     /**
6132      * This method is like `_.pull` except that it accepts an array of values to remove.
6133      *
6134      * **Note:** Unlike `_.difference`, this method mutates `array`.
6135      *
6136      * @static
6137      * @memberOf _
6138      * @category Array
6139      * @param {Array} array The array to modify.
6140      * @param {Array} values The values to remove.
6141      * @returns {Array} Returns `array`.
6142      * @example
6143      *
6144      * var array = [1, 2, 3, 1, 2, 3];
6145      *
6146      * _.pullAll(array, [2, 3]);
6147      * console.log(array);
6148      * // => [1, 1]
6149      */
6150     function pullAll(array, values) {
6151       return (array && array.length && values && values.length)
6152         ? basePullAll(array, values)
6153         : array;
6154     }
6155
6156     /**
6157      * This method is like `_.pullAll` except that it accepts `iteratee` which is
6158      * invoked for each element of `array` and `values` to generate the criterion
6159      * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
6160      *
6161      * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
6162      *
6163      * @static
6164      * @memberOf _
6165      * @category Array
6166      * @param {Array} array The array to modify.
6167      * @param {Array} values The values to remove.
6168      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6169      * @returns {Array} Returns `array`.
6170      * @example
6171      *
6172      * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
6173      *
6174      * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
6175      * console.log(array);
6176      * // => [{ 'x': 2 }]
6177      */
6178     function pullAllBy(array, values, iteratee) {
6179       return (array && array.length && values && values.length)
6180         ? basePullAllBy(array, values, getIteratee(iteratee))
6181         : array;
6182     }
6183
6184     /**
6185      * Removes elements from `array` corresponding to `indexes` and returns an
6186      * array of removed elements.
6187      *
6188      * **Note:** Unlike `_.at`, this method mutates `array`.
6189      *
6190      * @static
6191      * @memberOf _
6192      * @category Array
6193      * @param {Array} array The array to modify.
6194      * @param {...(number|number[])} [indexes] The indexes of elements to remove,
6195      *  specified individually or in arrays.
6196      * @returns {Array} Returns the new array of removed elements.
6197      * @example
6198      *
6199      * var array = [5, 10, 15, 20];
6200      * var evens = _.pullAt(array, 1, 3);
6201      *
6202      * console.log(array);
6203      * // => [5, 15]
6204      *
6205      * console.log(evens);
6206      * // => [10, 20]
6207      */
6208     var pullAt = rest(function(array, indexes) {
6209       indexes = arrayMap(baseFlatten(indexes), String);
6210
6211       var result = baseAt(array, indexes);
6212       basePullAt(array, indexes.sort(compareAscending));
6213       return result;
6214     });
6215
6216     /**
6217      * Removes all elements from `array` that `predicate` returns truthy for
6218      * and returns an array of the removed elements. The predicate is invoked with
6219      * three arguments: (value, index, array).
6220      *
6221      * **Note:** Unlike `_.filter`, this method mutates `array`.
6222      *
6223      * @static
6224      * @memberOf _
6225      * @category Array
6226      * @param {Array} array The array to modify.
6227      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6228      * @returns {Array} Returns the new array of removed elements.
6229      * @example
6230      *
6231      * var array = [1, 2, 3, 4];
6232      * var evens = _.remove(array, function(n) {
6233      *   return n % 2 == 0;
6234      * });
6235      *
6236      * console.log(array);
6237      * // => [1, 3]
6238      *
6239      * console.log(evens);
6240      * // => [2, 4]
6241      */
6242     function remove(array, predicate) {
6243       var result = [];
6244       if (!(array && array.length)) {
6245         return result;
6246       }
6247       var index = -1,
6248           indexes = [],
6249           length = array.length;
6250
6251       predicate = getIteratee(predicate, 3);
6252       while (++index < length) {
6253         var value = array[index];
6254         if (predicate(value, index, array)) {
6255           result.push(value);
6256           indexes.push(index);
6257         }
6258       }
6259       basePullAt(array, indexes);
6260       return result;
6261     }
6262
6263     /**
6264      * Reverses `array` so that the first element becomes the last, the second
6265      * element becomes the second to last, and so on.
6266      *
6267      * **Note:** This method mutates `array` and is based on
6268      * [`Array#reverse`](https://mdn.io/Array/reverse).
6269      *
6270      * @static
6271      * @memberOf _
6272      * @category Array
6273      * @returns {Array} Returns `array`.
6274      * @example
6275      *
6276      * var array = [1, 2, 3];
6277      *
6278      * _.reverse(array);
6279      * // => [3, 2, 1]
6280      *
6281      * console.log(array);
6282      * // => [3, 2, 1]
6283      */
6284     function reverse(array) {
6285       return array ? nativeReverse.call(array) : array;
6286     }
6287
6288     /**
6289      * Creates a slice of `array` from `start` up to, but not including, `end`.
6290      *
6291      * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice)
6292      * to ensure dense arrays are returned.
6293      *
6294      * @static
6295      * @memberOf _
6296      * @category Array
6297      * @param {Array} array The array to slice.
6298      * @param {number} [start=0] The start position.
6299      * @param {number} [end=array.length] The end position.
6300      * @returns {Array} Returns the slice of `array`.
6301      */
6302     function slice(array, start, end) {
6303       var length = array ? array.length : 0;
6304       if (!length) {
6305         return [];
6306       }
6307       if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
6308         start = 0;
6309         end = length;
6310       }
6311       else {
6312         start = start == null ? 0 : toInteger(start);
6313         end = end === undefined ? length : toInteger(end);
6314       }
6315       return baseSlice(array, start, end);
6316     }
6317
6318     /**
6319      * Uses a binary search to determine the lowest index at which `value` should
6320      * be inserted into `array` in order to maintain its sort order.
6321      *
6322      * @static
6323      * @memberOf _
6324      * @category Array
6325      * @param {Array} array The sorted array to inspect.
6326      * @param {*} value The value to evaluate.
6327      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6328      * @example
6329      *
6330      * _.sortedIndex([30, 50], 40);
6331      * // => 1
6332      *
6333      * _.sortedIndex([4, 5], 4);
6334      * // => 0
6335      */
6336     function sortedIndex(array, value) {
6337       return baseSortedIndex(array, value);
6338     }
6339
6340     /**
6341      * This method is like `_.sortedIndex` except that it accepts `iteratee`
6342      * which is invoked for `value` and each element of `array` to compute their
6343      * sort ranking. The iteratee is invoked with one argument: (value).
6344      *
6345      * @static
6346      * @memberOf _
6347      * @category Array
6348      * @param {Array} array The sorted array to inspect.
6349      * @param {*} value The value to evaluate.
6350      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6351      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6352      * @example
6353      *
6354      * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
6355      *
6356      * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
6357      * // => 1
6358      *
6359      * // The `_.property` iteratee shorthand.
6360      * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6361      * // => 0
6362      */
6363     function sortedIndexBy(array, value, iteratee) {
6364       return baseSortedIndexBy(array, value, getIteratee(iteratee));
6365     }
6366
6367     /**
6368      * This method is like `_.indexOf` except that it performs a binary
6369      * search on a sorted `array`.
6370      *
6371      * @static
6372      * @memberOf _
6373      * @category Array
6374      * @param {Array} array The array to search.
6375      * @param {*} value The value to search for.
6376      * @returns {number} Returns the index of the matched value, else `-1`.
6377      * @example
6378      *
6379      * _.sortedIndexOf([1, 1, 2, 2], 2);
6380      * // => 2
6381      */
6382     function sortedIndexOf(array, value) {
6383       var length = array ? array.length : 0;
6384       if (length) {
6385         var index = baseSortedIndex(array, value);
6386         if (index < length && eq(array[index], value)) {
6387           return index;
6388         }
6389       }
6390       return -1;
6391     }
6392
6393     /**
6394      * This method is like `_.sortedIndex` except that it returns the highest
6395      * index at which `value` should be inserted into `array` in order to
6396      * maintain its sort order.
6397      *
6398      * @static
6399      * @memberOf _
6400      * @category Array
6401      * @param {Array} array The sorted array to inspect.
6402      * @param {*} value The value to evaluate.
6403      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6404      * @example
6405      *
6406      * _.sortedLastIndex([4, 5], 4);
6407      * // => 1
6408      */
6409     function sortedLastIndex(array, value) {
6410       return baseSortedIndex(array, value, true);
6411     }
6412
6413     /**
6414      * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
6415      * which is invoked for `value` and each element of `array` to compute their
6416      * sort ranking. The iteratee is invoked with one argument: (value).
6417      *
6418      * @static
6419      * @memberOf _
6420      * @category Array
6421      * @param {Array} array The sorted array to inspect.
6422      * @param {*} value The value to evaluate.
6423      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6424      * @returns {number} Returns the index at which `value` should be inserted into `array`.
6425      * @example
6426      *
6427      * // The `_.property` iteratee shorthand.
6428      * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6429      * // => 1
6430      */
6431     function sortedLastIndexBy(array, value, iteratee) {
6432       return baseSortedIndexBy(array, value, getIteratee(iteratee), true);
6433     }
6434
6435     /**
6436      * This method is like `_.lastIndexOf` except that it performs a binary
6437      * search on a sorted `array`.
6438      *
6439      * @static
6440      * @memberOf _
6441      * @category Array
6442      * @param {Array} array The array to search.
6443      * @param {*} value The value to search for.
6444      * @returns {number} Returns the index of the matched value, else `-1`.
6445      * @example
6446      *
6447      * _.sortedLastIndexOf([1, 1, 2, 2], 2);
6448      * // => 3
6449      */
6450     function sortedLastIndexOf(array, value) {
6451       var length = array ? array.length : 0;
6452       if (length) {
6453         var index = baseSortedIndex(array, value, true) - 1;
6454         if (eq(array[index], value)) {
6455           return index;
6456         }
6457       }
6458       return -1;
6459     }
6460
6461     /**
6462      * This method is like `_.uniq` except that it's designed and optimized
6463      * for sorted arrays.
6464      *
6465      * @static
6466      * @memberOf _
6467      * @category Array
6468      * @param {Array} array The array to inspect.
6469      * @returns {Array} Returns the new duplicate free array.
6470      * @example
6471      *
6472      * _.sortedUniq([1, 1, 2]);
6473      * // => [1, 2]
6474      */
6475     function sortedUniq(array) {
6476       return (array && array.length)
6477         ? baseSortedUniq(array)
6478         : [];
6479     }
6480
6481     /**
6482      * This method is like `_.uniqBy` except that it's designed and optimized
6483      * for sorted arrays.
6484      *
6485      * @static
6486      * @memberOf _
6487      * @category Array
6488      * @param {Array} array The array to inspect.
6489      * @param {Function} [iteratee] The iteratee invoked per element.
6490      * @returns {Array} Returns the new duplicate free array.
6491      * @example
6492      *
6493      * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
6494      * // => [1.1, 2.3]
6495      */
6496     function sortedUniqBy(array, iteratee) {
6497       return (array && array.length)
6498         ? baseSortedUniqBy(array, getIteratee(iteratee))
6499         : [];
6500     }
6501
6502     /**
6503      * Gets all but the first element of `array`.
6504      *
6505      * @static
6506      * @memberOf _
6507      * @category Array
6508      * @param {Array} array The array to query.
6509      * @returns {Array} Returns the slice of `array`.
6510      * @example
6511      *
6512      * _.tail([1, 2, 3]);
6513      * // => [2, 3]
6514      */
6515     function tail(array) {
6516       return drop(array, 1);
6517     }
6518
6519     /**
6520      * Creates a slice of `array` with `n` elements taken from the beginning.
6521      *
6522      * @static
6523      * @memberOf _
6524      * @category Array
6525      * @param {Array} array The array to query.
6526      * @param {number} [n=1] The number of elements to take.
6527      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6528      * @returns {Array} Returns the slice of `array`.
6529      * @example
6530      *
6531      * _.take([1, 2, 3]);
6532      * // => [1]
6533      *
6534      * _.take([1, 2, 3], 2);
6535      * // => [1, 2]
6536      *
6537      * _.take([1, 2, 3], 5);
6538      * // => [1, 2, 3]
6539      *
6540      * _.take([1, 2, 3], 0);
6541      * // => []
6542      */
6543     function take(array, n, guard) {
6544       if (!(array && array.length)) {
6545         return [];
6546       }
6547       n = (guard || n === undefined) ? 1 : toInteger(n);
6548       return baseSlice(array, 0, n < 0 ? 0 : n);
6549     }
6550
6551     /**
6552      * Creates a slice of `array` with `n` elements taken from the end.
6553      *
6554      * @static
6555      * @memberOf _
6556      * @category Array
6557      * @param {Array} array The array to query.
6558      * @param {number} [n=1] The number of elements to take.
6559      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6560      * @returns {Array} Returns the slice of `array`.
6561      * @example
6562      *
6563      * _.takeRight([1, 2, 3]);
6564      * // => [3]
6565      *
6566      * _.takeRight([1, 2, 3], 2);
6567      * // => [2, 3]
6568      *
6569      * _.takeRight([1, 2, 3], 5);
6570      * // => [1, 2, 3]
6571      *
6572      * _.takeRight([1, 2, 3], 0);
6573      * // => []
6574      */
6575     function takeRight(array, n, guard) {
6576       var length = array ? array.length : 0;
6577       if (!length) {
6578         return [];
6579       }
6580       n = (guard || n === undefined) ? 1 : toInteger(n);
6581       n = length - n;
6582       return baseSlice(array, n < 0 ? 0 : n, length);
6583     }
6584
6585     /**
6586      * Creates a slice of `array` with elements taken from the end. Elements are
6587      * taken until `predicate` returns falsey. The predicate is invoked with three
6588      * arguments: (value, index, array).
6589      *
6590      * @static
6591      * @memberOf _
6592      * @category Array
6593      * @param {Array} array The array to query.
6594      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6595      * @returns {Array} Returns the slice of `array`.
6596      * @example
6597      *
6598      * var users = [
6599      *   { 'user': 'barney',  'active': true },
6600      *   { 'user': 'fred',    'active': false },
6601      *   { 'user': 'pebbles', 'active': false }
6602      * ];
6603      *
6604      * _.takeRightWhile(users, function(o) { return !o.active; });
6605      * // => objects for ['fred', 'pebbles']
6606      *
6607      * // The `_.matches` iteratee shorthand.
6608      * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
6609      * // => objects for ['pebbles']
6610      *
6611      * // The `_.matchesProperty` iteratee shorthand.
6612      * _.takeRightWhile(users, ['active', false]);
6613      * // => objects for ['fred', 'pebbles']
6614      *
6615      * // The `_.property` iteratee shorthand.
6616      * _.takeRightWhile(users, 'active');
6617      * // => []
6618      */
6619     function takeRightWhile(array, predicate) {
6620       return (array && array.length)
6621         ? baseWhile(array, getIteratee(predicate, 3), false, true)
6622         : [];
6623     }
6624
6625     /**
6626      * Creates a slice of `array` with elements taken from the beginning. Elements
6627      * are taken until `predicate` returns falsey. The predicate is invoked with
6628      * three arguments: (value, index, array).
6629      *
6630      * @static
6631      * @memberOf _
6632      * @category Array
6633      * @param {Array} array The array to query.
6634      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6635      * @returns {Array} Returns the slice of `array`.
6636      * @example
6637      *
6638      * var users = [
6639      *   { 'user': 'barney',  'active': false },
6640      *   { 'user': 'fred',    'active': false},
6641      *   { 'user': 'pebbles', 'active': true }
6642      * ];
6643      *
6644      * _.takeWhile(users, function(o) { return !o.active; });
6645      * // => objects for ['barney', 'fred']
6646      *
6647      * // The `_.matches` iteratee shorthand.
6648      * _.takeWhile(users, { 'user': 'barney', 'active': false });
6649      * // => objects for ['barney']
6650      *
6651      * // The `_.matchesProperty` iteratee shorthand.
6652      * _.takeWhile(users, ['active', false]);
6653      * // => objects for ['barney', 'fred']
6654      *
6655      * // The `_.property` iteratee shorthand.
6656      * _.takeWhile(users, 'active');
6657      * // => []
6658      */
6659     function takeWhile(array, predicate) {
6660       return (array && array.length)
6661         ? baseWhile(array, getIteratee(predicate, 3))
6662         : [];
6663     }
6664
6665     /**
6666      * Creates an array of unique values, in order, from all given arrays using
6667      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6668      * for equality comparisons.
6669      *
6670      * @static
6671      * @memberOf _
6672      * @category Array
6673      * @param {...Array} [arrays] The arrays to inspect.
6674      * @returns {Array} Returns the new array of combined values.
6675      * @example
6676      *
6677      * _.union([2, 1], [4, 2], [1, 2]);
6678      * // => [2, 1, 4]
6679      */
6680     var union = rest(function(arrays) {
6681       return baseUniq(baseFlatten(arrays, false, true));
6682     });
6683
6684     /**
6685      * This method is like `_.union` except that it accepts `iteratee` which is
6686      * invoked for each element of each `arrays` to generate the criterion by which
6687      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6688      *
6689      * @static
6690      * @memberOf _
6691      * @category Array
6692      * @param {...Array} [arrays] The arrays to inspect.
6693      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6694      * @returns {Array} Returns the new array of combined values.
6695      * @example
6696      *
6697      * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6698      * // => [2.1, 1.2, 4.3]
6699      *
6700      * // The `_.property` iteratee shorthand.
6701      * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6702      * // => [{ 'x': 1 }, { 'x': 2 }]
6703      */
6704     var unionBy = rest(function(arrays) {
6705       var iteratee = last(arrays);
6706       if (isArrayLikeObject(iteratee)) {
6707         iteratee = undefined;
6708       }
6709       return baseUniq(baseFlatten(arrays, false, true), getIteratee(iteratee));
6710     });
6711
6712     /**
6713      * This method is like `_.union` except that it accepts `comparator` which
6714      * is invoked to compare elements of `arrays`. The comparator is invoked
6715      * with two arguments: (arrVal, othVal).
6716      *
6717      * @static
6718      * @memberOf _
6719      * @category Array
6720      * @param {...Array} [arrays] The arrays to inspect.
6721      * @param {Function} [comparator] The comparator invoked per element.
6722      * @returns {Array} Returns the new array of combined values.
6723      * @example
6724      *
6725      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6726      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6727      *
6728      * _.unionWith(objects, others, _.isEqual);
6729      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
6730      */
6731     var unionWith = rest(function(arrays) {
6732       var comparator = last(arrays);
6733       if (isArrayLikeObject(comparator)) {
6734         comparator = undefined;
6735       }
6736       return baseUniq(baseFlatten(arrays, false, true), undefined, comparator);
6737     });
6738
6739     /**
6740      * Creates a duplicate-free version of an array, using
6741      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6742      * for equality comparisons, in which only the first occurrence of each element
6743      * is kept.
6744      *
6745      * @static
6746      * @memberOf _
6747      * @category Array
6748      * @param {Array} array The array to inspect.
6749      * @returns {Array} Returns the new duplicate free array.
6750      * @example
6751      *
6752      * _.uniq([2, 1, 2]);
6753      * // => [2, 1]
6754      */
6755     function uniq(array) {
6756       return (array && array.length)
6757         ? baseUniq(array)
6758         : [];
6759     }
6760
6761     /**
6762      * This method is like `_.uniq` except that it accepts `iteratee` which is
6763      * invoked for each element in `array` to generate the criterion by which
6764      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6765      *
6766      * @static
6767      * @memberOf _
6768      * @category Array
6769      * @param {Array} array The array to inspect.
6770      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6771      * @returns {Array} Returns the new duplicate free array.
6772      * @example
6773      *
6774      * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
6775      * // => [2.1, 1.2]
6776      *
6777      * // The `_.property` iteratee shorthand.
6778      * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
6779      * // => [{ 'x': 1 }, { 'x': 2 }]
6780      */
6781     function uniqBy(array, iteratee) {
6782       return (array && array.length)
6783         ? baseUniq(array, getIteratee(iteratee))
6784         : [];
6785     }
6786
6787     /**
6788      * This method is like `_.uniq` except that it accepts `comparator` which
6789      * is invoked to compare elements of `array`. The comparator is invoked with
6790      * two arguments: (arrVal, othVal).
6791      *
6792      * @static
6793      * @memberOf _
6794      * @category Array
6795      * @param {Array} array The array to inspect.
6796      * @param {Function} [comparator] The comparator invoked per element.
6797      * @returns {Array} Returns the new duplicate free array.
6798      * @example
6799      *
6800      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }];
6801      *
6802      * _.uniqWith(objects, _.isEqual);
6803      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
6804      */
6805     function uniqWith(array, comparator) {
6806       return (array && array.length)
6807         ? baseUniq(array, undefined, comparator)
6808         : [];
6809     }
6810
6811     /**
6812      * This method is like `_.zip` except that it accepts an array of grouped
6813      * elements and creates an array regrouping the elements to their pre-zip
6814      * configuration.
6815      *
6816      * @static
6817      * @memberOf _
6818      * @category Array
6819      * @param {Array} array The array of grouped elements to process.
6820      * @returns {Array} Returns the new array of regrouped elements.
6821      * @example
6822      *
6823      * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
6824      * // => [['fred', 30, true], ['barney', 40, false]]
6825      *
6826      * _.unzip(zipped);
6827      * // => [['fred', 'barney'], [30, 40], [true, false]]
6828      */
6829     function unzip(array) {
6830       if (!(array && array.length)) {
6831         return [];
6832       }
6833       var length = 0;
6834       array = arrayFilter(array, function(group) {
6835         if (isArrayLikeObject(group)) {
6836           length = nativeMax(group.length, length);
6837           return true;
6838         }
6839       });
6840       return baseTimes(length, function(index) {
6841         return arrayMap(array, baseProperty(index));
6842       });
6843     }
6844
6845     /**
6846      * This method is like `_.unzip` except that it accepts `iteratee` to specify
6847      * how regrouped values should be combined. The iteratee is invoked with the
6848      * elements of each group: (...group).
6849      *
6850      * @static
6851      * @memberOf _
6852      * @category Array
6853      * @param {Array} array The array of grouped elements to process.
6854      * @param {Function} [iteratee=_.identity] The function to combine regrouped values.
6855      * @returns {Array} Returns the new array of regrouped elements.
6856      * @example
6857      *
6858      * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
6859      * // => [[1, 10, 100], [2, 20, 200]]
6860      *
6861      * _.unzipWith(zipped, _.add);
6862      * // => [3, 30, 300]
6863      */
6864     function unzipWith(array, iteratee) {
6865       if (!(array && array.length)) {
6866         return [];
6867       }
6868       var result = unzip(array);
6869       if (iteratee == null) {
6870         return result;
6871       }
6872       return arrayMap(result, function(group) {
6873         return apply(iteratee, undefined, group);
6874       });
6875     }
6876
6877     /**
6878      * Creates an array excluding all given values using
6879      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6880      * for equality comparisons.
6881      *
6882      * @static
6883      * @memberOf _
6884      * @category Array
6885      * @param {Array} array The array to filter.
6886      * @param {...*} [values] The values to exclude.
6887      * @returns {Array} Returns the new array of filtered values.
6888      * @example
6889      *
6890      * _.without([1, 2, 1, 3], 1, 2);
6891      * // => [3]
6892      */
6893     var without = rest(function(array, values) {
6894       return isArrayLikeObject(array)
6895         ? baseDifference(array, values)
6896         : [];
6897     });
6898
6899     /**
6900      * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
6901      * of the given arrays.
6902      *
6903      * @static
6904      * @memberOf _
6905      * @category Array
6906      * @param {...Array} [arrays] The arrays to inspect.
6907      * @returns {Array} Returns the new array of values.
6908      * @example
6909      *
6910      * _.xor([2, 1], [4, 2]);
6911      * // => [1, 4]
6912      */
6913     var xor = rest(function(arrays) {
6914       return baseXor(arrayFilter(arrays, isArrayLikeObject));
6915     });
6916
6917     /**
6918      * This method is like `_.xor` except that it accepts `iteratee` which is
6919      * invoked for each element of each `arrays` to generate the criterion by which
6920      * uniqueness is computed. The iteratee is invoked with one argument: (value).
6921      *
6922      * @static
6923      * @memberOf _
6924      * @category Array
6925      * @param {...Array} [arrays] The arrays to inspect.
6926      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6927      * @returns {Array} Returns the new array of values.
6928      * @example
6929      *
6930      * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6931      * // => [1.2, 4.3]
6932      *
6933      * // The `_.property` iteratee shorthand.
6934      * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6935      * // => [{ 'x': 2 }]
6936      */
6937     var xorBy = rest(function(arrays) {
6938       var iteratee = last(arrays);
6939       if (isArrayLikeObject(iteratee)) {
6940         iteratee = undefined;
6941       }
6942       return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
6943     });
6944
6945     /**
6946      * This method is like `_.xor` except that it accepts `comparator` which is
6947      * invoked to compare elements of `arrays`. The comparator is invoked with
6948      * two arguments: (arrVal, othVal).
6949      *
6950      * @static
6951      * @memberOf _
6952      * @category Array
6953      * @param {...Array} [arrays] The arrays to inspect.
6954      * @param {Function} [comparator] The comparator invoked per element.
6955      * @returns {Array} Returns the new array of values.
6956      * @example
6957      *
6958      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6959      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6960      *
6961      * _.xorWith(objects, others, _.isEqual);
6962      * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
6963      */
6964     var xorWith = rest(function(arrays) {
6965       var comparator = last(arrays);
6966       if (isArrayLikeObject(comparator)) {
6967         comparator = undefined;
6968       }
6969       return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
6970     });
6971
6972     /**
6973      * Creates an array of grouped elements, the first of which contains the first
6974      * elements of the given arrays, the second of which contains the second elements
6975      * of the given arrays, and so on.
6976      *
6977      * @static
6978      * @memberOf _
6979      * @category Array
6980      * @param {...Array} [arrays] The arrays to process.
6981      * @returns {Array} Returns the new array of grouped elements.
6982      * @example
6983      *
6984      * _.zip(['fred', 'barney'], [30, 40], [true, false]);
6985      * // => [['fred', 30, true], ['barney', 40, false]]
6986      */
6987     var zip = rest(unzip);
6988
6989     /**
6990      * This method is like `_.fromPairs` except that it accepts two arrays,
6991      * one of property names and one of corresponding values.
6992      *
6993      * @static
6994      * @memberOf _
6995      * @category Array
6996      * @param {Array} [props=[]] The property names.
6997      * @param {Array} [values=[]] The property values.
6998      * @returns {Object} Returns the new object.
6999      * @example
7000      *
7001      * _.zipObject(['a', 'b'], [1, 2]);
7002      * // => { 'a': 1, 'b': 2 }
7003      */
7004     function zipObject(props, values) {
7005       return baseZipObject(props || [], values || [], assignValue);
7006     }
7007
7008     /**
7009      * This method is like `_.zipObject` except that it supports property paths.
7010      *
7011      * @static
7012      * @memberOf _
7013      * @category Array
7014      * @param {Array} [props=[]] The property names.
7015      * @param {Array} [values=[]] The property values.
7016      * @returns {Object} Returns the new object.
7017      * @example
7018      *
7019      * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
7020      * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
7021      */
7022     function zipObjectDeep(props, values) {
7023       return baseZipObject(props || [], values || [], baseSet);
7024     }
7025
7026     /**
7027      * This method is like `_.zip` except that it accepts `iteratee` to specify
7028      * how grouped values should be combined. The iteratee is invoked with the
7029      * elements of each group: (...group).
7030      *
7031      * @static
7032      * @memberOf _
7033      * @category Array
7034      * @param {...Array} [arrays] The arrays to process.
7035      * @param {Function} [iteratee=_.identity] The function to combine grouped values.
7036      * @returns {Array} Returns the new array of grouped elements.
7037      * @example
7038      *
7039      * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
7040      *   return a + b + c;
7041      * });
7042      * // => [111, 222]
7043      */
7044     var zipWith = rest(function(arrays) {
7045       var length = arrays.length,
7046           iteratee = length > 1 ? arrays[length - 1] : undefined;
7047
7048       iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
7049       return unzipWith(arrays, iteratee);
7050     });
7051
7052     /*------------------------------------------------------------------------*/
7053
7054     /**
7055      * Creates a `lodash` object that wraps `value` with explicit method chaining enabled.
7056      * The result of such method chaining must be unwrapped with `_#value`.
7057      *
7058      * @static
7059      * @memberOf _
7060      * @category Seq
7061      * @param {*} value The value to wrap.
7062      * @returns {Object} Returns the new `lodash` wrapper instance.
7063      * @example
7064      *
7065      * var users = [
7066      *   { 'user': 'barney',  'age': 36 },
7067      *   { 'user': 'fred',    'age': 40 },
7068      *   { 'user': 'pebbles', 'age': 1 }
7069      * ];
7070      *
7071      * var youngest = _
7072      *   .chain(users)
7073      *   .sortBy('age')
7074      *   .map(function(o) {
7075      *     return o.user + ' is ' + o.age;
7076      *   })
7077      *   .head()
7078      *   .value();
7079      * // => 'pebbles is 1'
7080      */
7081     function chain(value) {
7082       var result = lodash(value);
7083       result.__chain__ = true;
7084       return result;
7085     }
7086
7087     /**
7088      * This method invokes `interceptor` and returns `value`. The interceptor
7089      * is invoked with one argument; (value). The purpose of this method is to
7090      * "tap into" a method chain in order to modify intermediate results.
7091      *
7092      * @static
7093      * @memberOf _
7094      * @category Seq
7095      * @param {*} value The value to provide to `interceptor`.
7096      * @param {Function} interceptor The function to invoke.
7097      * @returns {*} Returns `value`.
7098      * @example
7099      *
7100      * _([1, 2, 3])
7101      *  .tap(function(array) {
7102      *    // Mutate input array.
7103      *    array.pop();
7104      *  })
7105      *  .reverse()
7106      *  .value();
7107      * // => [2, 1]
7108      */
7109     function tap(value, interceptor) {
7110       interceptor(value);
7111       return value;
7112     }
7113
7114     /**
7115      * This method is like `_.tap` except that it returns the result of `interceptor`.
7116      * The purpose of this method is to "pass thru" values replacing intermediate
7117      * results in a method chain.
7118      *
7119      * @static
7120      * @memberOf _
7121      * @category Seq
7122      * @param {*} value The value to provide to `interceptor`.
7123      * @param {Function} interceptor The function to invoke.
7124      * @returns {*} Returns the result of `interceptor`.
7125      * @example
7126      *
7127      * _('  abc  ')
7128      *  .chain()
7129      *  .trim()
7130      *  .thru(function(value) {
7131      *    return [value];
7132      *  })
7133      *  .value();
7134      * // => ['abc']
7135      */
7136     function thru(value, interceptor) {
7137       return interceptor(value);
7138     }
7139
7140     /**
7141      * This method is the wrapper version of `_.at`.
7142      *
7143      * @name at
7144      * @memberOf _
7145      * @category Seq
7146      * @param {...(string|string[])} [paths] The property paths of elements to pick,
7147      *  specified individually or in arrays.
7148      * @returns {Object} Returns the new `lodash` wrapper instance.
7149      * @example
7150      *
7151      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
7152      *
7153      * _(object).at(['a[0].b.c', 'a[1]']).value();
7154      * // => [3, 4]
7155      *
7156      * _(['a', 'b', 'c']).at(0, 2).value();
7157      * // => ['a', 'c']
7158      */
7159     var wrapperAt = rest(function(paths) {
7160       paths = baseFlatten(paths);
7161       var length = paths.length,
7162           start = length ? paths[0] : 0,
7163           value = this.__wrapped__,
7164           interceptor = function(object) { return baseAt(object, paths); };
7165
7166       if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start)) {
7167         return this.thru(interceptor);
7168       }
7169       value = value.slice(start, +start + (length ? 1 : 0));
7170       value.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
7171       return new LodashWrapper(value, this.__chain__).thru(function(array) {
7172         if (length && !array.length) {
7173           array.push(undefined);
7174         }
7175         return array;
7176       });
7177     });
7178
7179     /**
7180      * Enables explicit method chaining on the wrapper object.
7181      *
7182      * @name chain
7183      * @memberOf _
7184      * @category Seq
7185      * @returns {Object} Returns the new `lodash` wrapper instance.
7186      * @example
7187      *
7188      * var users = [
7189      *   { 'user': 'barney', 'age': 36 },
7190      *   { 'user': 'fred',   'age': 40 }
7191      * ];
7192      *
7193      * // A sequence without explicit chaining.
7194      * _(users).head();
7195      * // => { 'user': 'barney', 'age': 36 }
7196      *
7197      * // A sequence with explicit chaining.
7198      * _(users)
7199      *   .chain()
7200      *   .head()
7201      *   .pick('user')
7202      *   .value();
7203      * // => { 'user': 'barney' }
7204      */
7205     function wrapperChain() {
7206       return chain(this);
7207     }
7208
7209     /**
7210      * Executes the chained sequence and returns the wrapped result.
7211      *
7212      * @name commit
7213      * @memberOf _
7214      * @category Seq
7215      * @returns {Object} Returns the new `lodash` wrapper instance.
7216      * @example
7217      *
7218      * var array = [1, 2];
7219      * var wrapped = _(array).push(3);
7220      *
7221      * console.log(array);
7222      * // => [1, 2]
7223      *
7224      * wrapped = wrapped.commit();
7225      * console.log(array);
7226      * // => [1, 2, 3]
7227      *
7228      * wrapped.last();
7229      * // => 3
7230      *
7231      * console.log(array);
7232      * // => [1, 2, 3]
7233      */
7234     function wrapperCommit() {
7235       return new LodashWrapper(this.value(), this.__chain__);
7236     }
7237
7238     /**
7239      * This method is the wrapper version of `_.flatMap`.
7240      *
7241      * @name flatMap
7242      * @memberOf _
7243      * @category Seq
7244      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7245      * @returns {Object} Returns the new `lodash` wrapper instance.
7246      * @example
7247      *
7248      * function duplicate(n) {
7249      *   return [n, n];
7250      * }
7251      *
7252      * _([1, 2]).flatMap(duplicate).value();
7253      * // => [1, 1, 2, 2]
7254      */
7255     function wrapperFlatMap(iteratee) {
7256       return this.map(iteratee).flatten();
7257     }
7258
7259     /**
7260      * Gets the next value on a wrapped object following the
7261      * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
7262      *
7263      * @name next
7264      * @memberOf _
7265      * @category Seq
7266      * @returns {Object} Returns the next iterator value.
7267      * @example
7268      *
7269      * var wrapped = _([1, 2]);
7270      *
7271      * wrapped.next();
7272      * // => { 'done': false, 'value': 1 }
7273      *
7274      * wrapped.next();
7275      * // => { 'done': false, 'value': 2 }
7276      *
7277      * wrapped.next();
7278      * // => { 'done': true, 'value': undefined }
7279      */
7280     function wrapperNext() {
7281       if (this.__values__ === undefined) {
7282         this.__values__ = toArray(this.value());
7283       }
7284       var done = this.__index__ >= this.__values__.length,
7285           value = done ? undefined : this.__values__[this.__index__++];
7286
7287       return { 'done': done, 'value': value };
7288     }
7289
7290     /**
7291      * Enables the wrapper to be iterable.
7292      *
7293      * @name Symbol.iterator
7294      * @memberOf _
7295      * @category Seq
7296      * @returns {Object} Returns the wrapper object.
7297      * @example
7298      *
7299      * var wrapped = _([1, 2]);
7300      *
7301      * wrapped[Symbol.iterator]() === wrapped;
7302      * // => true
7303      *
7304      * Array.from(wrapped);
7305      * // => [1, 2]
7306      */
7307     function wrapperToIterator() {
7308       return this;
7309     }
7310
7311     /**
7312      * Creates a clone of the chained sequence planting `value` as the wrapped value.
7313      *
7314      * @name plant
7315      * @memberOf _
7316      * @category Seq
7317      * @param {*} value The value to plant.
7318      * @returns {Object} Returns the new `lodash` wrapper instance.
7319      * @example
7320      *
7321      * function square(n) {
7322      *   return n * n;
7323      * }
7324      *
7325      * var wrapped = _([1, 2]).map(square);
7326      * var other = wrapped.plant([3, 4]);
7327      *
7328      * other.value();
7329      * // => [9, 16]
7330      *
7331      * wrapped.value();
7332      * // => [1, 4]
7333      */
7334     function wrapperPlant(value) {
7335       var result,
7336           parent = this;
7337
7338       while (parent instanceof baseLodash) {
7339         var clone = wrapperClone(parent);
7340         clone.__index__ = 0;
7341         clone.__values__ = undefined;
7342         if (result) {
7343           previous.__wrapped__ = clone;
7344         } else {
7345           result = clone;
7346         }
7347         var previous = clone;
7348         parent = parent.__wrapped__;
7349       }
7350       previous.__wrapped__ = value;
7351       return result;
7352     }
7353
7354     /**
7355      * This method is the wrapper version of `_.reverse`.
7356      *
7357      * **Note:** This method mutates the wrapped array.
7358      *
7359      * @name reverse
7360      * @memberOf _
7361      * @category Seq
7362      * @returns {Object} Returns the new `lodash` wrapper instance.
7363      * @example
7364      *
7365      * var array = [1, 2, 3];
7366      *
7367      * _(array).reverse().value()
7368      * // => [3, 2, 1]
7369      *
7370      * console.log(array);
7371      * // => [3, 2, 1]
7372      */
7373     function wrapperReverse() {
7374       var value = this.__wrapped__;
7375       if (value instanceof LazyWrapper) {
7376         var wrapped = value;
7377         if (this.__actions__.length) {
7378           wrapped = new LazyWrapper(this);
7379         }
7380         wrapped = wrapped.reverse();
7381         wrapped.__actions__.push({ 'func': thru, 'args': [reverse], 'thisArg': undefined });
7382         return new LodashWrapper(wrapped, this.__chain__);
7383       }
7384       return this.thru(reverse);
7385     }
7386
7387     /**
7388      * Executes the chained sequence to extract the unwrapped value.
7389      *
7390      * @name value
7391      * @memberOf _
7392      * @alias toJSON, valueOf
7393      * @category Seq
7394      * @returns {*} Returns the resolved unwrapped value.
7395      * @example
7396      *
7397      * _([1, 2, 3]).value();
7398      * // => [1, 2, 3]
7399      */
7400     function wrapperValue() {
7401       return baseWrapperValue(this.__wrapped__, this.__actions__);
7402     }
7403
7404     /*------------------------------------------------------------------------*/
7405
7406     /**
7407      * Creates an object composed of keys generated from the results of running
7408      * each element of `collection` through `iteratee`. The corresponding value
7409      * of each key is the number of times the key was returned by `iteratee`.
7410      * The iteratee is invoked with one argument: (value).
7411      *
7412      * @static
7413      * @memberOf _
7414      * @category Collection
7415      * @param {Array|Object} collection The collection to iterate over.
7416      * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7417      * @returns {Object} Returns the composed aggregate object.
7418      * @example
7419      *
7420      * _.countBy([6.1, 4.2, 6.3], Math.floor);
7421      * // => { '4': 1, '6': 2 }
7422      *
7423      * _.countBy(['one', 'two', 'three'], 'length');
7424      * // => { '3': 2, '5': 1 }
7425      */
7426     var countBy = createAggregator(function(result, value, key) {
7427       hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
7428     });
7429
7430     /**
7431      * Checks if `predicate` returns truthy for **all** elements of `collection`.
7432      * Iteration is stopped once `predicate` returns falsey. The predicate is
7433      * invoked with three arguments: (value, index|key, collection).
7434      *
7435      * @static
7436      * @memberOf _
7437      * @category Collection
7438      * @param {Array|Object} collection The collection to iterate over.
7439      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7440      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
7441      * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
7442      * @example
7443      *
7444      * _.every([true, 1, null, 'yes'], Boolean);
7445      * // => false
7446      *
7447      * var users = [
7448      *   { 'user': 'barney', 'active': false },
7449      *   { 'user': 'fred',   'active': false }
7450      * ];
7451      *
7452      * // The `_.matches` iteratee shorthand.
7453      * _.every(users, { 'user': 'barney', 'active': false });
7454      * // => false
7455      *
7456      * // The `_.matchesProperty` iteratee shorthand.
7457      * _.every(users, ['active', false]);
7458      * // => true
7459      *
7460      * // The `_.property` iteratee shorthand.
7461      * _.every(users, 'active');
7462      * // => false
7463      */
7464     function every(collection, predicate, guard) {
7465       var func = isArray(collection) ? arrayEvery : baseEvery;
7466       if (guard && isIterateeCall(collection, predicate, guard)) {
7467         predicate = undefined;
7468       }
7469       return func(collection, getIteratee(predicate, 3));
7470     }
7471
7472     /**
7473      * Iterates over elements of `collection`, returning an array of all elements
7474      * `predicate` returns truthy for. The predicate is invoked with three arguments:
7475      * (value, index|key, collection).
7476      *
7477      * @static
7478      * @memberOf _
7479      * @category Collection
7480      * @param {Array|Object} collection The collection to iterate over.
7481      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7482      * @returns {Array} Returns the new filtered array.
7483      * @example
7484      *
7485      * var users = [
7486      *   { 'user': 'barney', 'age': 36, 'active': true },
7487      *   { 'user': 'fred',   'age': 40, 'active': false }
7488      * ];
7489      *
7490      * _.filter(users, function(o) { return !o.active; });
7491      * // => objects for ['fred']
7492      *
7493      * // The `_.matches` iteratee shorthand.
7494      * _.filter(users, { 'age': 36, 'active': true });
7495      * // => objects for ['barney']
7496      *
7497      * // The `_.matchesProperty` iteratee shorthand.
7498      * _.filter(users, ['active', false]);
7499      * // => objects for ['fred']
7500      *
7501      * // The `_.property` iteratee shorthand.
7502      * _.filter(users, 'active');
7503      * // => objects for ['barney']
7504      */
7505     function filter(collection, predicate) {
7506       var func = isArray(collection) ? arrayFilter : baseFilter;
7507       return func(collection, getIteratee(predicate, 3));
7508     }
7509
7510     /**
7511      * Iterates over elements of `collection`, returning the first element
7512      * `predicate` returns truthy for. The predicate is invoked with three arguments:
7513      * (value, index|key, collection).
7514      *
7515      * @static
7516      * @memberOf _
7517      * @category Collection
7518      * @param {Array|Object} collection The collection to search.
7519      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7520      * @returns {*} Returns the matched element, else `undefined`.
7521      * @example
7522      *
7523      * var users = [
7524      *   { 'user': 'barney',  'age': 36, 'active': true },
7525      *   { 'user': 'fred',    'age': 40, 'active': false },
7526      *   { 'user': 'pebbles', 'age': 1,  'active': true }
7527      * ];
7528      *
7529      * _.find(users, function(o) { return o.age < 40; });
7530      * // => object for 'barney'
7531      *
7532      * // The `_.matches` iteratee shorthand.
7533      * _.find(users, { 'age': 1, 'active': true });
7534      * // => object for 'pebbles'
7535      *
7536      * // The `_.matchesProperty` iteratee shorthand.
7537      * _.find(users, ['active', false]);
7538      * // => object for 'fred'
7539      *
7540      * // The `_.property` iteratee shorthand.
7541      * _.find(users, 'active');
7542      * // => object for 'barney'
7543      */
7544     function find(collection, predicate) {
7545       predicate = getIteratee(predicate, 3);
7546       if (isArray(collection)) {
7547         var index = baseFindIndex(collection, predicate);
7548         return index > -1 ? collection[index] : undefined;
7549       }
7550       return baseFind(collection, predicate, baseEach);
7551     }
7552
7553     /**
7554      * This method is like `_.find` except that it iterates over elements of
7555      * `collection` from right to left.
7556      *
7557      * @static
7558      * @memberOf _
7559      * @category Collection
7560      * @param {Array|Object} collection The collection to search.
7561      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7562      * @returns {*} Returns the matched element, else `undefined`.
7563      * @example
7564      *
7565      * _.findLast([1, 2, 3, 4], function(n) {
7566      *   return n % 2 == 1;
7567      * });
7568      * // => 3
7569      */
7570     function findLast(collection, predicate) {
7571       predicate = getIteratee(predicate, 3);
7572       if (isArray(collection)) {
7573         var index = baseFindIndex(collection, predicate, true);
7574         return index > -1 ? collection[index] : undefined;
7575       }
7576       return baseFind(collection, predicate, baseEachRight);
7577     }
7578
7579     /**
7580      * Creates an array of flattened values by running each element in `collection`
7581      * through `iteratee` and concating its result to the other mapped values.
7582      * The iteratee is invoked with three arguments: (value, index|key, collection).
7583      *
7584      * @static
7585      * @memberOf _
7586      * @category Collection
7587      * @param {Array|Object} collection The collection to iterate over.
7588      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7589      * @returns {Array} Returns the new flattened array.
7590      * @example
7591      *
7592      * function duplicate(n) {
7593      *   return [n, n];
7594      * }
7595      *
7596      * _.flatMap([1, 2], duplicate);
7597      * // => [1, 1, 2, 2]
7598      */
7599     function flatMap(collection, iteratee) {
7600       return baseFlatten(map(collection, iteratee));
7601     }
7602
7603     /**
7604      * Iterates over elements of `collection` invoking `iteratee` for each element.
7605      * The iteratee is invoked with three arguments: (value, index|key, collection).
7606      * Iteratee functions may exit iteration early by explicitly returning `false`.
7607      *
7608      * **Note:** As with other "Collections" methods, objects with a "length" property
7609      * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn`
7610      * for object iteration.
7611      *
7612      * @static
7613      * @memberOf _
7614      * @alias each
7615      * @category Collection
7616      * @param {Array|Object} collection The collection to iterate over.
7617      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7618      * @returns {Array|Object} Returns `collection`.
7619      * @example
7620      *
7621      * _([1, 2]).forEach(function(value) {
7622      *   console.log(value);
7623      * });
7624      * // => logs `1` then `2`
7625      *
7626      * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
7627      *   console.log(key);
7628      * });
7629      * // => logs 'a' then 'b' (iteration order is not guaranteed)
7630      */
7631     function forEach(collection, iteratee) {
7632       return (typeof iteratee == 'function' && isArray(collection))
7633         ? arrayEach(collection, iteratee)
7634         : baseEach(collection, toFunction(iteratee));
7635     }
7636
7637     /**
7638      * This method is like `_.forEach` except that it iterates over elements of
7639      * `collection` from right to left.
7640      *
7641      * @static
7642      * @memberOf _
7643      * @alias eachRight
7644      * @category Collection
7645      * @param {Array|Object} collection The collection to iterate over.
7646      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7647      * @returns {Array|Object} Returns `collection`.
7648      * @example
7649      *
7650      * _.forEachRight([1, 2], function(value) {
7651      *   console.log(value);
7652      * });
7653      * // => logs `2` then `1`
7654      */
7655     function forEachRight(collection, iteratee) {
7656       return (typeof iteratee == 'function' && isArray(collection))
7657         ? arrayEachRight(collection, iteratee)
7658         : baseEachRight(collection, toFunction(iteratee));
7659     }
7660
7661     /**
7662      * Creates an object composed of keys generated from the results of running
7663      * each element of `collection` through `iteratee`. The corresponding value
7664      * of each key is an array of elements responsible for generating the key.
7665      * The iteratee is invoked with one argument: (value).
7666      *
7667      * @static
7668      * @memberOf _
7669      * @category Collection
7670      * @param {Array|Object} collection The collection to iterate over.
7671      * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7672      * @returns {Object} Returns the composed aggregate object.
7673      * @example
7674      *
7675      * _.groupBy([6.1, 4.2, 6.3], Math.floor);
7676      * // => { '4': [4.2], '6': [6.1, 6.3] }
7677      *
7678      * // The `_.property` iteratee shorthand.
7679      * _.groupBy(['one', 'two', 'three'], 'length');
7680      * // => { '3': ['one', 'two'], '5': ['three'] }
7681      */
7682     var groupBy = createAggregator(function(result, value, key) {
7683       if (hasOwnProperty.call(result, key)) {
7684         result[key].push(value);
7685       } else {
7686         result[key] = [value];
7687       }
7688     });
7689
7690     /**
7691      * Checks if `value` is in `collection`. If `collection` is a string it's checked
7692      * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7693      * is used for equality comparisons. If `fromIndex` is negative, it's used as
7694      * the offset from the end of `collection`.
7695      *
7696      * @static
7697      * @memberOf _
7698      * @category Collection
7699      * @param {Array|Object|string} collection The collection to search.
7700      * @param {*} value The value to search for.
7701      * @param {number} [fromIndex=0] The index to search from.
7702      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7703      * @returns {boolean} Returns `true` if `value` is found, else `false`.
7704      * @example
7705      *
7706      * _.includes([1, 2, 3], 1);
7707      * // => true
7708      *
7709      * _.includes([1, 2, 3], 1, 2);
7710      * // => false
7711      *
7712      * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
7713      * // => true
7714      *
7715      * _.includes('pebbles', 'eb');
7716      * // => true
7717      */
7718     function includes(collection, value, fromIndex, guard) {
7719       collection = isArrayLike(collection) ? collection : values(collection);
7720       fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
7721
7722       var length = collection.length;
7723       if (fromIndex < 0) {
7724         fromIndex = nativeMax(length + fromIndex, 0);
7725       }
7726       return isString(collection)
7727         ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
7728         : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
7729     }
7730
7731     /**
7732      * Invokes the method at `path` of each element in `collection`, returning
7733      * an array of the results of each invoked method. Any additional arguments
7734      * are provided to each invoked method. If `methodName` is a function it's
7735      * invoked for, and `this` bound to, each element in `collection`.
7736      *
7737      * @static
7738      * @memberOf _
7739      * @category Collection
7740      * @param {Array|Object} collection The collection to iterate over.
7741      * @param {Array|Function|string} path The path of the method to invoke or
7742      *  the function invoked per iteration.
7743      * @param {...*} [args] The arguments to invoke each method with.
7744      * @returns {Array} Returns the array of results.
7745      * @example
7746      *
7747      * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
7748      * // => [[1, 5, 7], [1, 2, 3]]
7749      *
7750      * _.invokeMap([123, 456], String.prototype.split, '');
7751      * // => [['1', '2', '3'], ['4', '5', '6']]
7752      */
7753     var invokeMap = rest(function(collection, path, args) {
7754       var index = -1,
7755           isFunc = typeof path == 'function',
7756           isProp = isKey(path),
7757           result = isArrayLike(collection) ? Array(collection.length) : [];
7758
7759       baseEach(collection, function(value) {
7760         var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
7761         result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
7762       });
7763       return result;
7764     });
7765
7766     /**
7767      * Creates an object composed of keys generated from the results of running
7768      * each element of `collection` through `iteratee`. The corresponding value
7769      * of each key is the last element responsible for generating the key. The
7770      * iteratee is invoked with one argument: (value).
7771      *
7772      * @static
7773      * @memberOf _
7774      * @category Collection
7775      * @param {Array|Object} collection The collection to iterate over.
7776      * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7777      * @returns {Object} Returns the composed aggregate object.
7778      * @example
7779      *
7780      * var array = [
7781      *   { 'dir': 'left', 'code': 97 },
7782      *   { 'dir': 'right', 'code': 100 }
7783      * ];
7784      *
7785      * _.keyBy(array, function(o) {
7786      *   return String.fromCharCode(o.code);
7787      * });
7788      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
7789      *
7790      * _.keyBy(array, 'dir');
7791      * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
7792      */
7793     var keyBy = createAggregator(function(result, value, key) {
7794       result[key] = value;
7795     });
7796
7797     /**
7798      * Creates an array of values by running each element in `collection` through
7799      * `iteratee`. The iteratee is invoked with three arguments:
7800      * (value, index|key, collection).
7801      *
7802      * Many lodash methods are guarded to work as iteratees for methods like
7803      * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
7804      *
7805      * The guarded methods are:
7806      * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`,
7807      * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`,
7808      * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`,
7809      * and `words`
7810      *
7811      * @static
7812      * @memberOf _
7813      * @category Collection
7814      * @param {Array|Object} collection The collection to iterate over.
7815      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7816      * @returns {Array} Returns the new mapped array.
7817      * @example
7818      *
7819      * function square(n) {
7820      *   return n * n;
7821      * }
7822      *
7823      * _.map([4, 8], square);
7824      * // => [16, 64]
7825      *
7826      * _.map({ 'a': 4, 'b': 8 }, square);
7827      * // => [16, 64] (iteration order is not guaranteed)
7828      *
7829      * var users = [
7830      *   { 'user': 'barney' },
7831      *   { 'user': 'fred' }
7832      * ];
7833      *
7834      * // The `_.property` iteratee shorthand.
7835      * _.map(users, 'user');
7836      * // => ['barney', 'fred']
7837      */
7838     function map(collection, iteratee) {
7839       var func = isArray(collection) ? arrayMap : baseMap;
7840       return func(collection, getIteratee(iteratee, 3));
7841     }
7842
7843     /**
7844      * This method is like `_.sortBy` except that it allows specifying the sort
7845      * orders of the iteratees to sort by. If `orders` is unspecified, all values
7846      * are sorted in ascending order. Otherwise, specify an order of "desc" for
7847      * descending or "asc" for ascending sort order of corresponding values.
7848      *
7849      * @static
7850      * @memberOf _
7851      * @category Collection
7852      * @param {Array|Object} collection The collection to iterate over.
7853      * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by.
7854      * @param {string[]} [orders] The sort orders of `iteratees`.
7855      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7856      * @returns {Array} Returns the new sorted array.
7857      * @example
7858      *
7859      * var users = [
7860      *   { 'user': 'fred',   'age': 48 },
7861      *   { 'user': 'barney', 'age': 34 },
7862      *   { 'user': 'fred',   'age': 42 },
7863      *   { 'user': 'barney', 'age': 36 }
7864      * ];
7865      *
7866      * // Sort by `user` in ascending order and by `age` in descending order.
7867      * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
7868      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
7869      */
7870     function orderBy(collection, iteratees, orders, guard) {
7871       if (collection == null) {
7872         return [];
7873       }
7874       if (!isArray(iteratees)) {
7875         iteratees = iteratees == null ? [] : [iteratees];
7876       }
7877       orders = guard ? undefined : orders;
7878       if (!isArray(orders)) {
7879         orders = orders == null ? [] : [orders];
7880       }
7881       return baseOrderBy(collection, iteratees, orders);
7882     }
7883
7884     /**
7885      * Creates an array of elements split into two groups, the first of which
7886      * contains elements `predicate` returns truthy for, the second of which
7887      * contains elements `predicate` returns falsey for. The predicate is
7888      * invoked with one argument: (value).
7889      *
7890      * @static
7891      * @memberOf _
7892      * @category Collection
7893      * @param {Array|Object} collection The collection to iterate over.
7894      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7895      * @returns {Array} Returns the array of grouped elements.
7896      * @example
7897      *
7898      * var users = [
7899      *   { 'user': 'barney',  'age': 36, 'active': false },
7900      *   { 'user': 'fred',    'age': 40, 'active': true },
7901      *   { 'user': 'pebbles', 'age': 1,  'active': false }
7902      * ];
7903      *
7904      * _.partition(users, function(o) { return o.active; });
7905      * // => objects for [['fred'], ['barney', 'pebbles']]
7906      *
7907      * // The `_.matches` iteratee shorthand.
7908      * _.partition(users, { 'age': 1, 'active': false });
7909      * // => objects for [['pebbles'], ['barney', 'fred']]
7910      *
7911      * // The `_.matchesProperty` iteratee shorthand.
7912      * _.partition(users, ['active', false]);
7913      * // => objects for [['barney', 'pebbles'], ['fred']]
7914      *
7915      * // The `_.property` iteratee shorthand.
7916      * _.partition(users, 'active');
7917      * // => objects for [['fred'], ['barney', 'pebbles']]
7918      */
7919     var partition = createAggregator(function(result, value, key) {
7920       result[key ? 0 : 1].push(value);
7921     }, function() { return [[], []]; });
7922
7923     /**
7924      * Reduces `collection` to a value which is the accumulated result of running
7925      * each element in `collection` through `iteratee`, where each successive
7926      * invocation is supplied the return value of the previous. If `accumulator`
7927      * is not given the first element of `collection` is used as the initial
7928      * value. The iteratee is invoked with four arguments:
7929      * (accumulator, value, index|key, collection).
7930      *
7931      * Many lodash methods are guarded to work as iteratees for methods like
7932      * `_.reduce`, `_.reduceRight`, and `_.transform`.
7933      *
7934      * The guarded methods are:
7935      * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
7936      * and `sortBy`
7937      *
7938      * @static
7939      * @memberOf _
7940      * @category Collection
7941      * @param {Array|Object} collection The collection to iterate over.
7942      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7943      * @param {*} [accumulator] The initial value.
7944      * @returns {*} Returns the accumulated value.
7945      * @example
7946      *
7947      * _.reduce([1, 2], function(sum, n) {
7948      *   return sum + n;
7949      * }, 0);
7950      * // => 3
7951      *
7952      * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
7953      *   (result[value] || (result[value] = [])).push(key);
7954      *   return result;
7955      * }, {});
7956      * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
7957      */
7958     function reduce(collection, iteratee, accumulator) {
7959       var func = isArray(collection) ? arrayReduce : baseReduce,
7960           initAccum = arguments.length < 3;
7961
7962       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
7963     }
7964
7965     /**
7966      * This method is like `_.reduce` except that it iterates over elements of
7967      * `collection` from right to left.
7968      *
7969      * @static
7970      * @memberOf _
7971      * @category Collection
7972      * @param {Array|Object} collection The collection to iterate over.
7973      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7974      * @param {*} [accumulator] The initial value.
7975      * @returns {*} Returns the accumulated value.
7976      * @example
7977      *
7978      * var array = [[0, 1], [2, 3], [4, 5]];
7979      *
7980      * _.reduceRight(array, function(flattened, other) {
7981      *   return flattened.concat(other);
7982      * }, []);
7983      * // => [4, 5, 2, 3, 0, 1]
7984      */
7985     function reduceRight(collection, iteratee, accumulator) {
7986       var func = isArray(collection) ? arrayReduceRight : baseReduce,
7987           initAccum = arguments.length < 3;
7988
7989       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
7990     }
7991
7992     /**
7993      * The opposite of `_.filter`; this method returns the elements of `collection`
7994      * that `predicate` does **not** return truthy for.
7995      *
7996      * @static
7997      * @memberOf _
7998      * @category Collection
7999      * @param {Array|Object} collection The collection to iterate over.
8000      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
8001      * @returns {Array} Returns the new filtered array.
8002      * @example
8003      *
8004      * var users = [
8005      *   { 'user': 'barney', 'age': 36, 'active': false },
8006      *   { 'user': 'fred',   'age': 40, 'active': true }
8007      * ];
8008      *
8009      * _.reject(users, function(o) { return !o.active; });
8010      * // => objects for ['fred']
8011      *
8012      * // The `_.matches` iteratee shorthand.
8013      * _.reject(users, { 'age': 40, 'active': true });
8014      * // => objects for ['barney']
8015      *
8016      * // The `_.matchesProperty` iteratee shorthand.
8017      * _.reject(users, ['active', false]);
8018      * // => objects for ['fred']
8019      *
8020      * // The `_.property` iteratee shorthand.
8021      * _.reject(users, 'active');
8022      * // => objects for ['barney']
8023      */
8024     function reject(collection, predicate) {
8025       var func = isArray(collection) ? arrayFilter : baseFilter;
8026       predicate = getIteratee(predicate, 3);
8027       return func(collection, function(value, index, collection) {
8028         return !predicate(value, index, collection);
8029       });
8030     }
8031
8032     /**
8033      * Gets a random element from `collection`.
8034      *
8035      * @static
8036      * @memberOf _
8037      * @category Collection
8038      * @param {Array|Object} collection The collection to sample.
8039      * @returns {*} Returns the random element.
8040      * @example
8041      *
8042      * _.sample([1, 2, 3, 4]);
8043      * // => 2
8044      */
8045     function sample(collection) {
8046       var array = isArrayLike(collection) ? collection : values(collection),
8047           length = array.length;
8048
8049       return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
8050     }
8051
8052     /**
8053      * Gets `n` random elements at unique keys from `collection` up to the
8054      * size of `collection`.
8055      *
8056      * @static
8057      * @memberOf _
8058      * @category Collection
8059      * @param {Array|Object} collection The collection to sample.
8060      * @param {number} [n=0] The number of elements to sample.
8061      * @returns {Array} Returns the random elements.
8062      * @example
8063      *
8064      * _.sampleSize([1, 2, 3], 2);
8065      * // => [3, 1]
8066      *
8067      * _.sampleSize([1, 2, 3], 4);
8068      * // => [2, 3, 1]
8069      */
8070     function sampleSize(collection, n) {
8071       var index = -1,
8072           result = toArray(collection),
8073           length = result.length,
8074           lastIndex = length - 1;
8075
8076       n = baseClamp(toInteger(n), 0, length);
8077       while (++index < n) {
8078         var rand = baseRandom(index, lastIndex),
8079             value = result[rand];
8080
8081         result[rand] = result[index];
8082         result[index] = value;
8083       }
8084       result.length = n;
8085       return result;
8086     }
8087
8088     /**
8089      * Creates an array of shuffled values, using a version of the
8090      * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
8091      *
8092      * @static
8093      * @memberOf _
8094      * @category Collection
8095      * @param {Array|Object} collection The collection to shuffle.
8096      * @returns {Array} Returns the new shuffled array.
8097      * @example
8098      *
8099      * _.shuffle([1, 2, 3, 4]);
8100      * // => [4, 1, 3, 2]
8101      */
8102     function shuffle(collection) {
8103       return sampleSize(collection, MAX_ARRAY_LENGTH);
8104     }
8105
8106     /**
8107      * Gets the size of `collection` by returning its length for array-like
8108      * values or the number of own enumerable properties for objects.
8109      *
8110      * @static
8111      * @memberOf _
8112      * @category Collection
8113      * @param {Array|Object} collection The collection to inspect.
8114      * @returns {number} Returns the collection size.
8115      * @example
8116      *
8117      * _.size([1, 2, 3]);
8118      * // => 3
8119      *
8120      * _.size({ 'a': 1, 'b': 2 });
8121      * // => 2
8122      *
8123      * _.size('pebbles');
8124      * // => 7
8125      */
8126     function size(collection) {
8127       if (collection == null) {
8128         return 0;
8129       }
8130       if (isArrayLike(collection)) {
8131         var result = collection.length;
8132         return (result && isString(collection)) ? stringSize(collection) : result;
8133       }
8134       return keys(collection).length;
8135     }
8136
8137     /**
8138      * Checks if `predicate` returns truthy for **any** element of `collection`.
8139      * Iteration is stopped once `predicate` returns truthy. The predicate is
8140      * invoked with three arguments: (value, index|key, collection).
8141      *
8142      * @static
8143      * @memberOf _
8144      * @category Collection
8145      * @param {Array|Object} collection The collection to iterate over.
8146      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
8147      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8148      * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
8149      * @example
8150      *
8151      * _.some([null, 0, 'yes', false], Boolean);
8152      * // => true
8153      *
8154      * var users = [
8155      *   { 'user': 'barney', 'active': true },
8156      *   { 'user': 'fred',   'active': false }
8157      * ];
8158      *
8159      * // The `_.matches` iteratee shorthand.
8160      * _.some(users, { 'user': 'barney', 'active': false });
8161      * // => false
8162      *
8163      * // The `_.matchesProperty` iteratee shorthand.
8164      * _.some(users, ['active', false]);
8165      * // => true
8166      *
8167      * // The `_.property` iteratee shorthand.
8168      * _.some(users, 'active');
8169      * // => true
8170      */
8171     function some(collection, predicate, guard) {
8172       var func = isArray(collection) ? arraySome : baseSome;
8173       if (guard && isIterateeCall(collection, predicate, guard)) {
8174         predicate = undefined;
8175       }
8176       return func(collection, getIteratee(predicate, 3));
8177     }
8178
8179     /**
8180      * Creates an array of elements, sorted in ascending order by the results of
8181      * running each element in a collection through each iteratee. This method
8182      * performs a stable sort, that is, it preserves the original sort order of
8183      * equal elements. The iteratees are invoked with one argument: (value).
8184      *
8185      * @static
8186      * @memberOf _
8187      * @category Collection
8188      * @param {Array|Object} collection The collection to iterate over.
8189      * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]]
8190      *  The iteratees to sort by, specified individually or in arrays.
8191      * @returns {Array} Returns the new sorted array.
8192      * @example
8193      *
8194      * var users = [
8195      *   { 'user': 'fred',   'age': 48 },
8196      *   { 'user': 'barney', 'age': 36 },
8197      *   { 'user': 'fred',   'age': 42 },
8198      *   { 'user': 'barney', 'age': 34 }
8199      * ];
8200      *
8201      * _.sortBy(users, function(o) { return o.user; });
8202      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8203      *
8204      * _.sortBy(users, ['user', 'age']);
8205      * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
8206      *
8207      * _.sortBy(users, 'user', function(o) {
8208      *   return Math.floor(o.age / 10);
8209      * });
8210      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8211      */
8212     var sortBy = rest(function(collection, iteratees) {
8213       if (collection == null) {
8214         return [];
8215       }
8216       var length = iteratees.length;
8217       if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
8218         iteratees = [];
8219       } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
8220         iteratees.length = 1;
8221       }
8222       return baseOrderBy(collection, baseFlatten(iteratees), []);
8223     });
8224
8225     /*------------------------------------------------------------------------*/
8226
8227     /**
8228      * Gets the timestamp of the number of milliseconds that have elapsed since
8229      * the Unix epoch (1 January 1970 00:00:00 UTC).
8230      *
8231      * @static
8232      * @memberOf _
8233      * @type Function
8234      * @category Date
8235      * @returns {number} Returns the timestamp.
8236      * @example
8237      *
8238      * _.defer(function(stamp) {
8239      *   console.log(_.now() - stamp);
8240      * }, _.now());
8241      * // => logs the number of milliseconds it took for the deferred function to be invoked
8242      */
8243     var now = Date.now;
8244
8245     /*------------------------------------------------------------------------*/
8246
8247     /**
8248      * The opposite of `_.before`; this method creates a function that invokes
8249      * `func` once it's called `n` or more times.
8250      *
8251      * @static
8252      * @memberOf _
8253      * @category Function
8254      * @param {number} n The number of calls before `func` is invoked.
8255      * @param {Function} func The function to restrict.
8256      * @returns {Function} Returns the new restricted function.
8257      * @example
8258      *
8259      * var saves = ['profile', 'settings'];
8260      *
8261      * var done = _.after(saves.length, function() {
8262      *   console.log('done saving!');
8263      * });
8264      *
8265      * _.forEach(saves, function(type) {
8266      *   asyncSave({ 'type': type, 'complete': done });
8267      * });
8268      * // => logs 'done saving!' after the two async saves have completed
8269      */
8270     function after(n, func) {
8271       if (typeof func != 'function') {
8272         throw new TypeError(FUNC_ERROR_TEXT);
8273       }
8274       n = toInteger(n);
8275       return function() {
8276         if (--n < 1) {
8277           return func.apply(this, arguments);
8278         }
8279       };
8280     }
8281
8282     /**
8283      * Creates a function that accepts up to `n` arguments, ignoring any
8284      * additional arguments.
8285      *
8286      * @static
8287      * @memberOf _
8288      * @category Function
8289      * @param {Function} func The function to cap arguments for.
8290      * @param {number} [n=func.length] The arity cap.
8291      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8292      * @returns {Function} Returns the new function.
8293      * @example
8294      *
8295      * _.map(['6', '8', '10'], _.ary(parseInt, 1));
8296      * // => [6, 8, 10]
8297      */
8298     function ary(func, n, guard) {
8299       n = guard ? undefined : n;
8300       n = (func && n == null) ? func.length : n;
8301       return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
8302     }
8303
8304     /**
8305      * Creates a function that invokes `func`, with the `this` binding and arguments
8306      * of the created function, while it's called less than `n` times. Subsequent
8307      * calls to the created function return the result of the last `func` invocation.
8308      *
8309      * @static
8310      * @memberOf _
8311      * @category Function
8312      * @param {number} n The number of calls at which `func` is no longer invoked.
8313      * @param {Function} func The function to restrict.
8314      * @returns {Function} Returns the new restricted function.
8315      * @example
8316      *
8317      * jQuery(element).on('click', _.before(5, addContactToList));
8318      * // => allows adding up to 4 contacts to the list
8319      */
8320     function before(n, func) {
8321       var result;
8322       if (typeof func != 'function') {
8323         throw new TypeError(FUNC_ERROR_TEXT);
8324       }
8325       n = toInteger(n);
8326       return function() {
8327         if (--n > 0) {
8328           result = func.apply(this, arguments);
8329         }
8330         if (n <= 1) {
8331           func = undefined;
8332         }
8333         return result;
8334       };
8335     }
8336
8337     /**
8338      * Creates a function that invokes `func` with the `this` binding of `thisArg`
8339      * and prepends any additional `_.bind` arguments to those provided to the
8340      * bound function.
8341      *
8342      * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
8343      * may be used as a placeholder for partially applied arguments.
8344      *
8345      * **Note:** Unlike native `Function#bind` this method doesn't set the "length"
8346      * property of bound functions.
8347      *
8348      * @static
8349      * @memberOf _
8350      * @category Function
8351      * @param {Function} func The function to bind.
8352      * @param {*} thisArg The `this` binding of `func`.
8353      * @param {...*} [partials] The arguments to be partially applied.
8354      * @returns {Function} Returns the new bound function.
8355      * @example
8356      *
8357      * var greet = function(greeting, punctuation) {
8358      *   return greeting + ' ' + this.user + punctuation;
8359      * };
8360      *
8361      * var object = { 'user': 'fred' };
8362      *
8363      * var bound = _.bind(greet, object, 'hi');
8364      * bound('!');
8365      * // => 'hi fred!'
8366      *
8367      * // Bound with placeholders.
8368      * var bound = _.bind(greet, object, _, '!');
8369      * bound('hi');
8370      * // => 'hi fred!'
8371      */
8372     var bind = rest(function(func, thisArg, partials) {
8373       var bitmask = BIND_FLAG;
8374       if (partials.length) {
8375         var placeholder = lodash.placeholder || bind.placeholder,
8376             holders = replaceHolders(partials, placeholder);
8377
8378         bitmask |= PARTIAL_FLAG;
8379       }
8380       return createWrapper(func, bitmask, thisArg, partials, holders);
8381     });
8382
8383     /**
8384      * Creates a function that invokes the method at `object[key]` and prepends
8385      * any additional `_.bindKey` arguments to those provided to the bound function.
8386      *
8387      * This method differs from `_.bind` by allowing bound functions to reference
8388      * methods that may be redefined or don't yet exist.
8389      * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
8390      * for more details.
8391      *
8392      * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
8393      * builds, may be used as a placeholder for partially applied arguments.
8394      *
8395      * @static
8396      * @memberOf _
8397      * @category Function
8398      * @param {Object} object The object to invoke the method on.
8399      * @param {string} key The key of the method.
8400      * @param {...*} [partials] The arguments to be partially applied.
8401      * @returns {Function} Returns the new bound function.
8402      * @example
8403      *
8404      * var object = {
8405      *   'user': 'fred',
8406      *   'greet': function(greeting, punctuation) {
8407      *     return greeting + ' ' + this.user + punctuation;
8408      *   }
8409      * };
8410      *
8411      * var bound = _.bindKey(object, 'greet', 'hi');
8412      * bound('!');
8413      * // => 'hi fred!'
8414      *
8415      * object.greet = function(greeting, punctuation) {
8416      *   return greeting + 'ya ' + this.user + punctuation;
8417      * };
8418      *
8419      * bound('!');
8420      * // => 'hiya fred!'
8421      *
8422      * // Bound with placeholders.
8423      * var bound = _.bindKey(object, 'greet', _, '!');
8424      * bound('hi');
8425      * // => 'hiya fred!'
8426      */
8427     var bindKey = rest(function(object, key, partials) {
8428       var bitmask = BIND_FLAG | BIND_KEY_FLAG;
8429       if (partials.length) {
8430         var placeholder = lodash.placeholder || bindKey.placeholder,
8431             holders = replaceHolders(partials, placeholder);
8432
8433         bitmask |= PARTIAL_FLAG;
8434       }
8435       return createWrapper(key, bitmask, object, partials, holders);
8436     });
8437
8438     /**
8439      * Creates a function that accepts arguments of `func` and either invokes
8440      * `func` returning its result, if at least `arity` number of arguments have
8441      * been provided, or returns a function that accepts the remaining `func`
8442      * arguments, and so on. The arity of `func` may be specified if `func.length`
8443      * is not sufficient.
8444      *
8445      * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
8446      * may be used as a placeholder for provided arguments.
8447      *
8448      * **Note:** This method doesn't set the "length" property of curried functions.
8449      *
8450      * @static
8451      * @memberOf _
8452      * @category Function
8453      * @param {Function} func The function to curry.
8454      * @param {number} [arity=func.length] The arity of `func`.
8455      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8456      * @returns {Function} Returns the new curried function.
8457      * @example
8458      *
8459      * var abc = function(a, b, c) {
8460      *   return [a, b, c];
8461      * };
8462      *
8463      * var curried = _.curry(abc);
8464      *
8465      * curried(1)(2)(3);
8466      * // => [1, 2, 3]
8467      *
8468      * curried(1, 2)(3);
8469      * // => [1, 2, 3]
8470      *
8471      * curried(1, 2, 3);
8472      * // => [1, 2, 3]
8473      *
8474      * // Curried with placeholders.
8475      * curried(1)(_, 3)(2);
8476      * // => [1, 2, 3]
8477      */
8478     function curry(func, arity, guard) {
8479       arity = guard ? undefined : arity;
8480       var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8481       result.placeholder = lodash.placeholder || curry.placeholder;
8482       return result;
8483     }
8484
8485     /**
8486      * This method is like `_.curry` except that arguments are applied to `func`
8487      * in the manner of `_.partialRight` instead of `_.partial`.
8488      *
8489      * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
8490      * builds, may be used as a placeholder for provided arguments.
8491      *
8492      * **Note:** This method doesn't set the "length" property of curried functions.
8493      *
8494      * @static
8495      * @memberOf _
8496      * @category Function
8497      * @param {Function} func The function to curry.
8498      * @param {number} [arity=func.length] The arity of `func`.
8499      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8500      * @returns {Function} Returns the new curried function.
8501      * @example
8502      *
8503      * var abc = function(a, b, c) {
8504      *   return [a, b, c];
8505      * };
8506      *
8507      * var curried = _.curryRight(abc);
8508      *
8509      * curried(3)(2)(1);
8510      * // => [1, 2, 3]
8511      *
8512      * curried(2, 3)(1);
8513      * // => [1, 2, 3]
8514      *
8515      * curried(1, 2, 3);
8516      * // => [1, 2, 3]
8517      *
8518      * // Curried with placeholders.
8519      * curried(3)(1, _)(2);
8520      * // => [1, 2, 3]
8521      */
8522     function curryRight(func, arity, guard) {
8523       arity = guard ? undefined : arity;
8524       var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8525       result.placeholder = lodash.placeholder || curryRight.placeholder;
8526       return result;
8527     }
8528
8529     /**
8530      * Creates a debounced function that delays invoking `func` until after `wait`
8531      * milliseconds have elapsed since the last time the debounced function was
8532      * invoked. The debounced function comes with a `cancel` method to cancel
8533      * delayed `func` invocations and a `flush` method to immediately invoke them.
8534      * Provide an options object to indicate whether `func` should be invoked on
8535      * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
8536      * with the last arguments provided to the debounced function. Subsequent calls
8537      * to the debounced function return the result of the last `func` invocation.
8538      *
8539      * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
8540      * on the trailing edge of the timeout only if the debounced function is
8541      * invoked more than once during the `wait` timeout.
8542      *
8543      * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
8544      * for details over the differences between `_.debounce` and `_.throttle`.
8545      *
8546      * @static
8547      * @memberOf _
8548      * @category Function
8549      * @param {Function} func The function to debounce.
8550      * @param {number} [wait=0] The number of milliseconds to delay.
8551      * @param {Object} [options] The options object.
8552      * @param {boolean} [options.leading=false] Specify invoking on the leading
8553      *  edge of the timeout.
8554      * @param {number} [options.maxWait] The maximum time `func` is allowed to be
8555      *  delayed before it's invoked.
8556      * @param {boolean} [options.trailing=true] Specify invoking on the trailing
8557      *  edge of the timeout.
8558      * @returns {Function} Returns the new debounced function.
8559      * @example
8560      *
8561      * // Avoid costly calculations while the window size is in flux.
8562      * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
8563      *
8564      * // Invoke `sendMail` when clicked, debouncing subsequent calls.
8565      * jQuery(element).on('click', _.debounce(sendMail, 300, {
8566      *   'leading': true,
8567      *   'trailing': false
8568      * }));
8569      *
8570      * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
8571      * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
8572      * var source = new EventSource('/stream');
8573      * jQuery(source).on('message', debounced);
8574      *
8575      * // Cancel the trailing debounced invocation.
8576      * jQuery(window).on('popstate', debounced.cancel);
8577      */
8578     function debounce(func, wait, options) {
8579       var args,
8580           maxTimeoutId,
8581           result,
8582           stamp,
8583           thisArg,
8584           timeoutId,
8585           trailingCall,
8586           lastCalled = 0,
8587           leading = false,
8588           maxWait = false,
8589           trailing = true;
8590
8591       if (typeof func != 'function') {
8592         throw new TypeError(FUNC_ERROR_TEXT);
8593       }
8594       wait = toNumber(wait) || 0;
8595       if (isObject(options)) {
8596         leading = !!options.leading;
8597         maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait);
8598         trailing = 'trailing' in options ? !!options.trailing : trailing;
8599       }
8600
8601       function cancel() {
8602         if (timeoutId) {
8603           clearTimeout(timeoutId);
8604         }
8605         if (maxTimeoutId) {
8606           clearTimeout(maxTimeoutId);
8607         }
8608         lastCalled = 0;
8609         args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined;
8610       }
8611
8612       function complete(isCalled, id) {
8613         if (id) {
8614           clearTimeout(id);
8615         }
8616         maxTimeoutId = timeoutId = trailingCall = undefined;
8617         if (isCalled) {
8618           lastCalled = now();
8619           result = func.apply(thisArg, args);
8620           if (!timeoutId && !maxTimeoutId) {
8621             args = thisArg = undefined;
8622           }
8623         }
8624       }
8625
8626       function delayed() {
8627         var remaining = wait - (now() - stamp);
8628         if (remaining <= 0 || remaining > wait) {
8629           complete(trailingCall, maxTimeoutId);
8630         } else {
8631           timeoutId = setTimeout(delayed, remaining);
8632         }
8633       }
8634
8635       function flush() {
8636         if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) {
8637           result = func.apply(thisArg, args);
8638         }
8639         cancel();
8640         return result;
8641       }
8642
8643       function maxDelayed() {
8644         complete(trailing, timeoutId);
8645       }
8646
8647       function debounced() {
8648         args = arguments;
8649         stamp = now();
8650         thisArg = this;
8651         trailingCall = trailing && (timeoutId || !leading);
8652
8653         if (maxWait === false) {
8654           var leadingCall = leading && !timeoutId;
8655         } else {
8656           if (!lastCalled && !maxTimeoutId && !leading) {
8657             lastCalled = stamp;
8658           }
8659           var remaining = maxWait - (stamp - lastCalled),
8660               isCalled = remaining <= 0 || remaining > maxWait;
8661
8662           if (isCalled) {
8663             if (maxTimeoutId) {
8664               maxTimeoutId = clearTimeout(maxTimeoutId);
8665             }
8666             lastCalled = stamp;
8667             result = func.apply(thisArg, args);
8668           }
8669           else if (!maxTimeoutId) {
8670             maxTimeoutId = setTimeout(maxDelayed, remaining);
8671           }
8672         }
8673         if (isCalled && timeoutId) {
8674           timeoutId = clearTimeout(timeoutId);
8675         }
8676         else if (!timeoutId && wait !== maxWait) {
8677           timeoutId = setTimeout(delayed, wait);
8678         }
8679         if (leadingCall) {
8680           isCalled = true;
8681           result = func.apply(thisArg, args);
8682         }
8683         if (isCalled && !timeoutId && !maxTimeoutId) {
8684           args = thisArg = undefined;
8685         }
8686         return result;
8687       }
8688       debounced.cancel = cancel;
8689       debounced.flush = flush;
8690       return debounced;
8691     }
8692
8693     /**
8694      * Defers invoking the `func` until the current call stack has cleared. Any
8695      * additional arguments are provided to `func` when it's invoked.
8696      *
8697      * @static
8698      * @memberOf _
8699      * @category Function
8700      * @param {Function} func The function to defer.
8701      * @param {...*} [args] The arguments to invoke `func` with.
8702      * @returns {number} Returns the timer id.
8703      * @example
8704      *
8705      * _.defer(function(text) {
8706      *   console.log(text);
8707      * }, 'deferred');
8708      * // => logs 'deferred' after one or more milliseconds
8709      */
8710     var defer = rest(function(func, args) {
8711       return baseDelay(func, 1, args);
8712     });
8713
8714     /**
8715      * Invokes `func` after `wait` milliseconds. Any additional arguments are
8716      * provided to `func` when it's invoked.
8717      *
8718      * @static
8719      * @memberOf _
8720      * @category Function
8721      * @param {Function} func The function to delay.
8722      * @param {number} wait The number of milliseconds to delay invocation.
8723      * @param {...*} [args] The arguments to invoke `func` with.
8724      * @returns {number} Returns the timer id.
8725      * @example
8726      *
8727      * _.delay(function(text) {
8728      *   console.log(text);
8729      * }, 1000, 'later');
8730      * // => logs 'later' after one second
8731      */
8732     var delay = rest(function(func, wait, args) {
8733       return baseDelay(func, toNumber(wait) || 0, args);
8734     });
8735
8736     /**
8737      * Creates a function that invokes `func` with arguments reversed.
8738      *
8739      * @static
8740      * @memberOf _
8741      * @category Function
8742      * @param {Function} func The function to flip arguments for.
8743      * @returns {Function} Returns the new function.
8744      * @example
8745      *
8746      * var flipped = _.flip(function() {
8747      *   return _.toArray(arguments);
8748      * });
8749      *
8750      * flipped('a', 'b', 'c', 'd');
8751      * // => ['d', 'c', 'b', 'a']
8752      */
8753     function flip(func) {
8754       return createWrapper(func, FLIP_FLAG);
8755     }
8756
8757     /**
8758      * Creates a function that memoizes the result of `func`. If `resolver` is
8759      * provided it determines the cache key for storing the result based on the
8760      * arguments provided to the memoized function. By default, the first argument
8761      * provided to the memoized function is used as the map cache key. The `func`
8762      * is invoked with the `this` binding of the memoized function.
8763      *
8764      * **Note:** The cache is exposed as the `cache` property on the memoized
8765      * function. Its creation may be customized by replacing the `_.memoize.Cache`
8766      * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
8767      * method interface of `delete`, `get`, `has`, and `set`.
8768      *
8769      * @static
8770      * @memberOf _
8771      * @category Function
8772      * @param {Function} func The function to have its output memoized.
8773      * @param {Function} [resolver] The function to resolve the cache key.
8774      * @returns {Function} Returns the new memoizing function.
8775      * @example
8776      *
8777      * var object = { 'a': 1, 'b': 2 };
8778      * var other = { 'c': 3, 'd': 4 };
8779      *
8780      * var values = _.memoize(_.values);
8781      * values(object);
8782      * // => [1, 2]
8783      *
8784      * values(other);
8785      * // => [3, 4]
8786      *
8787      * object.a = 2;
8788      * values(object);
8789      * // => [1, 2]
8790      *
8791      * // Modify the result cache.
8792      * values.cache.set(object, ['a', 'b']);
8793      * values(object);
8794      * // => ['a', 'b']
8795      *
8796      * // Replace `_.memoize.Cache`.
8797      * _.memoize.Cache = WeakMap;
8798      */
8799     function memoize(func, resolver) {
8800       if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
8801         throw new TypeError(FUNC_ERROR_TEXT);
8802       }
8803       var memoized = function() {
8804         var args = arguments,
8805             key = resolver ? resolver.apply(this, args) : args[0],
8806             cache = memoized.cache;
8807
8808         if (cache.has(key)) {
8809           return cache.get(key);
8810         }
8811         var result = func.apply(this, args);
8812         memoized.cache = cache.set(key, result);
8813         return result;
8814       };
8815       memoized.cache = new memoize.Cache;
8816       return memoized;
8817     }
8818
8819     /**
8820      * Creates a function that negates the result of the predicate `func`. The
8821      * `func` predicate is invoked with the `this` binding and arguments of the
8822      * created function.
8823      *
8824      * @static
8825      * @memberOf _
8826      * @category Function
8827      * @param {Function} predicate The predicate to negate.
8828      * @returns {Function} Returns the new function.
8829      * @example
8830      *
8831      * function isEven(n) {
8832      *   return n % 2 == 0;
8833      * }
8834      *
8835      * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
8836      * // => [1, 3, 5]
8837      */
8838     function negate(predicate) {
8839       if (typeof predicate != 'function') {
8840         throw new TypeError(FUNC_ERROR_TEXT);
8841       }
8842       return function() {
8843         return !predicate.apply(this, arguments);
8844       };
8845     }
8846
8847     /**
8848      * Creates a function that is restricted to invoking `func` once. Repeat calls
8849      * to the function return the value of the first invocation. The `func` is
8850      * invoked with the `this` binding and arguments of the created function.
8851      *
8852      * @static
8853      * @memberOf _
8854      * @category Function
8855      * @param {Function} func The function to restrict.
8856      * @returns {Function} Returns the new restricted function.
8857      * @example
8858      *
8859      * var initialize = _.once(createApplication);
8860      * initialize();
8861      * initialize();
8862      * // `initialize` invokes `createApplication` once
8863      */
8864     function once(func) {
8865       return before(2, func);
8866     }
8867
8868     /**
8869      * Creates a function that invokes `func` with arguments transformed by
8870      * corresponding `transforms`.
8871      *
8872      * @static
8873      * @memberOf _
8874      * @category Function
8875      * @param {Function} func The function to wrap.
8876      * @param {...(Function|Function[])} [transforms] The functions to transform
8877      * arguments, specified individually or in arrays.
8878      * @returns {Function} Returns the new function.
8879      * @example
8880      *
8881      * function doubled(n) {
8882      *   return n * 2;
8883      * }
8884      *
8885      * function square(n) {
8886      *   return n * n;
8887      * }
8888      *
8889      * var func = _.overArgs(function(x, y) {
8890      *   return [x, y];
8891      * }, square, doubled);
8892      *
8893      * func(9, 3);
8894      * // => [81, 6]
8895      *
8896      * func(10, 5);
8897      * // => [100, 10]
8898      */
8899     var overArgs = rest(function(func, transforms) {
8900       transforms = arrayMap(baseFlatten(transforms), getIteratee());
8901
8902       var funcsLength = transforms.length;
8903       return rest(function(args) {
8904         var index = -1,
8905             length = nativeMin(args.length, funcsLength);
8906
8907         while (++index < length) {
8908           args[index] = transforms[index].call(this, args[index]);
8909         }
8910         return apply(func, this, args);
8911       });
8912     });
8913
8914     /**
8915      * Creates a function that invokes `func` with `partial` arguments prepended
8916      * to those provided to the new function. This method is like `_.bind` except
8917      * it does **not** alter the `this` binding.
8918      *
8919      * The `_.partial.placeholder` value, which defaults to `_` in monolithic
8920      * builds, may be used as a placeholder for partially applied arguments.
8921      *
8922      * **Note:** This method doesn't set the "length" property of partially
8923      * applied functions.
8924      *
8925      * @static
8926      * @memberOf _
8927      * @category Function
8928      * @param {Function} func The function to partially apply arguments to.
8929      * @param {...*} [partials] The arguments to be partially applied.
8930      * @returns {Function} Returns the new partially applied function.
8931      * @example
8932      *
8933      * var greet = function(greeting, name) {
8934      *   return greeting + ' ' + name;
8935      * };
8936      *
8937      * var sayHelloTo = _.partial(greet, 'hello');
8938      * sayHelloTo('fred');
8939      * // => 'hello fred'
8940      *
8941      * // Partially applied with placeholders.
8942      * var greetFred = _.partial(greet, _, 'fred');
8943      * greetFred('hi');
8944      * // => 'hi fred'
8945      */
8946     var partial = rest(function(func, partials) {
8947       var placeholder = lodash.placeholder || partial.placeholder,
8948           holders = replaceHolders(partials, placeholder);
8949
8950       return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
8951     });
8952
8953     /**
8954      * This method is like `_.partial` except that partially applied arguments
8955      * are appended to those provided to the new function.
8956      *
8957      * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
8958      * builds, may be used as a placeholder for partially applied arguments.
8959      *
8960      * **Note:** This method doesn't set the "length" property of partially
8961      * applied functions.
8962      *
8963      * @static
8964      * @memberOf _
8965      * @category Function
8966      * @param {Function} func The function to partially apply arguments to.
8967      * @param {...*} [partials] The arguments to be partially applied.
8968      * @returns {Function} Returns the new partially applied function.
8969      * @example
8970      *
8971      * var greet = function(greeting, name) {
8972      *   return greeting + ' ' + name;
8973      * };
8974      *
8975      * var greetFred = _.partialRight(greet, 'fred');
8976      * greetFred('hi');
8977      * // => 'hi fred'
8978      *
8979      * // Partially applied with placeholders.
8980      * var sayHelloTo = _.partialRight(greet, 'hello', _);
8981      * sayHelloTo('fred');
8982      * // => 'hello fred'
8983      */
8984     var partialRight = rest(function(func, partials) {
8985       var placeholder = lodash.placeholder || partialRight.placeholder,
8986           holders = replaceHolders(partials, placeholder);
8987
8988       return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
8989     });
8990
8991     /**
8992      * Creates a function that invokes `func` with arguments arranged according
8993      * to the specified indexes where the argument value at the first index is
8994      * provided as the first argument, the argument value at the second index is
8995      * provided as the second argument, and so on.
8996      *
8997      * @static
8998      * @memberOf _
8999      * @category Function
9000      * @param {Function} func The function to rearrange arguments for.
9001      * @param {...(number|number[])} indexes The arranged argument indexes,
9002      *  specified individually or in arrays.
9003      * @returns {Function} Returns the new function.
9004      * @example
9005      *
9006      * var rearged = _.rearg(function(a, b, c) {
9007      *   return [a, b, c];
9008      * }, 2, 0, 1);
9009      *
9010      * rearged('b', 'c', 'a')
9011      * // => ['a', 'b', 'c']
9012      */
9013     var rearg = rest(function(func, indexes) {
9014       return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));
9015     });
9016
9017     /**
9018      * Creates a function that invokes `func` with the `this` binding of the
9019      * created function and arguments from `start` and beyond provided as an array.
9020      *
9021      * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
9022      *
9023      * @static
9024      * @memberOf _
9025      * @category Function
9026      * @param {Function} func The function to apply a rest parameter to.
9027      * @param {number} [start=func.length-1] The start position of the rest parameter.
9028      * @returns {Function} Returns the new function.
9029      * @example
9030      *
9031      * var say = _.rest(function(what, names) {
9032      *   return what + ' ' + _.initial(names).join(', ') +
9033      *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
9034      * });
9035      *
9036      * say('hello', 'fred', 'barney', 'pebbles');
9037      * // => 'hello fred, barney, & pebbles'
9038      */
9039     function rest(func, start) {
9040       if (typeof func != 'function') {
9041         throw new TypeError(FUNC_ERROR_TEXT);
9042       }
9043       start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
9044       return function() {
9045         var args = arguments,
9046             index = -1,
9047             length = nativeMax(args.length - start, 0),
9048             array = Array(length);
9049
9050         while (++index < length) {
9051           array[index] = args[start + index];
9052         }
9053         switch (start) {
9054           case 0: return func.call(this, array);
9055           case 1: return func.call(this, args[0], array);
9056           case 2: return func.call(this, args[0], args[1], array);
9057         }
9058         var otherArgs = Array(start + 1);
9059         index = -1;
9060         while (++index < start) {
9061           otherArgs[index] = args[index];
9062         }
9063         otherArgs[start] = array;
9064         return apply(func, this, otherArgs);
9065       };
9066     }
9067
9068     /**
9069      * Creates a function that invokes `func` with the `this` binding of the created
9070      * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
9071      *
9072      * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator).
9073      *
9074      * @static
9075      * @memberOf _
9076      * @category Function
9077      * @param {Function} func The function to spread arguments over.
9078      * @param {number} [start=0] The start position of the spread.
9079      * @returns {Function} Returns the new function.
9080      * @example
9081      *
9082      * var say = _.spread(function(who, what) {
9083      *   return who + ' says ' + what;
9084      * });
9085      *
9086      * say(['fred', 'hello']);
9087      * // => 'fred says hello'
9088      *
9089      * var numbers = Promise.all([
9090      *   Promise.resolve(40),
9091      *   Promise.resolve(36)
9092      * ]);
9093      *
9094      * numbers.then(_.spread(function(x, y) {
9095      *   return x + y;
9096      * }));
9097      * // => a Promise of 76
9098      */
9099     function spread(func, start) {
9100       if (typeof func != 'function') {
9101         throw new TypeError(FUNC_ERROR_TEXT);
9102       }
9103       start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
9104       return rest(function(args) {
9105         var array = args[start],
9106             otherArgs = args.slice(0, start);
9107
9108         if (array) {
9109           arrayPush(otherArgs, array);
9110         }
9111         return apply(func, this, otherArgs);
9112       });
9113     }
9114
9115     /**
9116      * Creates a throttled function that only invokes `func` at most once per
9117      * every `wait` milliseconds. The throttled function comes with a `cancel`
9118      * method to cancel delayed `func` invocations and a `flush` method to
9119      * immediately invoke them. Provide an options object to indicate whether
9120      * `func` should be invoked on the leading and/or trailing edge of the `wait`
9121      * timeout. The `func` is invoked with the last arguments provided to the
9122      * throttled function. Subsequent calls to the throttled function return the
9123      * result of the last `func` invocation.
9124      *
9125      * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
9126      * on the trailing edge of the timeout only if the throttled function is
9127      * invoked more than once during the `wait` timeout.
9128      *
9129      * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
9130      * for details over the differences between `_.throttle` and `_.debounce`.
9131      *
9132      * @static
9133      * @memberOf _
9134      * @category Function
9135      * @param {Function} func The function to throttle.
9136      * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
9137      * @param {Object} [options] The options object.
9138      * @param {boolean} [options.leading=true] Specify invoking on the leading
9139      *  edge of the timeout.
9140      * @param {boolean} [options.trailing=true] Specify invoking on the trailing
9141      *  edge of the timeout.
9142      * @returns {Function} Returns the new throttled function.
9143      * @example
9144      *
9145      * // Avoid excessively updating the position while scrolling.
9146      * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
9147      *
9148      * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
9149      * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
9150      * jQuery(element).on('click', throttled);
9151      *
9152      * // Cancel the trailing throttled invocation.
9153      * jQuery(window).on('popstate', throttled.cancel);
9154      */
9155     function throttle(func, wait, options) {
9156       var leading = true,
9157           trailing = true;
9158
9159       if (typeof func != 'function') {
9160         throw new TypeError(FUNC_ERROR_TEXT);
9161       }
9162       if (isObject(options)) {
9163         leading = 'leading' in options ? !!options.leading : leading;
9164         trailing = 'trailing' in options ? !!options.trailing : trailing;
9165       }
9166       return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing });
9167     }
9168
9169     /**
9170      * Creates a function that accepts up to one argument, ignoring any
9171      * additional arguments.
9172      *
9173      * @static
9174      * @memberOf _
9175      * @category Function
9176      * @param {Function} func The function to cap arguments for.
9177      * @returns {Function} Returns the new function.
9178      * @example
9179      *
9180      * _.map(['6', '8', '10'], _.unary(parseInt));
9181      * // => [6, 8, 10]
9182      */
9183     function unary(func) {
9184       return ary(func, 1);
9185     }
9186
9187     /**
9188      * Creates a function that provides `value` to the wrapper function as its
9189      * first argument. Any additional arguments provided to the function are
9190      * appended to those provided to the wrapper function. The wrapper is invoked
9191      * with the `this` binding of the created function.
9192      *
9193      * @static
9194      * @memberOf _
9195      * @category Function
9196      * @param {*} value The value to wrap.
9197      * @param {Function} wrapper The wrapper function.
9198      * @returns {Function} Returns the new function.
9199      * @example
9200      *
9201      * var p = _.wrap(_.escape, function(func, text) {
9202      *   return '<p>' + func(text) + '</p>';
9203      * });
9204      *
9205      * p('fred, barney, & pebbles');
9206      * // => '<p>fred, barney, &amp; pebbles</p>'
9207      */
9208     function wrap(value, wrapper) {
9209       wrapper = wrapper == null ? identity : wrapper;
9210       return partial(wrapper, value);
9211     }
9212
9213     /*------------------------------------------------------------------------*/
9214
9215     /**
9216      * Creates a shallow clone of `value`.
9217      *
9218      * **Note:** This method is loosely based on the
9219      * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
9220      * and supports cloning arrays, array buffers, booleans, date objects, maps,
9221      * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
9222      * arrays. The own enumerable properties of `arguments` objects are cloned
9223      * as plain objects. An empty object is returned for uncloneable values such
9224      * as error objects, functions, DOM nodes, and WeakMaps.
9225      *
9226      * @static
9227      * @memberOf _
9228      * @category Lang
9229      * @param {*} value The value to clone.
9230      * @returns {*} Returns the cloned value.
9231      * @example
9232      *
9233      * var objects = [{ 'a': 1 }, { 'b': 2 }];
9234      *
9235      * var shallow = _.clone(objects);
9236      * console.log(shallow[0] === objects[0]);
9237      * // => true
9238      */
9239     function clone(value) {
9240       return baseClone(value);
9241     }
9242
9243     /**
9244      * This method is like `_.clone` except that it accepts `customizer` which
9245      * is invoked to produce the cloned value. If `customizer` returns `undefined`
9246      * cloning is handled by the method instead. The `customizer` is invoked with
9247      * up to four arguments; (value [, index|key, object, stack]).
9248      *
9249      * @static
9250      * @memberOf _
9251      * @category Lang
9252      * @param {*} value The value to clone.
9253      * @param {Function} [customizer] The function to customize cloning.
9254      * @returns {*} Returns the cloned value.
9255      * @example
9256      *
9257      * function customizer(value) {
9258      *   if (_.isElement(value)) {
9259      *     return value.cloneNode(false);
9260      *   }
9261      * }
9262      *
9263      * var el = _.cloneWith(document.body, customizer);
9264      *
9265      * console.log(el === document.body);
9266      * // => false
9267      * console.log(el.nodeName);
9268      * // => 'BODY'
9269      * console.log(el.childNodes.length);
9270      * // => 0
9271      */
9272     function cloneWith(value, customizer) {
9273       return baseClone(value, false, customizer);
9274     }
9275
9276     /**
9277      * This method is like `_.clone` except that it recursively clones `value`.
9278      *
9279      * @static
9280      * @memberOf _
9281      * @category Lang
9282      * @param {*} value The value to recursively clone.
9283      * @returns {*} Returns the deep cloned value.
9284      * @example
9285      *
9286      * var objects = [{ 'a': 1 }, { 'b': 2 }];
9287      *
9288      * var deep = _.cloneDeep(objects);
9289      * console.log(deep[0] === objects[0]);
9290      * // => false
9291      */
9292     function cloneDeep(value) {
9293       return baseClone(value, true);
9294     }
9295
9296     /**
9297      * This method is like `_.cloneWith` except that it recursively clones `value`.
9298      *
9299      * @static
9300      * @memberOf _
9301      * @category Lang
9302      * @param {*} value The value to recursively clone.
9303      * @param {Function} [customizer] The function to customize cloning.
9304      * @returns {*} Returns the deep cloned value.
9305      * @example
9306      *
9307      * function customizer(value) {
9308      *   if (_.isElement(value)) {
9309      *     return value.cloneNode(true);
9310      *   }
9311      * }
9312      *
9313      * var el = _.cloneDeepWith(document.body, customizer);
9314      *
9315      * console.log(el === document.body);
9316      * // => false
9317      * console.log(el.nodeName);
9318      * // => 'BODY'
9319      * console.log(el.childNodes.length);
9320      * // => 20
9321      */
9322     function cloneDeepWith(value, customizer) {
9323       return baseClone(value, true, customizer);
9324     }
9325
9326     /**
9327      * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
9328      * comparison between two values to determine if they are equivalent.
9329      *
9330      * @static
9331      * @memberOf _
9332      * @category Lang
9333      * @param {*} value The value to compare.
9334      * @param {*} other The other value to compare.
9335      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9336      * @example
9337      *
9338      * var object = { 'user': 'fred' };
9339      * var other = { 'user': 'fred' };
9340      *
9341      * _.eq(object, object);
9342      * // => true
9343      *
9344      * _.eq(object, other);
9345      * // => false
9346      *
9347      * _.eq('a', 'a');
9348      * // => true
9349      *
9350      * _.eq('a', Object('a'));
9351      * // => false
9352      *
9353      * _.eq(NaN, NaN);
9354      * // => true
9355      */
9356     function eq(value, other) {
9357       return value === other || (value !== value && other !== other);
9358     }
9359
9360     /**
9361      * Checks if `value` is greater than `other`.
9362      *
9363      * @static
9364      * @memberOf _
9365      * @category Lang
9366      * @param {*} value The value to compare.
9367      * @param {*} other The other value to compare.
9368      * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.
9369      * @example
9370      *
9371      * _.gt(3, 1);
9372      * // => true
9373      *
9374      * _.gt(3, 3);
9375      * // => false
9376      *
9377      * _.gt(1, 3);
9378      * // => false
9379      */
9380     function gt(value, other) {
9381       return value > other;
9382     }
9383
9384     /**
9385      * Checks if `value` is greater than or equal to `other`.
9386      *
9387      * @static
9388      * @memberOf _
9389      * @category Lang
9390      * @param {*} value The value to compare.
9391      * @param {*} other The other value to compare.
9392      * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.
9393      * @example
9394      *
9395      * _.gte(3, 1);
9396      * // => true
9397      *
9398      * _.gte(3, 3);
9399      * // => true
9400      *
9401      * _.gte(1, 3);
9402      * // => false
9403      */
9404     function gte(value, other) {
9405       return value >= other;
9406     }
9407
9408     /**
9409      * Checks if `value` is likely an `arguments` object.
9410      *
9411      * @static
9412      * @memberOf _
9413      * @category Lang
9414      * @param {*} value The value to check.
9415      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9416      * @example
9417      *
9418      * _.isArguments(function() { return arguments; }());
9419      * // => true
9420      *
9421      * _.isArguments([1, 2, 3]);
9422      * // => false
9423      */
9424     function isArguments(value) {
9425       // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
9426       return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
9427         (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
9428     }
9429
9430     /**
9431      * Checks if `value` is classified as an `Array` object.
9432      *
9433      * @static
9434      * @memberOf _
9435      * @type Function
9436      * @category Lang
9437      * @param {*} value The value to check.
9438      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9439      * @example
9440      *
9441      * _.isArray([1, 2, 3]);
9442      * // => true
9443      *
9444      * _.isArray(document.body.children);
9445      * // => false
9446      *
9447      * _.isArray('abc');
9448      * // => false
9449      *
9450      * _.isArray(_.noop);
9451      * // => false
9452      */
9453     var isArray = Array.isArray;
9454
9455     /**
9456      * Checks if `value` is classified as an `ArrayBuffer` object.
9457      *
9458      * @static
9459      * @memberOf _
9460      * @type Function
9461      * @category Lang
9462      * @param {*} value The value to check.
9463      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9464      * @example
9465      *
9466      * _.isArrayBuffer(new ArrayBuffer(2));
9467      * // => true
9468      *
9469      * _.isArrayBuffer(new Array(2));
9470      * // => false
9471      */
9472     function isArrayBuffer(value) {
9473       return isObjectLike(value) && objectToString.call(value) == arrayBufferTag;
9474     }
9475
9476     /**
9477      * Checks if `value` is array-like. A value is considered array-like if it's
9478      * not a function and has a `value.length` that's an integer greater than or
9479      * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
9480      *
9481      * @static
9482      * @memberOf _
9483      * @type Function
9484      * @category Lang
9485      * @param {*} value The value to check.
9486      * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
9487      * @example
9488      *
9489      * _.isArrayLike([1, 2, 3]);
9490      * // => true
9491      *
9492      * _.isArrayLike(document.body.children);
9493      * // => true
9494      *
9495      * _.isArrayLike('abc');
9496      * // => true
9497      *
9498      * _.isArrayLike(_.noop);
9499      * // => false
9500      */
9501     function isArrayLike(value) {
9502       return value != null &&
9503         !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
9504     }
9505
9506     /**
9507      * This method is like `_.isArrayLike` except that it also checks if `value`
9508      * is an object.
9509      *
9510      * @static
9511      * @memberOf _
9512      * @type Function
9513      * @category Lang
9514      * @param {*} value The value to check.
9515      * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
9516      * @example
9517      *
9518      * _.isArrayLikeObject([1, 2, 3]);
9519      * // => true
9520      *
9521      * _.isArrayLikeObject(document.body.children);
9522      * // => true
9523      *
9524      * _.isArrayLikeObject('abc');
9525      * // => false
9526      *
9527      * _.isArrayLikeObject(_.noop);
9528      * // => false
9529      */
9530     function isArrayLikeObject(value) {
9531       return isObjectLike(value) && isArrayLike(value);
9532     }
9533
9534     /**
9535      * Checks if `value` is classified as a boolean primitive or object.
9536      *
9537      * @static
9538      * @memberOf _
9539      * @category Lang
9540      * @param {*} value The value to check.
9541      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9542      * @example
9543      *
9544      * _.isBoolean(false);
9545      * // => true
9546      *
9547      * _.isBoolean(null);
9548      * // => false
9549      */
9550     function isBoolean(value) {
9551       return value === true || value === false ||
9552         (isObjectLike(value) && objectToString.call(value) == boolTag);
9553     }
9554
9555     /**
9556      * Checks if `value` is a buffer.
9557      *
9558      * @static
9559      * @memberOf _
9560      * @category Lang
9561      * @param {*} value The value to check.
9562      * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
9563      * @example
9564      *
9565      * _.isBuffer(new Buffer(2));
9566      * // => true
9567      *
9568      * _.isBuffer(new Uint8Array(2));
9569      * // => false
9570      */
9571     var isBuffer = !Buffer ? constant(false) : function(value) {
9572       return value instanceof Buffer;
9573     };
9574
9575     /**
9576      * Checks if `value` is classified as a `Date` object.
9577      *
9578      * @static
9579      * @memberOf _
9580      * @category Lang
9581      * @param {*} value The value to check.
9582      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9583      * @example
9584      *
9585      * _.isDate(new Date);
9586      * // => true
9587      *
9588      * _.isDate('Mon April 23 2012');
9589      * // => false
9590      */
9591     function isDate(value) {
9592       return isObjectLike(value) && objectToString.call(value) == dateTag;
9593     }
9594
9595     /**
9596      * Checks if `value` is likely a DOM element.
9597      *
9598      * @static
9599      * @memberOf _
9600      * @category Lang
9601      * @param {*} value The value to check.
9602      * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
9603      * @example
9604      *
9605      * _.isElement(document.body);
9606      * // => true
9607      *
9608      * _.isElement('<body>');
9609      * // => false
9610      */
9611     function isElement(value) {
9612       return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
9613     }
9614
9615     /**
9616      * Checks if `value` is empty. A value is considered empty unless it's an
9617      * `arguments` object, array, string, or jQuery-like collection with a length
9618      * greater than `0` or an object with own enumerable properties.
9619      *
9620      * @static
9621      * @memberOf _
9622      * @category Lang
9623      * @param {Array|Object|string} value The value to inspect.
9624      * @returns {boolean} Returns `true` if `value` is empty, else `false`.
9625      * @example
9626      *
9627      * _.isEmpty(null);
9628      * // => true
9629      *
9630      * _.isEmpty(true);
9631      * // => true
9632      *
9633      * _.isEmpty(1);
9634      * // => true
9635      *
9636      * _.isEmpty([1, 2, 3]);
9637      * // => false
9638      *
9639      * _.isEmpty({ 'a': 1 });
9640      * // => false
9641      */
9642     function isEmpty(value) {
9643       if (isArrayLike(value) &&
9644           (isArray(value) || isString(value) || isFunction(value.splice) || isArguments(value))) {
9645         return !value.length;
9646       }
9647       for (var key in value) {
9648         if (hasOwnProperty.call(value, key)) {
9649           return false;
9650         }
9651       }
9652       return true;
9653     }
9654
9655     /**
9656      * Performs a deep comparison between two values to determine if they are
9657      * equivalent.
9658      *
9659      * **Note:** This method supports comparing arrays, array buffers, booleans,
9660      * date objects, error objects, maps, numbers, `Object` objects, regexes,
9661      * sets, strings, symbols, and typed arrays. `Object` objects are compared
9662      * by their own, not inherited, enumerable properties. Functions and DOM
9663      * nodes are **not** supported.
9664      *
9665      * @static
9666      * @memberOf _
9667      * @category Lang
9668      * @param {*} value The value to compare.
9669      * @param {*} other The other value to compare.
9670      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9671      * @example
9672      *
9673      * var object = { 'user': 'fred' };
9674      * var other = { 'user': 'fred' };
9675      *
9676      * _.isEqual(object, other);
9677      * // => true
9678      *
9679      * object === other;
9680      * // => false
9681      */
9682     function isEqual(value, other) {
9683       return baseIsEqual(value, other);
9684     }
9685
9686     /**
9687      * This method is like `_.isEqual` except that it accepts `customizer` which is
9688      * invoked to compare values. If `customizer` returns `undefined` comparisons are
9689      * handled by the method instead. The `customizer` is invoked with up to six arguments:
9690      * (objValue, othValue [, index|key, object, other, stack]).
9691      *
9692      * @static
9693      * @memberOf _
9694      * @category Lang
9695      * @param {*} value The value to compare.
9696      * @param {*} other The other value to compare.
9697      * @param {Function} [customizer] The function to customize comparisons.
9698      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9699      * @example
9700      *
9701      * function isGreeting(value) {
9702      *   return /^h(?:i|ello)$/.test(value);
9703      * }
9704      *
9705      * function customizer(objValue, othValue) {
9706      *   if (isGreeting(objValue) && isGreeting(othValue)) {
9707      *     return true;
9708      *   }
9709      * }
9710      *
9711      * var array = ['hello', 'goodbye'];
9712      * var other = ['hi', 'goodbye'];
9713      *
9714      * _.isEqualWith(array, other, customizer);
9715      * // => true
9716      */
9717     function isEqualWith(value, other, customizer) {
9718       customizer = typeof customizer == 'function' ? customizer : undefined;
9719       var result = customizer ? customizer(value, other) : undefined;
9720       return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
9721     }
9722
9723     /**
9724      * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
9725      * `SyntaxError`, `TypeError`, or `URIError` object.
9726      *
9727      * @static
9728      * @memberOf _
9729      * @category Lang
9730      * @param {*} value The value to check.
9731      * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
9732      * @example
9733      *
9734      * _.isError(new Error);
9735      * // => true
9736      *
9737      * _.isError(Error);
9738      * // => false
9739      */
9740     function isError(value) {
9741       return isObjectLike(value) &&
9742         typeof value.message == 'string' && objectToString.call(value) == errorTag;
9743     }
9744
9745     /**
9746      * Checks if `value` is a finite primitive number.
9747      *
9748      * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite).
9749      *
9750      * @static
9751      * @memberOf _
9752      * @category Lang
9753      * @param {*} value The value to check.
9754      * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
9755      * @example
9756      *
9757      * _.isFinite(3);
9758      * // => true
9759      *
9760      * _.isFinite(Number.MAX_VALUE);
9761      * // => true
9762      *
9763      * _.isFinite(3.14);
9764      * // => true
9765      *
9766      * _.isFinite(Infinity);
9767      * // => false
9768      */
9769     function isFinite(value) {
9770       return typeof value == 'number' && nativeIsFinite(value);
9771     }
9772
9773     /**
9774      * Checks if `value` is classified as a `Function` object.
9775      *
9776      * @static
9777      * @memberOf _
9778      * @category Lang
9779      * @param {*} value The value to check.
9780      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9781      * @example
9782      *
9783      * _.isFunction(_);
9784      * // => true
9785      *
9786      * _.isFunction(/abc/);
9787      * // => false
9788      */
9789     function isFunction(value) {
9790       // The use of `Object#toString` avoids issues with the `typeof` operator
9791       // in Safari 8 which returns 'object' for typed array constructors, and
9792       // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
9793       var tag = isObject(value) ? objectToString.call(value) : '';
9794       return tag == funcTag || tag == genTag;
9795     }
9796
9797     /**
9798      * Checks if `value` is an integer.
9799      *
9800      * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger).
9801      *
9802      * @static
9803      * @memberOf _
9804      * @category Lang
9805      * @param {*} value The value to check.
9806      * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
9807      * @example
9808      *
9809      * _.isInteger(3);
9810      * // => true
9811      *
9812      * _.isInteger(Number.MIN_VALUE);
9813      * // => false
9814      *
9815      * _.isInteger(Infinity);
9816      * // => false
9817      *
9818      * _.isInteger('3');
9819      * // => false
9820      */
9821     function isInteger(value) {
9822       return typeof value == 'number' && value == toInteger(value);
9823     }
9824
9825     /**
9826      * Checks if `value` is a valid array-like length.
9827      *
9828      * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
9829      *
9830      * @static
9831      * @memberOf _
9832      * @category Lang
9833      * @param {*} value The value to check.
9834      * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
9835      * @example
9836      *
9837      * _.isLength(3);
9838      * // => true
9839      *
9840      * _.isLength(Number.MIN_VALUE);
9841      * // => false
9842      *
9843      * _.isLength(Infinity);
9844      * // => false
9845      *
9846      * _.isLength('3');
9847      * // => false
9848      */
9849     function isLength(value) {
9850       return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
9851     }
9852
9853     /**
9854      * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
9855      * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
9856      *
9857      * @static
9858      * @memberOf _
9859      * @category Lang
9860      * @param {*} value The value to check.
9861      * @returns {boolean} Returns `true` if `value` is an object, else `false`.
9862      * @example
9863      *
9864      * _.isObject({});
9865      * // => true
9866      *
9867      * _.isObject([1, 2, 3]);
9868      * // => true
9869      *
9870      * _.isObject(_.noop);
9871      * // => true
9872      *
9873      * _.isObject(null);
9874      * // => false
9875      */
9876     function isObject(value) {
9877       var type = typeof value;
9878       return !!value && (type == 'object' || type == 'function');
9879     }
9880
9881     /**
9882      * Checks if `value` is object-like. A value is object-like if it's not `null`
9883      * and has a `typeof` result of "object".
9884      *
9885      * @static
9886      * @memberOf _
9887      * @category Lang
9888      * @param {*} value The value to check.
9889      * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
9890      * @example
9891      *
9892      * _.isObjectLike({});
9893      * // => true
9894      *
9895      * _.isObjectLike([1, 2, 3]);
9896      * // => true
9897      *
9898      * _.isObjectLike(_.noop);
9899      * // => false
9900      *
9901      * _.isObjectLike(null);
9902      * // => false
9903      */
9904     function isObjectLike(value) {
9905       return !!value && typeof value == 'object';
9906     }
9907
9908     /**
9909      * Checks if `value` is classified as a `Map` object.
9910      *
9911      * @static
9912      * @memberOf _
9913      * @category Lang
9914      * @param {*} value The value to check.
9915      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9916      * @example
9917      *
9918      * _.isMap(new Map);
9919      * // => true
9920      *
9921      * _.isMap(new WeakMap);
9922      * // => false
9923      */
9924     function isMap(value) {
9925       return isObjectLike(value) && getTag(value) == mapTag;
9926     }
9927
9928     /**
9929      * Performs a deep comparison between `object` and `source` to determine if
9930      * `object` contains equivalent property values.
9931      *
9932      * **Note:** This method supports comparing the same values as `_.isEqual`.
9933      *
9934      * @static
9935      * @memberOf _
9936      * @category Lang
9937      * @param {Object} object The object to inspect.
9938      * @param {Object} source The object of property values to match.
9939      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
9940      * @example
9941      *
9942      * var object = { 'user': 'fred', 'age': 40 };
9943      *
9944      * _.isMatch(object, { 'age': 40 });
9945      * // => true
9946      *
9947      * _.isMatch(object, { 'age': 36 });
9948      * // => false
9949      */
9950     function isMatch(object, source) {
9951       return object === source || baseIsMatch(object, source, getMatchData(source));
9952     }
9953
9954     /**
9955      * This method is like `_.isMatch` except that it accepts `customizer` which
9956      * is invoked to compare values. If `customizer` returns `undefined` comparisons
9957      * are handled by the method instead. The `customizer` is invoked with five
9958      * arguments: (objValue, srcValue, index|key, object, source).
9959      *
9960      * @static
9961      * @memberOf _
9962      * @category Lang
9963      * @param {Object} object The object to inspect.
9964      * @param {Object} source The object of property values to match.
9965      * @param {Function} [customizer] The function to customize comparisons.
9966      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
9967      * @example
9968      *
9969      * function isGreeting(value) {
9970      *   return /^h(?:i|ello)$/.test(value);
9971      * }
9972      *
9973      * function customizer(objValue, srcValue) {
9974      *   if (isGreeting(objValue) && isGreeting(srcValue)) {
9975      *     return true;
9976      *   }
9977      * }
9978      *
9979      * var object = { 'greeting': 'hello' };
9980      * var source = { 'greeting': 'hi' };
9981      *
9982      * _.isMatchWith(object, source, customizer);
9983      * // => true
9984      */
9985     function isMatchWith(object, source, customizer) {
9986       customizer = typeof customizer == 'function' ? customizer : undefined;
9987       return baseIsMatch(object, source, getMatchData(source), customizer);
9988     }
9989
9990     /**
9991      * Checks if `value` is `NaN`.
9992      *
9993      * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)
9994      * which returns `true` for `undefined` and other non-numeric values.
9995      *
9996      * @static
9997      * @memberOf _
9998      * @category Lang
9999      * @param {*} value The value to check.
10000      * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
10001      * @example
10002      *
10003      * _.isNaN(NaN);
10004      * // => true
10005      *
10006      * _.isNaN(new Number(NaN));
10007      * // => true
10008      *
10009      * isNaN(undefined);
10010      * // => true
10011      *
10012      * _.isNaN(undefined);
10013      * // => false
10014      */
10015     function isNaN(value) {
10016       // An `NaN` primitive is the only value that is not equal to itself.
10017       // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE.
10018       return isNumber(value) && value != +value;
10019     }
10020
10021     /**
10022      * Checks if `value` is a native function.
10023      *
10024      * @static
10025      * @memberOf _
10026      * @category Lang
10027      * @param {*} value The value to check.
10028      * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
10029      * @example
10030      *
10031      * _.isNative(Array.prototype.push);
10032      * // => true
10033      *
10034      * _.isNative(_);
10035      * // => false
10036      */
10037     function isNative(value) {
10038       if (value == null) {
10039         return false;
10040       }
10041       if (isFunction(value)) {
10042         return reIsNative.test(funcToString.call(value));
10043       }
10044       return isObjectLike(value) &&
10045         (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
10046     }
10047
10048     /**
10049      * Checks if `value` is `null`.
10050      *
10051      * @static
10052      * @memberOf _
10053      * @category Lang
10054      * @param {*} value The value to check.
10055      * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
10056      * @example
10057      *
10058      * _.isNull(null);
10059      * // => true
10060      *
10061      * _.isNull(void 0);
10062      * // => false
10063      */
10064     function isNull(value) {
10065       return value === null;
10066     }
10067
10068     /**
10069      * Checks if `value` is `null` or `undefined`.
10070      *
10071      * @static
10072      * @memberOf _
10073      * @category Lang
10074      * @param {*} value The value to check.
10075      * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
10076      * @example
10077      *
10078      * _.isNil(null);
10079      * // => true
10080      *
10081      * _.isNil(void 0);
10082      * // => true
10083      *
10084      * _.isNil(NaN);
10085      * // => false
10086      */
10087     function isNil(value) {
10088       return value == null;
10089     }
10090
10091     /**
10092      * Checks if `value` is classified as a `Number` primitive or object.
10093      *
10094      * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
10095      * as numbers, use the `_.isFinite` method.
10096      *
10097      * @static
10098      * @memberOf _
10099      * @category Lang
10100      * @param {*} value The value to check.
10101      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10102      * @example
10103      *
10104      * _.isNumber(3);
10105      * // => true
10106      *
10107      * _.isNumber(Number.MIN_VALUE);
10108      * // => true
10109      *
10110      * _.isNumber(Infinity);
10111      * // => true
10112      *
10113      * _.isNumber('3');
10114      * // => false
10115      */
10116     function isNumber(value) {
10117       return typeof value == 'number' ||
10118         (isObjectLike(value) && objectToString.call(value) == numberTag);
10119     }
10120
10121     /**
10122      * Checks if `value` is a plain object, that is, an object created by the
10123      * `Object` constructor or one with a `[[Prototype]]` of `null`.
10124      *
10125      * @static
10126      * @memberOf _
10127      * @category Lang
10128      * @param {*} value The value to check.
10129      * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
10130      * @example
10131      *
10132      * function Foo() {
10133      *   this.a = 1;
10134      * }
10135      *
10136      * _.isPlainObject(new Foo);
10137      * // => false
10138      *
10139      * _.isPlainObject([1, 2, 3]);
10140      * // => false
10141      *
10142      * _.isPlainObject({ 'x': 0, 'y': 0 });
10143      * // => true
10144      *
10145      * _.isPlainObject(Object.create(null));
10146      * // => true
10147      */
10148     function isPlainObject(value) {
10149       if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) {
10150         return false;
10151       }
10152       var proto = objectProto;
10153       if (typeof value.constructor == 'function') {
10154         proto = getPrototypeOf(value);
10155       }
10156       if (proto === null) {
10157         return true;
10158       }
10159       var Ctor = proto.constructor;
10160       return (typeof Ctor == 'function' &&
10161         Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
10162     }
10163
10164     /**
10165      * Checks if `value` is classified as a `RegExp` object.
10166      *
10167      * @static
10168      * @memberOf _
10169      * @category Lang
10170      * @param {*} value The value to check.
10171      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10172      * @example
10173      *
10174      * _.isRegExp(/abc/);
10175      * // => true
10176      *
10177      * _.isRegExp('/abc/');
10178      * // => false
10179      */
10180     function isRegExp(value) {
10181       return isObject(value) && objectToString.call(value) == regexpTag;
10182     }
10183
10184     /**
10185      * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
10186      * double precision number which isn't the result of a rounded unsafe integer.
10187      *
10188      * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
10189      *
10190      * @static
10191      * @memberOf _
10192      * @category Lang
10193      * @param {*} value The value to check.
10194      * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
10195      * @example
10196      *
10197      * _.isSafeInteger(3);
10198      * // => true
10199      *
10200      * _.isSafeInteger(Number.MIN_VALUE);
10201      * // => false
10202      *
10203      * _.isSafeInteger(Infinity);
10204      * // => false
10205      *
10206      * _.isSafeInteger('3');
10207      * // => false
10208      */
10209     function isSafeInteger(value) {
10210       return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
10211     }
10212
10213     /**
10214      * Checks if `value` is classified as a `Set` object.
10215      *
10216      * @static
10217      * @memberOf _
10218      * @category Lang
10219      * @param {*} value The value to check.
10220      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10221      * @example
10222      *
10223      * _.isSet(new Set);
10224      * // => true
10225      *
10226      * _.isSet(new WeakSet);
10227      * // => false
10228      */
10229     function isSet(value) {
10230       return isObjectLike(value) && getTag(value) == setTag;
10231     }
10232
10233     /**
10234      * Checks if `value` is classified as a `String` primitive or object.
10235      *
10236      * @static
10237      * @memberOf _
10238      * @category Lang
10239      * @param {*} value The value to check.
10240      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10241      * @example
10242      *
10243      * _.isString('abc');
10244      * // => true
10245      *
10246      * _.isString(1);
10247      * // => false
10248      */
10249     function isString(value) {
10250       return typeof value == 'string' ||
10251         (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
10252     }
10253
10254     /**
10255      * Checks if `value` is classified as a `Symbol` primitive or object.
10256      *
10257      * @static
10258      * @memberOf _
10259      * @category Lang
10260      * @param {*} value The value to check.
10261      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10262      * @example
10263      *
10264      * _.isSymbol(Symbol.iterator);
10265      * // => true
10266      *
10267      * _.isSymbol('abc');
10268      * // => false
10269      */
10270     function isSymbol(value) {
10271       return typeof value == 'symbol' ||
10272         (isObjectLike(value) && objectToString.call(value) == symbolTag);
10273     }
10274
10275     /**
10276      * Checks if `value` is classified as a typed array.
10277      *
10278      * @static
10279      * @memberOf _
10280      * @category Lang
10281      * @param {*} value The value to check.
10282      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10283      * @example
10284      *
10285      * _.isTypedArray(new Uint8Array);
10286      * // => true
10287      *
10288      * _.isTypedArray([]);
10289      * // => false
10290      */
10291     function isTypedArray(value) {
10292       return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
10293     }
10294
10295     /**
10296      * Checks if `value` is `undefined`.
10297      *
10298      * @static
10299      * @memberOf _
10300      * @category Lang
10301      * @param {*} value The value to check.
10302      * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
10303      * @example
10304      *
10305      * _.isUndefined(void 0);
10306      * // => true
10307      *
10308      * _.isUndefined(null);
10309      * // => false
10310      */
10311     function isUndefined(value) {
10312       return value === undefined;
10313     }
10314
10315     /**
10316      * Checks if `value` is classified as a `WeakMap` object.
10317      *
10318      * @static
10319      * @memberOf _
10320      * @category Lang
10321      * @param {*} value The value to check.
10322      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10323      * @example
10324      *
10325      * _.isWeakMap(new WeakMap);
10326      * // => true
10327      *
10328      * _.isWeakMap(new Map);
10329      * // => false
10330      */
10331     function isWeakMap(value) {
10332       return isObjectLike(value) && getTag(value) == weakMapTag;
10333     }
10334
10335     /**
10336      * Checks if `value` is classified as a `WeakSet` object.
10337      *
10338      * @static
10339      * @memberOf _
10340      * @category Lang
10341      * @param {*} value The value to check.
10342      * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10343      * @example
10344      *
10345      * _.isWeakSet(new WeakSet);
10346      * // => true
10347      *
10348      * _.isWeakSet(new Set);
10349      * // => false
10350      */
10351     function isWeakSet(value) {
10352       return isObjectLike(value) && objectToString.call(value) == weakSetTag;
10353     }
10354
10355     /**
10356      * Checks if `value` is less than `other`.
10357      *
10358      * @static
10359      * @memberOf _
10360      * @category Lang
10361      * @param {*} value The value to compare.
10362      * @param {*} other The other value to compare.
10363      * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
10364      * @example
10365      *
10366      * _.lt(1, 3);
10367      * // => true
10368      *
10369      * _.lt(3, 3);
10370      * // => false
10371      *
10372      * _.lt(3, 1);
10373      * // => false
10374      */
10375     function lt(value, other) {
10376       return value < other;
10377     }
10378
10379     /**
10380      * Checks if `value` is less than or equal to `other`.
10381      *
10382      * @static
10383      * @memberOf _
10384      * @category Lang
10385      * @param {*} value The value to compare.
10386      * @param {*} other The other value to compare.
10387      * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.
10388      * @example
10389      *
10390      * _.lte(1, 3);
10391      * // => true
10392      *
10393      * _.lte(3, 3);
10394      * // => true
10395      *
10396      * _.lte(3, 1);
10397      * // => false
10398      */
10399     function lte(value, other) {
10400       return value <= other;
10401     }
10402
10403     /**
10404      * Converts `value` to an array.
10405      *
10406      * @static
10407      * @memberOf _
10408      * @category Lang
10409      * @param {*} value The value to convert.
10410      * @returns {Array} Returns the converted array.
10411      * @example
10412      *
10413      * _.toArray({ 'a': 1, 'b': 2 });
10414      * // => [1, 2]
10415      *
10416      * _.toArray('abc');
10417      * // => ['a', 'b', 'c']
10418      *
10419      * _.toArray(1);
10420      * // => []
10421      *
10422      * _.toArray(null);
10423      * // => []
10424      */
10425     function toArray(value) {
10426       if (!value) {
10427         return [];
10428       }
10429       if (isArrayLike(value)) {
10430         return isString(value) ? stringToArray(value) : copyArray(value);
10431       }
10432       if (iteratorSymbol && value[iteratorSymbol]) {
10433         return iteratorToArray(value[iteratorSymbol]());
10434       }
10435       var tag = getTag(value),
10436           func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
10437
10438       return func(value);
10439     }
10440
10441     /**
10442      * Converts `value` to an integer.
10443      *
10444      * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
10445      *
10446      * @static
10447      * @memberOf _
10448      * @category Lang
10449      * @param {*} value The value to convert.
10450      * @returns {number} Returns the converted integer.
10451      * @example
10452      *
10453      * _.toInteger(3);
10454      * // => 3
10455      *
10456      * _.toInteger(Number.MIN_VALUE);
10457      * // => 0
10458      *
10459      * _.toInteger(Infinity);
10460      * // => 1.7976931348623157e+308
10461      *
10462      * _.toInteger('3');
10463      * // => 3
10464      */
10465     function toInteger(value) {
10466       if (!value) {
10467         return value === 0 ? value : 0;
10468       }
10469       value = toNumber(value);
10470       if (value === INFINITY || value === -INFINITY) {
10471         var sign = (value < 0 ? -1 : 1);
10472         return sign * MAX_INTEGER;
10473       }
10474       var remainder = value % 1;
10475       return value === value ? (remainder ? value - remainder : value) : 0;
10476     }
10477
10478     /**
10479      * Converts `value` to an integer suitable for use as the length of an
10480      * array-like object.
10481      *
10482      * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
10483      *
10484      * @static
10485      * @memberOf _
10486      * @category Lang
10487      * @param {*} value The value to convert.
10488      * @returns {number} Returns the converted integer.
10489      * @example
10490      *
10491      * _.toLength(3);
10492      * // => 3
10493      *
10494      * _.toLength(Number.MIN_VALUE);
10495      * // => 0
10496      *
10497      * _.toLength(Infinity);
10498      * // => 4294967295
10499      *
10500      * _.toLength('3');
10501      * // => 3
10502      */
10503     function toLength(value) {
10504       return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
10505     }
10506
10507     /**
10508      * Converts `value` to a number.
10509      *
10510      * @static
10511      * @memberOf _
10512      * @category Lang
10513      * @param {*} value The value to process.
10514      * @returns {number} Returns the number.
10515      * @example
10516      *
10517      * _.toNumber(3);
10518      * // => 3
10519      *
10520      * _.toNumber(Number.MIN_VALUE);
10521      * // => 5e-324
10522      *
10523      * _.toNumber(Infinity);
10524      * // => Infinity
10525      *
10526      * _.toNumber('3');
10527      * // => 3
10528      */
10529     function toNumber(value) {
10530       if (isObject(value)) {
10531         var other = isFunction(value.valueOf) ? value.valueOf() : value;
10532         value = isObject(other) ? (other + '') : other;
10533       }
10534       if (typeof value != 'string') {
10535         return value === 0 ? value : +value;
10536       }
10537       value = value.replace(reTrim, '');
10538       var isBinary = reIsBinary.test(value);
10539       return (isBinary || reIsOctal.test(value))
10540         ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
10541         : (reIsBadHex.test(value) ? NAN : +value);
10542     }
10543
10544     /**
10545      * Converts `value` to a plain object flattening inherited enumerable
10546      * properties of `value` to own properties of the plain object.
10547      *
10548      * @static
10549      * @memberOf _
10550      * @category Lang
10551      * @param {*} value The value to convert.
10552      * @returns {Object} Returns the converted plain object.
10553      * @example
10554      *
10555      * function Foo() {
10556      *   this.b = 2;
10557      * }
10558      *
10559      * Foo.prototype.c = 3;
10560      *
10561      * _.assign({ 'a': 1 }, new Foo);
10562      * // => { 'a': 1, 'b': 2 }
10563      *
10564      * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
10565      * // => { 'a': 1, 'b': 2, 'c': 3 }
10566      */
10567     function toPlainObject(value) {
10568       return copyObject(value, keysIn(value));
10569     }
10570
10571     /**
10572      * Converts `value` to a safe integer. A safe integer can be compared and
10573      * represented correctly.
10574      *
10575      * @static
10576      * @memberOf _
10577      * @category Lang
10578      * @param {*} value The value to convert.
10579      * @returns {number} Returns the converted integer.
10580      * @example
10581      *
10582      * _.toSafeInteger(3);
10583      * // => 3
10584      *
10585      * _.toSafeInteger(Number.MIN_VALUE);
10586      * // => 0
10587      *
10588      * _.toSafeInteger(Infinity);
10589      * // => 9007199254740991
10590      *
10591      * _.toSafeInteger('3');
10592      * // => 3
10593      */
10594     function toSafeInteger(value) {
10595       return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
10596     }
10597
10598     /**
10599      * Converts `value` to a string if it's not one. An empty string is returned
10600      * for `null` and `undefined` values. The sign of `-0` is preserved.
10601      *
10602      * @static
10603      * @memberOf _
10604      * @category Lang
10605      * @param {*} value The value to process.
10606      * @returns {string} Returns the string.
10607      * @example
10608      *
10609      * _.toString(null);
10610      * // => ''
10611      *
10612      * _.toString(-0);
10613      * // => '-0'
10614      *
10615      * _.toString([1, 2, 3]);
10616      * // => '1,2,3'
10617      */
10618     function toString(value) {
10619       // Exit early for strings to avoid a performance hit in some environments.
10620       if (typeof value == 'string') {
10621         return value;
10622       }
10623       if (value == null) {
10624         return '';
10625       }
10626       if (isSymbol(value)) {
10627         return Symbol ? symbolToString.call(value) : '';
10628       }
10629       var result = (value + '');
10630       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
10631     }
10632
10633     /*------------------------------------------------------------------------*/
10634
10635     /**
10636      * Assigns own enumerable properties of source objects to the destination
10637      * object. Source objects are applied from left to right. Subsequent sources
10638      * overwrite property assignments of previous sources.
10639      *
10640      * **Note:** This method mutates `object` and is loosely based on
10641      * [`Object.assign`](https://mdn.io/Object/assign).
10642      *
10643      * @static
10644      * @memberOf _
10645      * @category Object
10646      * @param {Object} object The destination object.
10647      * @param {...Object} [sources] The source objects.
10648      * @returns {Object} Returns `object`.
10649      * @example
10650      *
10651      * function Foo() {
10652      *   this.c = 3;
10653      * }
10654      *
10655      * function Bar() {
10656      *   this.e = 5;
10657      * }
10658      *
10659      * Foo.prototype.d = 4;
10660      * Bar.prototype.f = 6;
10661      *
10662      * _.assign({ 'a': 1 }, new Foo, new Bar);
10663      * // => { 'a': 1, 'c': 3, 'e': 5 }
10664      */
10665     var assign = createAssigner(function(object, source) {
10666       copyObject(source, keys(source), object);
10667     });
10668
10669     /**
10670      * This method is like `_.assign` except that it iterates over own and
10671      * inherited source properties.
10672      *
10673      * **Note:** This method mutates `object`.
10674      *
10675      * @static
10676      * @memberOf _
10677      * @alias extend
10678      * @category Object
10679      * @param {Object} object The destination object.
10680      * @param {...Object} [sources] The source objects.
10681      * @returns {Object} Returns `object`.
10682      * @example
10683      *
10684      * function Foo() {
10685      *   this.b = 2;
10686      * }
10687      *
10688      * function Bar() {
10689      *   this.d = 4;
10690      * }
10691      *
10692      * Foo.prototype.c = 3;
10693      * Bar.prototype.e = 5;
10694      *
10695      * _.assignIn({ 'a': 1 }, new Foo, new Bar);
10696      * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
10697      */
10698     var assignIn = createAssigner(function(object, source) {
10699       copyObject(source, keysIn(source), object);
10700     });
10701
10702     /**
10703      * This method is like `_.assignIn` except that it accepts `customizer` which
10704      * is invoked to produce the assigned values. If `customizer` returns `undefined`
10705      * assignment is handled by the method instead. The `customizer` is invoked
10706      * with five arguments: (objValue, srcValue, key, object, source).
10707      *
10708      * **Note:** This method mutates `object`.
10709      *
10710      * @static
10711      * @memberOf _
10712      * @alias extendWith
10713      * @category Object
10714      * @param {Object} object The destination object.
10715      * @param {...Object} sources The source objects.
10716      * @param {Function} [customizer] The function to customize assigned values.
10717      * @returns {Object} Returns `object`.
10718      * @example
10719      *
10720      * function customizer(objValue, srcValue) {
10721      *   return _.isUndefined(objValue) ? srcValue : objValue;
10722      * }
10723      *
10724      * var defaults = _.partialRight(_.assignInWith, customizer);
10725      *
10726      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10727      * // => { 'a': 1, 'b': 2 }
10728      */
10729     var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
10730       copyObjectWith(source, keysIn(source), object, customizer);
10731     });
10732
10733     /**
10734      * This method is like `_.assign` except that it accepts `customizer` which
10735      * is invoked to produce the assigned values. If `customizer` returns `undefined`
10736      * assignment is handled by the method instead. The `customizer` is invoked
10737      * with five arguments: (objValue, srcValue, key, object, source).
10738      *
10739      * **Note:** This method mutates `object`.
10740      *
10741      * @static
10742      * @memberOf _
10743      * @category Object
10744      * @param {Object} object The destination object.
10745      * @param {...Object} sources The source objects.
10746      * @param {Function} [customizer] The function to customize assigned values.
10747      * @returns {Object} Returns `object`.
10748      * @example
10749      *
10750      * function customizer(objValue, srcValue) {
10751      *   return _.isUndefined(objValue) ? srcValue : objValue;
10752      * }
10753      *
10754      * var defaults = _.partialRight(_.assignWith, customizer);
10755      *
10756      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10757      * // => { 'a': 1, 'b': 2 }
10758      */
10759     var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
10760       copyObjectWith(source, keys(source), object, customizer);
10761     });
10762
10763     /**
10764      * Creates an array of values corresponding to `paths` of `object`.
10765      *
10766      * @static
10767      * @memberOf _
10768      * @category Object
10769      * @param {Object} object The object to iterate over.
10770      * @param {...(string|string[])} [paths] The property paths of elements to pick,
10771      *  specified individually or in arrays.
10772      * @returns {Array} Returns the new array of picked elements.
10773      * @example
10774      *
10775      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
10776      *
10777      * _.at(object, ['a[0].b.c', 'a[1]']);
10778      * // => [3, 4]
10779      *
10780      * _.at(['a', 'b', 'c'], 0, 2);
10781      * // => ['a', 'c']
10782      */
10783     var at = rest(function(object, paths) {
10784       return baseAt(object, baseFlatten(paths));
10785     });
10786
10787     /**
10788      * Creates an object that inherits from the `prototype` object. If a `properties`
10789      * object is given its own enumerable properties are assigned to the created object.
10790      *
10791      * @static
10792      * @memberOf _
10793      * @category Object
10794      * @param {Object} prototype The object to inherit from.
10795      * @param {Object} [properties] The properties to assign to the object.
10796      * @returns {Object} Returns the new object.
10797      * @example
10798      *
10799      * function Shape() {
10800      *   this.x = 0;
10801      *   this.y = 0;
10802      * }
10803      *
10804      * function Circle() {
10805      *   Shape.call(this);
10806      * }
10807      *
10808      * Circle.prototype = _.create(Shape.prototype, {
10809      *   'constructor': Circle
10810      * });
10811      *
10812      * var circle = new Circle;
10813      * circle instanceof Circle;
10814      * // => true
10815      *
10816      * circle instanceof Shape;
10817      * // => true
10818      */
10819     function create(prototype, properties) {
10820       var result = baseCreate(prototype);
10821       return properties ? baseAssign(result, properties) : result;
10822     }
10823
10824     /**
10825      * Assigns own and inherited enumerable properties of source objects to the
10826      * destination object for all destination properties that resolve to `undefined`.
10827      * Source objects are applied from left to right. Once a property is set,
10828      * additional values of the same property are ignored.
10829      *
10830      * **Note:** This method mutates `object`.
10831      *
10832      * @static
10833      * @memberOf _
10834      * @category Object
10835      * @param {Object} object The destination object.
10836      * @param {...Object} [sources] The source objects.
10837      * @returns {Object} Returns `object`.
10838      * @example
10839      *
10840      * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
10841      * // => { 'user': 'barney', 'age': 36 }
10842      */
10843     var defaults = rest(function(args) {
10844       args.push(undefined, assignInDefaults);
10845       return apply(assignInWith, undefined, args);
10846     });
10847
10848     /**
10849      * This method is like `_.defaults` except that it recursively assigns
10850      * default properties.
10851      *
10852      * **Note:** This method mutates `object`.
10853      *
10854      * @static
10855      * @memberOf _
10856      * @category Object
10857      * @param {Object} object The destination object.
10858      * @param {...Object} [sources] The source objects.
10859      * @returns {Object} Returns `object`.
10860      * @example
10861      *
10862      * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
10863      * // => { 'user': { 'name': 'barney', 'age': 36 } }
10864      *
10865      */
10866     var defaultsDeep = rest(function(args) {
10867       args.push(undefined, mergeDefaults);
10868       return apply(mergeWith, undefined, args);
10869     });
10870
10871     /**
10872      * This method is like `_.find` except that it returns the key of the first
10873      * element `predicate` returns truthy for instead of the element itself.
10874      *
10875      * @static
10876      * @memberOf _
10877      * @category Object
10878      * @param {Object} object The object to search.
10879      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
10880      * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
10881      * @example
10882      *
10883      * var users = {
10884      *   'barney':  { 'age': 36, 'active': true },
10885      *   'fred':    { 'age': 40, 'active': false },
10886      *   'pebbles': { 'age': 1,  'active': true }
10887      * };
10888      *
10889      * _.findKey(users, function(o) { return o.age < 40; });
10890      * // => 'barney' (iteration order is not guaranteed)
10891      *
10892      * // The `_.matches` iteratee shorthand.
10893      * _.findKey(users, { 'age': 1, 'active': true });
10894      * // => 'pebbles'
10895      *
10896      * // The `_.matchesProperty` iteratee shorthand.
10897      * _.findKey(users, ['active', false]);
10898      * // => 'fred'
10899      *
10900      * // The `_.property` iteratee shorthand.
10901      * _.findKey(users, 'active');
10902      * // => 'barney'
10903      */
10904     function findKey(object, predicate) {
10905       return baseFind(object, getIteratee(predicate, 3), baseForOwn, true);
10906     }
10907
10908     /**
10909      * This method is like `_.findKey` except that it iterates over elements of
10910      * a collection in the opposite order.
10911      *
10912      * @static
10913      * @memberOf _
10914      * @category Object
10915      * @param {Object} object The object to search.
10916      * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
10917      * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
10918      * @example
10919      *
10920      * var users = {
10921      *   'barney':  { 'age': 36, 'active': true },
10922      *   'fred':    { 'age': 40, 'active': false },
10923      *   'pebbles': { 'age': 1,  'active': true }
10924      * };
10925      *
10926      * _.findLastKey(users, function(o) { return o.age < 40; });
10927      * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
10928      *
10929      * // The `_.matches` iteratee shorthand.
10930      * _.findLastKey(users, { 'age': 36, 'active': true });
10931      * // => 'barney'
10932      *
10933      * // The `_.matchesProperty` iteratee shorthand.
10934      * _.findLastKey(users, ['active', false]);
10935      * // => 'fred'
10936      *
10937      * // The `_.property` iteratee shorthand.
10938      * _.findLastKey(users, 'active');
10939      * // => 'pebbles'
10940      */
10941     function findLastKey(object, predicate) {
10942       return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true);
10943     }
10944
10945     /**
10946      * Iterates over own and inherited enumerable properties of an object invoking
10947      * `iteratee` for each property. The iteratee is invoked with three arguments:
10948      * (value, key, object). Iteratee functions may exit iteration early by explicitly
10949      * returning `false`.
10950      *
10951      * @static
10952      * @memberOf _
10953      * @category Object
10954      * @param {Object} object The object to iterate over.
10955      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10956      * @returns {Object} Returns `object`.
10957      * @example
10958      *
10959      * function Foo() {
10960      *   this.a = 1;
10961      *   this.b = 2;
10962      * }
10963      *
10964      * Foo.prototype.c = 3;
10965      *
10966      * _.forIn(new Foo, function(value, key) {
10967      *   console.log(key);
10968      * });
10969      * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed)
10970      */
10971     function forIn(object, iteratee) {
10972       return object == null ? object : baseFor(object, toFunction(iteratee), keysIn);
10973     }
10974
10975     /**
10976      * This method is like `_.forIn` except that it iterates over properties of
10977      * `object` in the opposite order.
10978      *
10979      * @static
10980      * @memberOf _
10981      * @category Object
10982      * @param {Object} object The object to iterate over.
10983      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10984      * @returns {Object} Returns `object`.
10985      * @example
10986      *
10987      * function Foo() {
10988      *   this.a = 1;
10989      *   this.b = 2;
10990      * }
10991      *
10992      * Foo.prototype.c = 3;
10993      *
10994      * _.forInRight(new Foo, function(value, key) {
10995      *   console.log(key);
10996      * });
10997      * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'
10998      */
10999     function forInRight(object, iteratee) {
11000       return object == null ? object : baseForRight(object, toFunction(iteratee), keysIn);
11001     }
11002
11003     /**
11004      * Iterates over own enumerable properties of an object invoking `iteratee`
11005      * for each property. The iteratee is invoked with three arguments:
11006      * (value, key, object). Iteratee functions may exit iteration early by
11007      * explicitly returning `false`.
11008      *
11009      * @static
11010      * @memberOf _
11011      * @category Object
11012      * @param {Object} object The object to iterate over.
11013      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11014      * @returns {Object} Returns `object`.
11015      * @example
11016      *
11017      * function Foo() {
11018      *   this.a = 1;
11019      *   this.b = 2;
11020      * }
11021      *
11022      * Foo.prototype.c = 3;
11023      *
11024      * _.forOwn(new Foo, function(value, key) {
11025      *   console.log(key);
11026      * });
11027      * // => logs 'a' then 'b' (iteration order is not guaranteed)
11028      */
11029     function forOwn(object, iteratee) {
11030       return object && baseForOwn(object, toFunction(iteratee));
11031     }
11032
11033     /**
11034      * This method is like `_.forOwn` except that it iterates over properties of
11035      * `object` in the opposite order.
11036      *
11037      * @static
11038      * @memberOf _
11039      * @category Object
11040      * @param {Object} object The object to iterate over.
11041      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11042      * @returns {Object} Returns `object`.
11043      * @example
11044      *
11045      * function Foo() {
11046      *   this.a = 1;
11047      *   this.b = 2;
11048      * }
11049      *
11050      * Foo.prototype.c = 3;
11051      *
11052      * _.forOwnRight(new Foo, function(value, key) {
11053      *   console.log(key);
11054      * });
11055      * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'
11056      */
11057     function forOwnRight(object, iteratee) {
11058       return object && baseForOwnRight(object, toFunction(iteratee));
11059     }
11060
11061     /**
11062      * Creates an array of function property names from own enumerable properties
11063      * of `object`.
11064      *
11065      * @static
11066      * @memberOf _
11067      * @category Object
11068      * @param {Object} object The object to inspect.
11069      * @returns {Array} Returns the new array of property names.
11070      * @example
11071      *
11072      * function Foo() {
11073      *   this.a = _.constant('a');
11074      *   this.b = _.constant('b');
11075      * }
11076      *
11077      * Foo.prototype.c = _.constant('c');
11078      *
11079      * _.functions(new Foo);
11080      * // => ['a', 'b']
11081      */
11082     function functions(object) {
11083       return object == null ? [] : baseFunctions(object, keys(object));
11084     }
11085
11086     /**
11087      * Creates an array of function property names from own and inherited
11088      * enumerable properties of `object`.
11089      *
11090      * @static
11091      * @memberOf _
11092      * @category Object
11093      * @param {Object} object The object to inspect.
11094      * @returns {Array} Returns the new array of property names.
11095      * @example
11096      *
11097      * function Foo() {
11098      *   this.a = _.constant('a');
11099      *   this.b = _.constant('b');
11100      * }
11101      *
11102      * Foo.prototype.c = _.constant('c');
11103      *
11104      * _.functionsIn(new Foo);
11105      * // => ['a', 'b', 'c']
11106      */
11107     function functionsIn(object) {
11108       return object == null ? [] : baseFunctions(object, keysIn(object));
11109     }
11110
11111     /**
11112      * Gets the value at `path` of `object`. If the resolved value is
11113      * `undefined` the `defaultValue` is used in its place.
11114      *
11115      * @static
11116      * @memberOf _
11117      * @category Object
11118      * @param {Object} object The object to query.
11119      * @param {Array|string} path The path of the property to get.
11120      * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
11121      * @returns {*} Returns the resolved value.
11122      * @example
11123      *
11124      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
11125      *
11126      * _.get(object, 'a[0].b.c');
11127      * // => 3
11128      *
11129      * _.get(object, ['a', '0', 'b', 'c']);
11130      * // => 3
11131      *
11132      * _.get(object, 'a.b.c', 'default');
11133      * // => 'default'
11134      */
11135     function get(object, path, defaultValue) {
11136       var result = object == null ? undefined : baseGet(object, path);
11137       return result === undefined ? defaultValue : result;
11138     }
11139
11140     /**
11141      * Checks if `path` is a direct property of `object`.
11142      *
11143      * @static
11144      * @memberOf _
11145      * @category Object
11146      * @param {Object} object The object to query.
11147      * @param {Array|string} path The path to check.
11148      * @returns {boolean} Returns `true` if `path` exists, else `false`.
11149      * @example
11150      *
11151      * var object = { 'a': { 'b': { 'c': 3 } } };
11152      * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
11153      *
11154      * _.has(object, 'a');
11155      * // => true
11156      *
11157      * _.has(object, 'a.b.c');
11158      * // => true
11159      *
11160      * _.has(object, ['a', 'b', 'c']);
11161      * // => true
11162      *
11163      * _.has(other, 'a');
11164      * // => false
11165      */
11166     function has(object, path) {
11167       return hasPath(object, path, baseHas);
11168     }
11169
11170     /**
11171      * Checks if `path` is a direct or inherited property of `object`.
11172      *
11173      * @static
11174      * @memberOf _
11175      * @category Object
11176      * @param {Object} object The object to query.
11177      * @param {Array|string} path The path to check.
11178      * @returns {boolean} Returns `true` if `path` exists, else `false`.
11179      * @example
11180      *
11181      * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
11182      *
11183      * _.hasIn(object, 'a');
11184      * // => true
11185      *
11186      * _.hasIn(object, 'a.b.c');
11187      * // => true
11188      *
11189      * _.hasIn(object, ['a', 'b', 'c']);
11190      * // => true
11191      *
11192      * _.hasIn(object, 'b');
11193      * // => false
11194      */
11195     function hasIn(object, path) {
11196       return hasPath(object, path, baseHasIn);
11197     }
11198
11199     /**
11200      * Creates an object composed of the inverted keys and values of `object`.
11201      * If `object` contains duplicate values, subsequent values overwrite property
11202      * assignments of previous values.
11203      *
11204      * @static
11205      * @memberOf _
11206      * @category Object
11207      * @param {Object} object The object to invert.
11208      * @returns {Object} Returns the new inverted object.
11209      * @example
11210      *
11211      * var object = { 'a': 1, 'b': 2, 'c': 1 };
11212      *
11213      * _.invert(object);
11214      * // => { '1': 'c', '2': 'b' }
11215      */
11216     var invert = createInverter(function(result, value, key) {
11217       result[value] = key;
11218     }, constant(identity));
11219
11220     /**
11221      * This method is like `_.invert` except that the inverted object is generated
11222      * from the results of running each element of `object` through `iteratee`.
11223      * The corresponding inverted value of each inverted key is an array of keys
11224      * responsible for generating the inverted value. The iteratee is invoked
11225      * with one argument: (value).
11226      *
11227      * @static
11228      * @memberOf _
11229      * @category Object
11230      * @param {Object} object The object to invert.
11231      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
11232      * @returns {Object} Returns the new inverted object.
11233      * @example
11234      *
11235      * var object = { 'a': 1, 'b': 2, 'c': 1 };
11236      *
11237      * _.invertBy(object);
11238      * // => { '1': ['a', 'c'], '2': ['b'] }
11239      *
11240      * _.invertBy(object, function(value) {
11241      *   return 'group' + value;
11242      * });
11243      * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
11244      */
11245     var invertBy = createInverter(function(result, value, key) {
11246       if (hasOwnProperty.call(result, value)) {
11247         result[value].push(key);
11248       } else {
11249         result[value] = [key];
11250       }
11251     }, getIteratee);
11252
11253     /**
11254      * Invokes the method at `path` of `object`.
11255      *
11256      * @static
11257      * @memberOf _
11258      * @category Object
11259      * @param {Object} object The object to query.
11260      * @param {Array|string} path The path of the method to invoke.
11261      * @param {...*} [args] The arguments to invoke the method with.
11262      * @returns {*} Returns the result of the invoked method.
11263      * @example
11264      *
11265      * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
11266      *
11267      * _.invoke(object, 'a[0].b.c.slice', 1, 3);
11268      * // => [2, 3]
11269      */
11270     var invoke = rest(baseInvoke);
11271
11272     /**
11273      * Creates an array of the own enumerable property names of `object`.
11274      *
11275      * **Note:** Non-object values are coerced to objects. See the
11276      * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
11277      * for more details.
11278      *
11279      * @static
11280      * @memberOf _
11281      * @category Object
11282      * @param {Object} object The object to query.
11283      * @returns {Array} Returns the array of property names.
11284      * @example
11285      *
11286      * function Foo() {
11287      *   this.a = 1;
11288      *   this.b = 2;
11289      * }
11290      *
11291      * Foo.prototype.c = 3;
11292      *
11293      * _.keys(new Foo);
11294      * // => ['a', 'b'] (iteration order is not guaranteed)
11295      *
11296      * _.keys('hi');
11297      * // => ['0', '1']
11298      */
11299     function keys(object) {
11300       var isProto = isPrototype(object);
11301       if (!(isProto || isArrayLike(object))) {
11302         return baseKeys(object);
11303       }
11304       var indexes = indexKeys(object),
11305           skipIndexes = !!indexes,
11306           result = indexes || [],
11307           length = result.length;
11308
11309       for (var key in object) {
11310         if (baseHas(object, key) &&
11311             !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11312             !(isProto && key == 'constructor')) {
11313           result.push(key);
11314         }
11315       }
11316       return result;
11317     }
11318
11319     /**
11320      * Creates an array of the own and inherited enumerable property names of `object`.
11321      *
11322      * **Note:** Non-object values are coerced to objects.
11323      *
11324      * @static
11325      * @memberOf _
11326      * @category Object
11327      * @param {Object} object The object to query.
11328      * @returns {Array} Returns the array of property names.
11329      * @example
11330      *
11331      * function Foo() {
11332      *   this.a = 1;
11333      *   this.b = 2;
11334      * }
11335      *
11336      * Foo.prototype.c = 3;
11337      *
11338      * _.keysIn(new Foo);
11339      * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
11340      */
11341     function keysIn(object) {
11342       var index = -1,
11343           isProto = isPrototype(object),
11344           props = baseKeysIn(object),
11345           propsLength = props.length,
11346           indexes = indexKeys(object),
11347           skipIndexes = !!indexes,
11348           result = indexes || [],
11349           length = result.length;
11350
11351       while (++index < propsLength) {
11352         var key = props[index];
11353         if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11354             !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
11355           result.push(key);
11356         }
11357       }
11358       return result;
11359     }
11360
11361     /**
11362      * The opposite of `_.mapValues`; this method creates an object with the
11363      * same values as `object` and keys generated by running each own enumerable
11364      * property of `object` through `iteratee`.
11365      *
11366      * @static
11367      * @memberOf _
11368      * @category Object
11369      * @param {Object} object The object to iterate over.
11370      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11371      * @returns {Object} Returns the new mapped object.
11372      * @example
11373      *
11374      * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
11375      *   return key + value;
11376      * });
11377      * // => { 'a1': 1, 'b2': 2 }
11378      */
11379     function mapKeys(object, iteratee) {
11380       var result = {};
11381       iteratee = getIteratee(iteratee, 3);
11382
11383       baseForOwn(object, function(value, key, object) {
11384         result[iteratee(value, key, object)] = value;
11385       });
11386       return result;
11387     }
11388
11389     /**
11390      * Creates an object with the same keys as `object` and values generated by
11391      * running each own enumerable property of `object` through `iteratee`. The
11392      * iteratee function is invoked with three arguments: (value, key, object).
11393      *
11394      * @static
11395      * @memberOf _
11396      * @category Object
11397      * @param {Object} object The object to iterate over.
11398      * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11399      * @returns {Object} Returns the new mapped object.
11400      * @example
11401      *
11402      * var users = {
11403      *   'fred':    { 'user': 'fred',    'age': 40 },
11404      *   'pebbles': { 'user': 'pebbles', 'age': 1 }
11405      * };
11406      *
11407      * _.mapValues(users, function(o) { return o.age; });
11408      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11409      *
11410      * // The `_.property` iteratee shorthand.
11411      * _.mapValues(users, 'age');
11412      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11413      */
11414     function mapValues(object, iteratee) {
11415       var result = {};
11416       iteratee = getIteratee(iteratee, 3);
11417
11418       baseForOwn(object, function(value, key, object) {
11419         result[key] = iteratee(value, key, object);
11420       });
11421       return result;
11422     }
11423
11424     /**
11425      * Recursively merges own and inherited enumerable properties of source
11426      * objects into the destination object, skipping source properties that resolve
11427      * to `undefined`. Array and plain object properties are merged recursively.
11428      * Other objects and value types are overridden by assignment. Source objects
11429      * are applied from left to right. Subsequent sources overwrite property
11430      * assignments of previous sources.
11431      *
11432      * **Note:** This method mutates `object`.
11433      *
11434      * @static
11435      * @memberOf _
11436      * @category Object
11437      * @param {Object} object The destination object.
11438      * @param {...Object} [sources] The source objects.
11439      * @returns {Object} Returns `object`.
11440      * @example
11441      *
11442      * var users = {
11443      *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
11444      * };
11445      *
11446      * var ages = {
11447      *   'data': [{ 'age': 36 }, { 'age': 40 }]
11448      * };
11449      *
11450      * _.merge(users, ages);
11451      * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
11452      */
11453     var merge = createAssigner(function(object, source, srcIndex) {
11454       baseMerge(object, source, srcIndex);
11455     });
11456
11457     /**
11458      * This method is like `_.merge` except that it accepts `customizer` which
11459      * is invoked to produce the merged values of the destination and source
11460      * properties. If `customizer` returns `undefined` merging is handled by the
11461      * method instead. The `customizer` is invoked with seven arguments:
11462      * (objValue, srcValue, key, object, source, stack).
11463      *
11464      * **Note:** This method mutates `object`.
11465      *
11466      * @static
11467      * @memberOf _
11468      * @category Object
11469      * @param {Object} object The destination object.
11470      * @param {...Object} sources The source objects.
11471      * @param {Function} customizer The function to customize assigned values.
11472      * @returns {Object} Returns `object`.
11473      * @example
11474      *
11475      * function customizer(objValue, srcValue) {
11476      *   if (_.isArray(objValue)) {
11477      *     return objValue.concat(srcValue);
11478      *   }
11479      * }
11480      *
11481      * var object = {
11482      *   'fruits': ['apple'],
11483      *   'vegetables': ['beet']
11484      * };
11485      *
11486      * var other = {
11487      *   'fruits': ['banana'],
11488      *   'vegetables': ['carrot']
11489      * };
11490      *
11491      * _.mergeWith(object, other, customizer);
11492      * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
11493      */
11494     var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
11495       baseMerge(object, source, srcIndex, customizer);
11496     });
11497
11498     /**
11499      * The opposite of `_.pick`; this method creates an object composed of the
11500      * own and inherited enumerable properties of `object` that are not omitted.
11501      *
11502      * @static
11503      * @memberOf _
11504      * @category Object
11505      * @param {Object} object The source object.
11506      * @param {...(string|string[])} [props] The property names to omit, specified
11507      *  individually or in arrays..
11508      * @returns {Object} Returns the new object.
11509      * @example
11510      *
11511      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11512      *
11513      * _.omit(object, ['a', 'c']);
11514      * // => { 'b': '2' }
11515      */
11516     var omit = rest(function(object, props) {
11517       if (object == null) {
11518         return {};
11519       }
11520       props = arrayMap(baseFlatten(props), String);
11521       return basePick(object, baseDifference(keysIn(object), props));
11522     });
11523
11524     /**
11525      * The opposite of `_.pickBy`; this method creates an object composed of the
11526      * own and inherited enumerable properties of `object` that `predicate`
11527      * doesn't return truthy for.
11528      *
11529      * @static
11530      * @memberOf _
11531      * @category Object
11532      * @param {Object} object The source object.
11533      * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11534      * @returns {Object} Returns the new object.
11535      * @example
11536      *
11537      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11538      *
11539      * _.omitBy(object, _.isNumber);
11540      * // => { 'b': '2' }
11541      */
11542     function omitBy(object, predicate) {
11543       predicate = getIteratee(predicate, 2);
11544       return basePickBy(object, function(value, key) {
11545         return !predicate(value, key);
11546       });
11547     }
11548
11549     /**
11550      * Creates an object composed of the picked `object` properties.
11551      *
11552      * @static
11553      * @memberOf _
11554      * @category Object
11555      * @param {Object} object The source object.
11556      * @param {...(string|string[])} [props] The property names to pick, specified
11557      *  individually or in arrays.
11558      * @returns {Object} Returns the new object.
11559      * @example
11560      *
11561      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11562      *
11563      * _.pick(object, ['a', 'c']);
11564      * // => { 'a': 1, 'c': 3 }
11565      */
11566     var pick = rest(function(object, props) {
11567       return object == null ? {} : basePick(object, baseFlatten(props));
11568     });
11569
11570     /**
11571      * Creates an object composed of the `object` properties `predicate` returns
11572      * truthy for. The predicate is invoked with two arguments: (value, key).
11573      *
11574      * @static
11575      * @memberOf _
11576      * @category Object
11577      * @param {Object} object The source object.
11578      * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11579      * @returns {Object} Returns the new object.
11580      * @example
11581      *
11582      * var object = { 'a': 1, 'b': '2', 'c': 3 };
11583      *
11584      * _.pickBy(object, _.isNumber);
11585      * // => { 'a': 1, 'c': 3 }
11586      */
11587     function pickBy(object, predicate) {
11588       return object == null ? {} : basePickBy(object, getIteratee(predicate, 2));
11589     }
11590
11591     /**
11592      * This method is like `_.get` except that if the resolved value is a function
11593      * it's invoked with the `this` binding of its parent object and its result
11594      * is returned.
11595      *
11596      * @static
11597      * @memberOf _
11598      * @category Object
11599      * @param {Object} object The object to query.
11600      * @param {Array|string} path The path of the property to resolve.
11601      * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
11602      * @returns {*} Returns the resolved value.
11603      * @example
11604      *
11605      * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
11606      *
11607      * _.result(object, 'a[0].b.c1');
11608      * // => 3
11609      *
11610      * _.result(object, 'a[0].b.c2');
11611      * // => 4
11612      *
11613      * _.result(object, 'a[0].b.c3', 'default');
11614      * // => 'default'
11615      *
11616      * _.result(object, 'a[0].b.c3', _.constant('default'));
11617      * // => 'default'
11618      */
11619     function result(object, path, defaultValue) {
11620       if (!isKey(path, object)) {
11621         path = baseToPath(path);
11622         var result = get(object, path);
11623         object = parent(object, path);
11624       } else {
11625         result = object == null ? undefined : object[path];
11626       }
11627       if (result === undefined) {
11628         result = defaultValue;
11629       }
11630       return isFunction(result) ? result.call(object) : result;
11631     }
11632
11633     /**
11634      * Sets the value at `path` of `object`. If a portion of `path` doesn't exist
11635      * it's created. Arrays are created for missing index properties while objects
11636      * are created for all other missing properties. Use `_.setWith` to customize
11637      * `path` creation.
11638      *
11639      * **Note:** This method mutates `object`.
11640      *
11641      * @static
11642      * @memberOf _
11643      * @category Object
11644      * @param {Object} object The object to modify.
11645      * @param {Array|string} path The path of the property to set.
11646      * @param {*} value The value to set.
11647      * @returns {Object} Returns `object`.
11648      * @example
11649      *
11650      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
11651      *
11652      * _.set(object, 'a[0].b.c', 4);
11653      * console.log(object.a[0].b.c);
11654      * // => 4
11655      *
11656      * _.set(object, 'x[0].y.z', 5);
11657      * console.log(object.x[0].y.z);
11658      * // => 5
11659      */
11660     function set(object, path, value) {
11661       return object == null ? object : baseSet(object, path, value);
11662     }
11663
11664     /**
11665      * This method is like `_.set` except that it accepts `customizer` which is
11666      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
11667      * path creation is handled by the method instead. The `customizer` is invoked
11668      * with three arguments: (nsValue, key, nsObject).
11669      *
11670      * **Note:** This method mutates `object`.
11671      *
11672      * @static
11673      * @memberOf _
11674      * @category Object
11675      * @param {Object} object The object to modify.
11676      * @param {Array|string} path The path of the property to set.
11677      * @param {*} value The value to set.
11678      * @param {Function} [customizer] The function to customize assigned values.
11679      * @returns {Object} Returns `object`.
11680      * @example
11681      *
11682      * _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object);
11683      * // => { '0': { '1': { '2': 3 }, 'length': 2 } }
11684      */
11685     function setWith(object, path, value, customizer) {
11686       customizer = typeof customizer == 'function' ? customizer : undefined;
11687       return object == null ? object : baseSet(object, path, value, customizer);
11688     }
11689
11690     /**
11691      * Creates an array of own enumerable key-value pairs for `object`.
11692      *
11693      * @static
11694      * @memberOf _
11695      * @category Object
11696      * @param {Object} object The object to query.
11697      * @returns {Array} Returns the new array of key-value pairs.
11698      * @example
11699      *
11700      * function Foo() {
11701      *   this.a = 1;
11702      *   this.b = 2;
11703      * }
11704      *
11705      * Foo.prototype.c = 3;
11706      *
11707      * _.toPairs(new Foo);
11708      * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
11709      */
11710     function toPairs(object) {
11711       return baseToPairs(object, keys(object));
11712     }
11713
11714     /**
11715      * Creates an array of own and inherited enumerable key-value pairs for `object`.
11716      *
11717      * @static
11718      * @memberOf _
11719      * @category Object
11720      * @param {Object} object The object to query.
11721      * @returns {Array} Returns the new array of key-value pairs.
11722      * @example
11723      *
11724      * function Foo() {
11725      *   this.a = 1;
11726      *   this.b = 2;
11727      * }
11728      *
11729      * Foo.prototype.c = 3;
11730      *
11731      * _.toPairsIn(new Foo);
11732      * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
11733      */
11734     function toPairsIn(object) {
11735       return baseToPairs(object, keysIn(object));
11736     }
11737
11738     /**
11739      * An alternative to `_.reduce`; this method transforms `object` to a new
11740      * `accumulator` object which is the result of running each of its own enumerable
11741      * properties through `iteratee`, with each invocation potentially mutating
11742      * the `accumulator` object. The iteratee is invoked with four arguments:
11743      * (accumulator, value, key, object). Iteratee functions may exit iteration
11744      * early by explicitly returning `false`.
11745      *
11746      * @static
11747      * @memberOf _
11748      * @category Object
11749      * @param {Array|Object} object The object to iterate over.
11750      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11751      * @param {*} [accumulator] The custom accumulator value.
11752      * @returns {*} Returns the accumulated value.
11753      * @example
11754      *
11755      * _.transform([2, 3, 4], function(result, n) {
11756      *   result.push(n *= n);
11757      *   return n % 2 == 0;
11758      * }, []);
11759      * // => [4, 9]
11760      *
11761      * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
11762      *   (result[value] || (result[value] = [])).push(key);
11763      * }, {});
11764      * // => { '1': ['a', 'c'], '2': ['b'] }
11765      */
11766     function transform(object, iteratee, accumulator) {
11767       var isArr = isArray(object) || isTypedArray(object);
11768       iteratee = getIteratee(iteratee, 4);
11769
11770       if (accumulator == null) {
11771         if (isArr || isObject(object)) {
11772           var Ctor = object.constructor;
11773           if (isArr) {
11774             accumulator = isArray(object) ? new Ctor : [];
11775           } else {
11776             accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
11777           }
11778         } else {
11779           accumulator = {};
11780         }
11781       }
11782       (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
11783         return iteratee(accumulator, value, index, object);
11784       });
11785       return accumulator;
11786     }
11787
11788     /**
11789      * Removes the property at `path` of `object`.
11790      *
11791      * **Note:** This method mutates `object`.
11792      *
11793      * @static
11794      * @memberOf _
11795      * @category Object
11796      * @param {Object} object The object to modify.
11797      * @param {Array|string} path The path of the property to unset.
11798      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
11799      * @example
11800      *
11801      * var object = { 'a': [{ 'b': { 'c': 7 } }] };
11802      * _.unset(object, 'a[0].b.c');
11803      * // => true
11804      *
11805      * console.log(object);
11806      * // => { 'a': [{ 'b': {} }] };
11807      *
11808      * _.unset(object, 'a[0].b.c');
11809      * // => true
11810      *
11811      * console.log(object);
11812      * // => { 'a': [{ 'b': {} }] };
11813      */
11814     function unset(object, path) {
11815       return object == null ? true : baseUnset(object, path);
11816     }
11817
11818     /**
11819      * Creates an array of the own enumerable property values of `object`.
11820      *
11821      * **Note:** Non-object values are coerced to objects.
11822      *
11823      * @static
11824      * @memberOf _
11825      * @category Object
11826      * @param {Object} object The object to query.
11827      * @returns {Array} Returns the array of property values.
11828      * @example
11829      *
11830      * function Foo() {
11831      *   this.a = 1;
11832      *   this.b = 2;
11833      * }
11834      *
11835      * Foo.prototype.c = 3;
11836      *
11837      * _.values(new Foo);
11838      * // => [1, 2] (iteration order is not guaranteed)
11839      *
11840      * _.values('hi');
11841      * // => ['h', 'i']
11842      */
11843     function values(object) {
11844       return object ? baseValues(object, keys(object)) : [];
11845     }
11846
11847     /**
11848      * Creates an array of the own and inherited enumerable property values of `object`.
11849      *
11850      * **Note:** Non-object values are coerced to objects.
11851      *
11852      * @static
11853      * @memberOf _
11854      * @category Object
11855      * @param {Object} object The object to query.
11856      * @returns {Array} Returns the array of property values.
11857      * @example
11858      *
11859      * function Foo() {
11860      *   this.a = 1;
11861      *   this.b = 2;
11862      * }
11863      *
11864      * Foo.prototype.c = 3;
11865      *
11866      * _.valuesIn(new Foo);
11867      * // => [1, 2, 3] (iteration order is not guaranteed)
11868      */
11869     function valuesIn(object) {
11870       return object == null ? baseValues(object, keysIn(object)) : [];
11871     }
11872
11873     /*------------------------------------------------------------------------*/
11874
11875     /**
11876      * Clamps `number` within the inclusive `lower` and `upper` bounds.
11877      *
11878      * @static
11879      * @memberOf _
11880      * @category Number
11881      * @param {number} number The number to clamp.
11882      * @param {number} [lower] The lower bound.
11883      * @param {number} upper The upper bound.
11884      * @returns {number} Returns the clamped number.
11885      * @example
11886      *
11887      * _.clamp(-10, -5, 5);
11888      * // => -5
11889      *
11890      * _.clamp(10, -5, 5);
11891      * // => 5
11892      */
11893     function clamp(number, lower, upper) {
11894       if (upper === undefined) {
11895         upper = lower;
11896         lower = undefined;
11897       }
11898       if (upper !== undefined) {
11899         upper = toNumber(upper);
11900         upper = upper === upper ? upper : 0;
11901       }
11902       if (lower !== undefined) {
11903         lower = toNumber(lower);
11904         lower = lower === lower ? lower : 0;
11905       }
11906       return baseClamp(toNumber(number), lower, upper);
11907     }
11908
11909     /**
11910      * Checks if `n` is between `start` and up to but not including, `end`. If
11911      * `end` is not specified it's set to `start` with `start` then set to `0`.
11912      * If `start` is greater than `end` the params are swapped to support
11913      * negative ranges.
11914      *
11915      * @static
11916      * @memberOf _
11917      * @category Number
11918      * @param {number} number The number to check.
11919      * @param {number} [start=0] The start of the range.
11920      * @param {number} end The end of the range.
11921      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
11922      * @example
11923      *
11924      * _.inRange(3, 2, 4);
11925      * // => true
11926      *
11927      * _.inRange(4, 8);
11928      * // => true
11929      *
11930      * _.inRange(4, 2);
11931      * // => false
11932      *
11933      * _.inRange(2, 2);
11934      * // => false
11935      *
11936      * _.inRange(1.2, 2);
11937      * // => true
11938      *
11939      * _.inRange(5.2, 4);
11940      * // => false
11941      *
11942      * _.inRange(-3, -2, -6);
11943      * // => true
11944      */
11945     function inRange(number, start, end) {
11946       start = toNumber(start) || 0;
11947       if (end === undefined) {
11948         end = start;
11949         start = 0;
11950       } else {
11951         end = toNumber(end) || 0;
11952       }
11953       number = toNumber(number);
11954       return baseInRange(number, start, end);
11955     }
11956
11957     /**
11958      * Produces a random number between the inclusive `lower` and `upper` bounds.
11959      * If only one argument is provided a number between `0` and the given number
11960      * is returned. If `floating` is `true`, or either `lower` or `upper` are floats,
11961      * a floating-point number is returned instead of an integer.
11962      *
11963      * **Note:** JavaScript follows the IEEE-754 standard for resolving
11964      * floating-point values which can produce unexpected results.
11965      *
11966      * @static
11967      * @memberOf _
11968      * @category Number
11969      * @param {number} [lower=0] The lower bound.
11970      * @param {number} [upper=1] The upper bound.
11971      * @param {boolean} [floating] Specify returning a floating-point number.
11972      * @returns {number} Returns the random number.
11973      * @example
11974      *
11975      * _.random(0, 5);
11976      * // => an integer between 0 and 5
11977      *
11978      * _.random(5);
11979      * // => also an integer between 0 and 5
11980      *
11981      * _.random(5, true);
11982      * // => a floating-point number between 0 and 5
11983      *
11984      * _.random(1.2, 5.2);
11985      * // => a floating-point number between 1.2 and 5.2
11986      */
11987     function random(lower, upper, floating) {
11988       if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
11989         upper = floating = undefined;
11990       }
11991       if (floating === undefined) {
11992         if (typeof upper == 'boolean') {
11993           floating = upper;
11994           upper = undefined;
11995         }
11996         else if (typeof lower == 'boolean') {
11997           floating = lower;
11998           lower = undefined;
11999         }
12000       }
12001       if (lower === undefined && upper === undefined) {
12002         lower = 0;
12003         upper = 1;
12004       }
12005       else {
12006         lower = toNumber(lower) || 0;
12007         if (upper === undefined) {
12008           upper = lower;
12009           lower = 0;
12010         } else {
12011           upper = toNumber(upper) || 0;
12012         }
12013       }
12014       if (lower > upper) {
12015         var temp = lower;
12016         lower = upper;
12017         upper = temp;
12018       }
12019       if (floating || lower % 1 || upper % 1) {
12020         var rand = nativeRandom();
12021         return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
12022       }
12023       return baseRandom(lower, upper);
12024     }
12025
12026     /*------------------------------------------------------------------------*/
12027
12028     /**
12029      * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
12030      *
12031      * @static
12032      * @memberOf _
12033      * @category String
12034      * @param {string} [string=''] The string to convert.
12035      * @returns {string} Returns the camel cased string.
12036      * @example
12037      *
12038      * _.camelCase('Foo Bar');
12039      * // => 'fooBar'
12040      *
12041      * _.camelCase('--foo-bar');
12042      * // => 'fooBar'
12043      *
12044      * _.camelCase('__foo_bar__');
12045      * // => 'fooBar'
12046      */
12047     var camelCase = createCompounder(function(result, word, index) {
12048       word = word.toLowerCase();
12049       return result + (index ? capitalize(word) : word);
12050     });
12051
12052     /**
12053      * Converts the first character of `string` to upper case and the remaining
12054      * to lower case.
12055      *
12056      * @static
12057      * @memberOf _
12058      * @category String
12059      * @param {string} [string=''] The string to capitalize.
12060      * @returns {string} Returns the capitalized string.
12061      * @example
12062      *
12063      * _.capitalize('FRED');
12064      * // => 'Fred'
12065      */
12066     function capitalize(string) {
12067       return upperFirst(toString(string).toLowerCase());
12068     }
12069
12070     /**
12071      * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
12072      * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
12073      *
12074      * @static
12075      * @memberOf _
12076      * @category String
12077      * @param {string} [string=''] The string to deburr.
12078      * @returns {string} Returns the deburred string.
12079      * @example
12080      *
12081      * _.deburr('déjà vu');
12082      * // => 'deja vu'
12083      */
12084     function deburr(string) {
12085       string = toString(string);
12086       return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
12087     }
12088
12089     /**
12090      * Checks if `string` ends with the given target string.
12091      *
12092      * @static
12093      * @memberOf _
12094      * @category String
12095      * @param {string} [string=''] The string to search.
12096      * @param {string} [target] The string to search for.
12097      * @param {number} [position=string.length] The position to search from.
12098      * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`.
12099      * @example
12100      *
12101      * _.endsWith('abc', 'c');
12102      * // => true
12103      *
12104      * _.endsWith('abc', 'b');
12105      * // => false
12106      *
12107      * _.endsWith('abc', 'b', 2);
12108      * // => true
12109      */
12110     function endsWith(string, target, position) {
12111       string = toString(string);
12112       target = typeof target == 'string' ? target : (target + '');
12113
12114       var length = string.length;
12115       position = position === undefined
12116         ? length
12117         : baseClamp(toInteger(position), 0, length);
12118
12119       position -= target.length;
12120       return position >= 0 && string.indexOf(target, position) == position;
12121     }
12122
12123     /**
12124      * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
12125      * their corresponding HTML entities.
12126      *
12127      * **Note:** No other characters are escaped. To escape additional
12128      * characters use a third-party library like [_he_](https://mths.be/he).
12129      *
12130      * Though the ">" character is escaped for symmetry, characters like
12131      * ">" and "/" don't need escaping in HTML and have no special meaning
12132      * unless they're part of a tag or unquoted attribute value.
12133      * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
12134      * (under "semi-related fun fact") for more details.
12135      *
12136      * Backticks are escaped because in IE < 9, they can break out of
12137      * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
12138      * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
12139      * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
12140      * for more details.
12141      *
12142      * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
12143      * to reduce XSS vectors.
12144      *
12145      * @static
12146      * @memberOf _
12147      * @category String
12148      * @param {string} [string=''] The string to escape.
12149      * @returns {string} Returns the escaped string.
12150      * @example
12151      *
12152      * _.escape('fred, barney, & pebbles');
12153      * // => 'fred, barney, &amp; pebbles'
12154      */
12155     function escape(string) {
12156       string = toString(string);
12157       return (string && reHasUnescapedHtml.test(string))
12158         ? string.replace(reUnescapedHtml, escapeHtmlChar)
12159         : string;
12160     }
12161
12162     /**
12163      * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
12164      * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
12165      *
12166      * @static
12167      * @memberOf _
12168      * @category String
12169      * @param {string} [string=''] The string to escape.
12170      * @returns {string} Returns the escaped string.
12171      * @example
12172      *
12173      * _.escapeRegExp('[lodash](https://lodash.com/)');
12174      * // => '\[lodash\]\(https://lodash\.com/\)'
12175      */
12176     function escapeRegExp(string) {
12177       string = toString(string);
12178       return (string && reHasRegExpChar.test(string))
12179         ? string.replace(reRegExpChar, '\\$&')
12180         : string;
12181     }
12182
12183     /**
12184      * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
12185      *
12186      * @static
12187      * @memberOf _
12188      * @category String
12189      * @param {string} [string=''] The string to convert.
12190      * @returns {string} Returns the kebab cased string.
12191      * @example
12192      *
12193      * _.kebabCase('Foo Bar');
12194      * // => 'foo-bar'
12195      *
12196      * _.kebabCase('fooBar');
12197      * // => 'foo-bar'
12198      *
12199      * _.kebabCase('__foo_bar__');
12200      * // => 'foo-bar'
12201      */
12202     var kebabCase = createCompounder(function(result, word, index) {
12203       return result + (index ? '-' : '') + word.toLowerCase();
12204     });
12205
12206     /**
12207      * Converts `string`, as space separated words, to lower case.
12208      *
12209      * @static
12210      * @memberOf _
12211      * @category String
12212      * @param {string} [string=''] The string to convert.
12213      * @returns {string} Returns the lower cased string.
12214      * @example
12215      *
12216      * _.lowerCase('--Foo-Bar');
12217      * // => 'foo bar'
12218      *
12219      * _.lowerCase('fooBar');
12220      * // => 'foo bar'
12221      *
12222      * _.lowerCase('__FOO_BAR__');
12223      * // => 'foo bar'
12224      */
12225     var lowerCase = createCompounder(function(result, word, index) {
12226       return result + (index ? ' ' : '') + word.toLowerCase();
12227     });
12228
12229     /**
12230      * Converts the first character of `string` to lower case.
12231      *
12232      * @static
12233      * @memberOf _
12234      * @category String
12235      * @param {string} [string=''] The string to convert.
12236      * @returns {string} Returns the converted string.
12237      * @example
12238      *
12239      * _.lowerFirst('Fred');
12240      * // => 'fred'
12241      *
12242      * _.lowerFirst('FRED');
12243      * // => 'fRED'
12244      */
12245     var lowerFirst = createCaseFirst('toLowerCase');
12246
12247     /**
12248      * Converts the first character of `string` to upper case.
12249      *
12250      * @static
12251      * @memberOf _
12252      * @category String
12253      * @param {string} [string=''] The string to convert.
12254      * @returns {string} Returns the converted string.
12255      * @example
12256      *
12257      * _.upperFirst('fred');
12258      * // => 'Fred'
12259      *
12260      * _.upperFirst('FRED');
12261      * // => 'FRED'
12262      */
12263     var upperFirst = createCaseFirst('toUpperCase');
12264
12265     /**
12266      * Pads `string` on the left and right sides if it's shorter than `length`.
12267      * Padding characters are truncated if they can't be evenly divided by `length`.
12268      *
12269      * @static
12270      * @memberOf _
12271      * @category String
12272      * @param {string} [string=''] The string to pad.
12273      * @param {number} [length=0] The padding length.
12274      * @param {string} [chars=' '] The string used as padding.
12275      * @returns {string} Returns the padded string.
12276      * @example
12277      *
12278      * _.pad('abc', 8);
12279      * // => '  abc   '
12280      *
12281      * _.pad('abc', 8, '_-');
12282      * // => '_-abc_-_'
12283      *
12284      * _.pad('abc', 3);
12285      * // => 'abc'
12286      */
12287     function pad(string, length, chars) {
12288       string = toString(string);
12289       length = toInteger(length);
12290
12291       var strLength = stringSize(string);
12292       if (!length || strLength >= length) {
12293         return string;
12294       }
12295       var mid = (length - strLength) / 2,
12296           leftLength = nativeFloor(mid),
12297           rightLength = nativeCeil(mid);
12298
12299       return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars);
12300     }
12301
12302     /**
12303      * Pads `string` on the right side if it's shorter than `length`. Padding
12304      * characters are truncated if they exceed `length`.
12305      *
12306      * @static
12307      * @memberOf _
12308      * @category String
12309      * @param {string} [string=''] The string to pad.
12310      * @param {number} [length=0] The padding length.
12311      * @param {string} [chars=' '] The string used as padding.
12312      * @returns {string} Returns the padded string.
12313      * @example
12314      *
12315      * _.padEnd('abc', 6);
12316      * // => 'abc   '
12317      *
12318      * _.padEnd('abc', 6, '_-');
12319      * // => 'abc_-_'
12320      *
12321      * _.padEnd('abc', 3);
12322      * // => 'abc'
12323      */
12324     function padEnd(string, length, chars) {
12325       string = toString(string);
12326       return string + createPadding(string, length, chars);
12327     }
12328
12329     /**
12330      * Pads `string` on the left side if it's shorter than `length`. Padding
12331      * characters are truncated if they exceed `length`.
12332      *
12333      * @static
12334      * @memberOf _
12335      * @category String
12336      * @param {string} [string=''] The string to pad.
12337      * @param {number} [length=0] The padding length.
12338      * @param {string} [chars=' '] The string used as padding.
12339      * @returns {string} Returns the padded string.
12340      * @example
12341      *
12342      * _.padStart('abc', 6);
12343      * // => '   abc'
12344      *
12345      * _.padStart('abc', 6, '_-');
12346      * // => '_-_abc'
12347      *
12348      * _.padStart('abc', 3);
12349      * // => 'abc'
12350      */
12351     function padStart(string, length, chars) {
12352       string = toString(string);
12353       return createPadding(string, length, chars) + string;
12354     }
12355
12356     /**
12357      * Converts `string` to an integer of the specified radix. If `radix` is
12358      * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
12359      * in which case a `radix` of `16` is used.
12360      *
12361      * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#x15.1.2.2)
12362      * of `parseInt`.
12363      *
12364      * @static
12365      * @memberOf _
12366      * @category String
12367      * @param {string} string The string to convert.
12368      * @param {number} [radix] The radix to interpret `value` by.
12369      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12370      * @returns {number} Returns the converted integer.
12371      * @example
12372      *
12373      * _.parseInt('08');
12374      * // => 8
12375      *
12376      * _.map(['6', '08', '10'], _.parseInt);
12377      * // => [6, 8, 10]
12378      */
12379     function parseInt(string, radix, guard) {
12380       // Chrome fails to trim leading <BOM> whitespace characters.
12381       // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
12382       if (guard || radix == null) {
12383         radix = 0;
12384       } else if (radix) {
12385         radix = +radix;
12386       }
12387       string = toString(string).replace(reTrim, '');
12388       return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
12389     }
12390
12391     /**
12392      * Repeats the given string `n` times.
12393      *
12394      * @static
12395      * @memberOf _
12396      * @category String
12397      * @param {string} [string=''] The string to repeat.
12398      * @param {number} [n=0] The number of times to repeat the string.
12399      * @returns {string} Returns the repeated string.
12400      * @example
12401      *
12402      * _.repeat('*', 3);
12403      * // => '***'
12404      *
12405      * _.repeat('abc', 2);
12406      * // => 'abcabc'
12407      *
12408      * _.repeat('abc', 0);
12409      * // => ''
12410      */
12411     function repeat(string, n) {
12412       string = toString(string);
12413       n = toInteger(n);
12414
12415       var result = '';
12416       if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
12417         return result;
12418       }
12419       // Leverage the exponentiation by squaring algorithm for a faster repeat.
12420       // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
12421       do {
12422         if (n % 2) {
12423           result += string;
12424         }
12425         n = nativeFloor(n / 2);
12426         string += string;
12427       } while (n);
12428
12429       return result;
12430     }
12431
12432     /**
12433      * Replaces matches for `pattern` in `string` with `replacement`.
12434      *
12435      * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace).
12436      *
12437      * @static
12438      * @memberOf _
12439      * @category String
12440      * @param {string} [string=''] The string to modify.
12441      * @param {RegExp|string} pattern The pattern to replace.
12442      * @param {Function|string} replacement The match replacement.
12443      * @returns {string} Returns the modified string.
12444      * @example
12445      *
12446      * _.replace('Hi Fred', 'Fred', 'Barney');
12447      * // => 'Hi Barney'
12448      */
12449     function replace() {
12450       var args = arguments,
12451           string = toString(args[0]);
12452
12453       return args.length < 3 ? string : string.replace(args[1], args[2]);
12454     }
12455
12456     /**
12457      * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
12458      *
12459      * @static
12460      * @memberOf _
12461      * @category String
12462      * @param {string} [string=''] The string to convert.
12463      * @returns {string} Returns the snake cased string.
12464      * @example
12465      *
12466      * _.snakeCase('Foo Bar');
12467      * // => 'foo_bar'
12468      *
12469      * _.snakeCase('fooBar');
12470      * // => 'foo_bar'
12471      *
12472      * _.snakeCase('--foo-bar');
12473      * // => 'foo_bar'
12474      */
12475     var snakeCase = createCompounder(function(result, word, index) {
12476       return result + (index ? '_' : '') + word.toLowerCase();
12477     });
12478
12479     /**
12480      * Splits `string` by `separator`.
12481      *
12482      * **Note:** This method is based on [`String#split`](https://mdn.io/String/split).
12483      *
12484      * @static
12485      * @memberOf _
12486      * @category String
12487      * @param {string} [string=''] The string to split.
12488      * @param {RegExp|string} separator The separator pattern to split by.
12489      * @param {number} [limit] The length to truncate results to.
12490      * @returns {Array} Returns the new array of string segments.
12491      * @example
12492      *
12493      * _.split('a-b-c', '-', 2);
12494      * // => ['a', 'b']
12495      */
12496     function split(string, separator, limit) {
12497       return toString(string).split(separator, limit);
12498     }
12499
12500     /**
12501      * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
12502      *
12503      * @static
12504      * @memberOf _
12505      * @category String
12506      * @param {string} [string=''] The string to convert.
12507      * @returns {string} Returns the start cased string.
12508      * @example
12509      *
12510      * _.startCase('--foo-bar');
12511      * // => 'Foo Bar'
12512      *
12513      * _.startCase('fooBar');
12514      * // => 'Foo Bar'
12515      *
12516      * _.startCase('__foo_bar__');
12517      * // => 'Foo Bar'
12518      */
12519     var startCase = createCompounder(function(result, word, index) {
12520       return result + (index ? ' ' : '') + capitalize(word);
12521     });
12522
12523     /**
12524      * Checks if `string` starts with the given target string.
12525      *
12526      * @static
12527      * @memberOf _
12528      * @category String
12529      * @param {string} [string=''] The string to search.
12530      * @param {string} [target] The string to search for.
12531      * @param {number} [position=0] The position to search from.
12532      * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`.
12533      * @example
12534      *
12535      * _.startsWith('abc', 'a');
12536      * // => true
12537      *
12538      * _.startsWith('abc', 'b');
12539      * // => false
12540      *
12541      * _.startsWith('abc', 'b', 1);
12542      * // => true
12543      */
12544     function startsWith(string, target, position) {
12545       string = toString(string);
12546       position = baseClamp(toInteger(position), 0, string.length);
12547       return string.lastIndexOf(target, position) == position;
12548     }
12549
12550     /**
12551      * Creates a compiled template function that can interpolate data properties
12552      * in "interpolate" delimiters, HTML-escape interpolated data properties in
12553      * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
12554      * properties may be accessed as free variables in the template. If a setting
12555      * object is given it takes precedence over `_.templateSettings` values.
12556      *
12557      * **Note:** In the development build `_.template` utilizes
12558      * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
12559      * for easier debugging.
12560      *
12561      * For more information on precompiling templates see
12562      * [lodash's custom builds documentation](https://lodash.com/custom-builds).
12563      *
12564      * For more information on Chrome extension sandboxes see
12565      * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
12566      *
12567      * @static
12568      * @memberOf _
12569      * @category String
12570      * @param {string} [string=''] The template string.
12571      * @param {Object} [options] The options object.
12572      * @param {RegExp} [options.escape] The HTML "escape" delimiter.
12573      * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
12574      * @param {Object} [options.imports] An object to import into the template as free variables.
12575      * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
12576      * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
12577      * @param {string} [options.variable] The data object variable name.
12578      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12579      * @returns {Function} Returns the compiled template function.
12580      * @example
12581      *
12582      * // Use the "interpolate" delimiter to create a compiled template.
12583      * var compiled = _.template('hello <%= user %>!');
12584      * compiled({ 'user': 'fred' });
12585      * // => 'hello fred!'
12586      *
12587      * // Use the HTML "escape" delimiter to escape data property values.
12588      * var compiled = _.template('<b><%- value %></b>');
12589      * compiled({ 'value': '<script>' });
12590      * // => '<b>&lt;script&gt;</b>'
12591      *
12592      * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
12593      * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
12594      * compiled({ 'users': ['fred', 'barney'] });
12595      * // => '<li>fred</li><li>barney</li>'
12596      *
12597      * // Use the internal `print` function in "evaluate" delimiters.
12598      * var compiled = _.template('<% print("hello " + user); %>!');
12599      * compiled({ 'user': 'barney' });
12600      * // => 'hello barney!'
12601      *
12602      * // Use the ES delimiter as an alternative to the default "interpolate" delimiter.
12603      * var compiled = _.template('hello ${ user }!');
12604      * compiled({ 'user': 'pebbles' });
12605      * // => 'hello pebbles!'
12606      *
12607      * // Use custom template delimiters.
12608      * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
12609      * var compiled = _.template('hello {{ user }}!');
12610      * compiled({ 'user': 'mustache' });
12611      * // => 'hello mustache!'
12612      *
12613      * // Use backslashes to treat delimiters as plain text.
12614      * var compiled = _.template('<%= "\\<%- value %\\>" %>');
12615      * compiled({ 'value': 'ignored' });
12616      * // => '<%- value %>'
12617      *
12618      * // Use the `imports` option to import `jQuery` as `jq`.
12619      * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
12620      * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
12621      * compiled({ 'users': ['fred', 'barney'] });
12622      * // => '<li>fred</li><li>barney</li>'
12623      *
12624      * // Use the `sourceURL` option to specify a custom sourceURL for the template.
12625      * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
12626      * compiled(data);
12627      * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
12628      *
12629      * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
12630      * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
12631      * compiled.source;
12632      * // => function(data) {
12633      * //   var __t, __p = '';
12634      * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
12635      * //   return __p;
12636      * // }
12637      *
12638      * // Use the `source` property to inline compiled templates for meaningful
12639      * // line numbers in error messages and stack traces.
12640      * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
12641      *   var JST = {\
12642      *     "main": ' + _.template(mainText).source + '\
12643      *   };\
12644      * ');
12645      */
12646     function template(string, options, guard) {
12647       // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)
12648       // and Laura Doktorova's doT.js (https://github.com/olado/doT).
12649       var settings = lodash.templateSettings;
12650
12651       if (guard && isIterateeCall(string, options, guard)) {
12652         options = undefined;
12653       }
12654       string = toString(string);
12655       options = assignInWith({}, options, settings, assignInDefaults);
12656
12657       var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
12658           importsKeys = keys(imports),
12659           importsValues = baseValues(imports, importsKeys);
12660
12661       var isEscaping,
12662           isEvaluating,
12663           index = 0,
12664           interpolate = options.interpolate || reNoMatch,
12665           source = "__p += '";
12666
12667       // Compile the regexp to match each delimiter.
12668       var reDelimiters = RegExp(
12669         (options.escape || reNoMatch).source + '|' +
12670         interpolate.source + '|' +
12671         (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
12672         (options.evaluate || reNoMatch).source + '|$'
12673       , 'g');
12674
12675       // Use a sourceURL for easier debugging.
12676       var sourceURL = '//# sourceURL=' +
12677         ('sourceURL' in options
12678           ? options.sourceURL
12679           : ('lodash.templateSources[' + (++templateCounter) + ']')
12680         ) + '\n';
12681
12682       string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
12683         interpolateValue || (interpolateValue = esTemplateValue);
12684
12685         // Escape characters that can't be included in string literals.
12686         source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
12687
12688         // Replace delimiters with snippets.
12689         if (escapeValue) {
12690           isEscaping = true;
12691           source += "' +\n__e(" + escapeValue + ") +\n'";
12692         }
12693         if (evaluateValue) {
12694           isEvaluating = true;
12695           source += "';\n" + evaluateValue + ";\n__p += '";
12696         }
12697         if (interpolateValue) {
12698           source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
12699         }
12700         index = offset + match.length;
12701
12702         // The JS engine embedded in Adobe products needs `match` returned in
12703         // order to produce the correct `offset` value.
12704         return match;
12705       });
12706
12707       source += "';\n";
12708
12709       // If `variable` is not specified wrap a with-statement around the generated
12710       // code to add the data object to the top of the scope chain.
12711       var variable = options.variable;
12712       if (!variable) {
12713         source = 'with (obj) {\n' + source + '\n}\n';
12714       }
12715       // Cleanup code by stripping empty strings.
12716       source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
12717         .replace(reEmptyStringMiddle, '$1')
12718         .replace(reEmptyStringTrailing, '$1;');
12719
12720       // Frame code as the function body.
12721       source = 'function(' + (variable || 'obj') + ') {\n' +
12722         (variable
12723           ? ''
12724           : 'obj || (obj = {});\n'
12725         ) +
12726         "var __t, __p = ''" +
12727         (isEscaping
12728            ? ', __e = _.escape'
12729            : ''
12730         ) +
12731         (isEvaluating
12732           ? ', __j = Array.prototype.join;\n' +
12733             "function print() { __p += __j.call(arguments, '') }\n"
12734           : ';\n'
12735         ) +
12736         source +
12737         'return __p\n}';
12738
12739       var result = attempt(function() {
12740         return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues);
12741       });
12742
12743       // Provide the compiled function's source by its `toString` method or
12744       // the `source` property as a convenience for inlining compiled templates.
12745       result.source = source;
12746       if (isError(result)) {
12747         throw result;
12748       }
12749       return result;
12750     }
12751
12752     /**
12753      * Converts `string`, as a whole, to lower case.
12754      *
12755      * @static
12756      * @memberOf _
12757      * @category String
12758      * @param {string} [string=''] The string to convert.
12759      * @returns {string} Returns the lower cased string.
12760      * @example
12761      *
12762      * _.toLower('--Foo-Bar');
12763      * // => '--foo-bar'
12764      *
12765      * _.toLower('fooBar');
12766      * // => 'foobar'
12767      *
12768      * _.toLower('__FOO_BAR__');
12769      * // => '__foo_bar__'
12770      */
12771     function toLower(value) {
12772       return toString(value).toLowerCase();
12773     }
12774
12775     /**
12776      * Converts `string`, as a whole, to upper case.
12777      *
12778      * @static
12779      * @memberOf _
12780      * @category String
12781      * @param {string} [string=''] The string to convert.
12782      * @returns {string} Returns the upper cased string.
12783      * @example
12784      *
12785      * _.toUpper('--foo-bar');
12786      * // => '--FOO-BAR'
12787      *
12788      * _.toUpper('fooBar');
12789      * // => 'FOOBAR'
12790      *
12791      * _.toUpper('__foo_bar__');
12792      * // => '__FOO_BAR__'
12793      */
12794     function toUpper(value) {
12795       return toString(value).toUpperCase();
12796     }
12797
12798     /**
12799      * Removes leading and trailing whitespace or specified characters from `string`.
12800      *
12801      * @static
12802      * @memberOf _
12803      * @category String
12804      * @param {string} [string=''] The string to trim.
12805      * @param {string} [chars=whitespace] The characters to trim.
12806      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12807      * @returns {string} Returns the trimmed string.
12808      * @example
12809      *
12810      * _.trim('  abc  ');
12811      * // => 'abc'
12812      *
12813      * _.trim('-_-abc-_-', '_-');
12814      * // => 'abc'
12815      *
12816      * _.map(['  foo  ', '  bar  '], _.trim);
12817      * // => ['foo', 'bar']
12818      */
12819     function trim(string, chars, guard) {
12820       string = toString(string);
12821       if (!string) {
12822         return string;
12823       }
12824       if (guard || chars === undefined) {
12825         return string.replace(reTrim, '');
12826       }
12827       chars = (chars + '');
12828       if (!chars) {
12829         return string;
12830       }
12831       var strSymbols = stringToArray(string),
12832           chrSymbols = stringToArray(chars);
12833
12834       return strSymbols.slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1).join('');
12835     }
12836
12837     /**
12838      * Removes trailing whitespace or specified characters from `string`.
12839      *
12840      * @static
12841      * @memberOf _
12842      * @category String
12843      * @param {string} [string=''] The string to trim.
12844      * @param {string} [chars=whitespace] The characters to trim.
12845      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12846      * @returns {string} Returns the trimmed string.
12847      * @example
12848      *
12849      * _.trimEnd('  abc  ');
12850      * // => '  abc'
12851      *
12852      * _.trimEnd('-_-abc-_-', '_-');
12853      * // => '-_-abc'
12854      */
12855     function trimEnd(string, chars, guard) {
12856       string = toString(string);
12857       if (!string) {
12858         return string;
12859       }
12860       if (guard || chars === undefined) {
12861         return string.replace(reTrimEnd, '');
12862       }
12863       chars = (chars + '');
12864       if (!chars) {
12865         return string;
12866       }
12867       var strSymbols = stringToArray(string);
12868       return strSymbols.slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1).join('');
12869     }
12870
12871     /**
12872      * Removes leading whitespace or specified characters from `string`.
12873      *
12874      * @static
12875      * @memberOf _
12876      * @category String
12877      * @param {string} [string=''] The string to trim.
12878      * @param {string} [chars=whitespace] The characters to trim.
12879      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12880      * @returns {string} Returns the trimmed string.
12881      * @example
12882      *
12883      * _.trimStart('  abc  ');
12884      * // => 'abc  '
12885      *
12886      * _.trimStart('-_-abc-_-', '_-');
12887      * // => 'abc-_-'
12888      */
12889     function trimStart(string, chars, guard) {
12890       string = toString(string);
12891       if (!string) {
12892         return string;
12893       }
12894       if (guard || chars === undefined) {
12895         return string.replace(reTrimStart, '');
12896       }
12897       chars = (chars + '');
12898       if (!chars) {
12899         return string;
12900       }
12901       var strSymbols = stringToArray(string);
12902       return strSymbols.slice(charsStartIndex(strSymbols, stringToArray(chars))).join('');
12903     }
12904
12905     /**
12906      * Truncates `string` if it's longer than the given maximum string length.
12907      * The last characters of the truncated string are replaced with the omission
12908      * string which defaults to "...".
12909      *
12910      * @static
12911      * @memberOf _
12912      * @category String
12913      * @param {string} [string=''] The string to truncate.
12914      * @param {Object} [options] The options object.
12915      * @param {number} [options.length=30] The maximum string length.
12916      * @param {string} [options.omission='...'] The string to indicate text is omitted.
12917      * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
12918      * @returns {string} Returns the truncated string.
12919      * @example
12920      *
12921      * _.truncate('hi-diddly-ho there, neighborino');
12922      * // => 'hi-diddly-ho there, neighbo...'
12923      *
12924      * _.truncate('hi-diddly-ho there, neighborino', {
12925      *   'length': 24,
12926      *   'separator': ' '
12927      * });
12928      * // => 'hi-diddly-ho there,...'
12929      *
12930      * _.truncate('hi-diddly-ho there, neighborino', {
12931      *   'length': 24,
12932      *   'separator': /,? +/
12933      * });
12934      * // => 'hi-diddly-ho there...'
12935      *
12936      * _.truncate('hi-diddly-ho there, neighborino', {
12937      *   'omission': ' [...]'
12938      * });
12939      * // => 'hi-diddly-ho there, neig [...]'
12940      */
12941     function truncate(string, options) {
12942       var length = DEFAULT_TRUNC_LENGTH,
12943           omission = DEFAULT_TRUNC_OMISSION;
12944
12945       if (isObject(options)) {
12946         var separator = 'separator' in options ? options.separator : separator;
12947         length = 'length' in options ? toInteger(options.length) : length;
12948         omission = 'omission' in options ? toString(options.omission) : omission;
12949       }
12950       string = toString(string);
12951
12952       var strLength = string.length;
12953       if (reHasComplexSymbol.test(string)) {
12954         var strSymbols = stringToArray(string);
12955         strLength = strSymbols.length;
12956       }
12957       if (length >= strLength) {
12958         return string;
12959       }
12960       var end = length - stringSize(omission);
12961       if (end < 1) {
12962         return omission;
12963       }
12964       var result = strSymbols
12965         ? strSymbols.slice(0, end).join('')
12966         : string.slice(0, end);
12967
12968       if (separator === undefined) {
12969         return result + omission;
12970       }
12971       if (strSymbols) {
12972         end += (result.length - end);
12973       }
12974       if (isRegExp(separator)) {
12975         if (string.slice(end).search(separator)) {
12976           var match,
12977               substring = result;
12978
12979           if (!separator.global) {
12980             separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
12981           }
12982           separator.lastIndex = 0;
12983           while ((match = separator.exec(substring))) {
12984             var newEnd = match.index;
12985           }
12986           result = result.slice(0, newEnd === undefined ? end : newEnd);
12987         }
12988       } else if (string.indexOf(separator, end) != end) {
12989         var index = result.lastIndexOf(separator);
12990         if (index > -1) {
12991           result = result.slice(0, index);
12992         }
12993       }
12994       return result + omission;
12995     }
12996
12997     /**
12998      * The inverse of `_.escape`; this method converts the HTML entities
12999      * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to their
13000      * corresponding characters.
13001      *
13002      * **Note:** No other HTML entities are unescaped. To unescape additional HTML
13003      * entities use a third-party library like [_he_](https://mths.be/he).
13004      *
13005      * @static
13006      * @memberOf _
13007      * @category String
13008      * @param {string} [string=''] The string to unescape.
13009      * @returns {string} Returns the unescaped string.
13010      * @example
13011      *
13012      * _.unescape('fred, barney, &amp; pebbles');
13013      * // => 'fred, barney, & pebbles'
13014      */
13015     function unescape(string) {
13016       string = toString(string);
13017       return (string && reHasEscapedHtml.test(string))
13018         ? string.replace(reEscapedHtml, unescapeHtmlChar)
13019         : string;
13020     }
13021
13022     /**
13023      * Converts `string`, as space separated words, to upper case.
13024      *
13025      * @static
13026      * @memberOf _
13027      * @category String
13028      * @param {string} [string=''] The string to convert.
13029      * @returns {string} Returns the upper cased string.
13030      * @example
13031      *
13032      * _.upperCase('--foo-bar');
13033      * // => 'FOO BAR'
13034      *
13035      * _.upperCase('fooBar');
13036      * // => 'FOO BAR'
13037      *
13038      * _.upperCase('__foo_bar__');
13039      * // => 'FOO BAR'
13040      */
13041     var upperCase = createCompounder(function(result, word, index) {
13042       return result + (index ? ' ' : '') + word.toUpperCase();
13043     });
13044
13045     /**
13046      * Splits `string` into an array of its words.
13047      *
13048      * @static
13049      * @memberOf _
13050      * @category String
13051      * @param {string} [string=''] The string to inspect.
13052      * @param {RegExp|string} [pattern] The pattern to match words.
13053      * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
13054      * @returns {Array} Returns the words of `string`.
13055      * @example
13056      *
13057      * _.words('fred, barney, & pebbles');
13058      * // => ['fred', 'barney', 'pebbles']
13059      *
13060      * _.words('fred, barney, & pebbles', /[^, ]+/g);
13061      * // => ['fred', 'barney', '&', 'pebbles']
13062      */
13063     function words(string, pattern, guard) {
13064       string = toString(string);
13065       pattern = guard ? undefined : pattern;
13066
13067       if (pattern === undefined) {
13068         pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
13069       }
13070       return string.match(pattern) || [];
13071     }
13072
13073     /*------------------------------------------------------------------------*/
13074
13075     /**
13076      * Attempts to invoke `func`, returning either the result or the caught error
13077      * object. Any additional arguments are provided to `func` when it's invoked.
13078      *
13079      * @static
13080      * @memberOf _
13081      * @category Util
13082      * @param {Function} func The function to attempt.
13083      * @returns {*} Returns the `func` result or error object.
13084      * @example
13085      *
13086      * // Avoid throwing errors for invalid selectors.
13087      * var elements = _.attempt(function(selector) {
13088      *   return document.querySelectorAll(selector);
13089      * }, '>_>');
13090      *
13091      * if (_.isError(elements)) {
13092      *   elements = [];
13093      * }
13094      */
13095     var attempt = rest(function(func, args) {
13096       try {
13097         return apply(func, undefined, args);
13098       } catch (e) {
13099         return isObject(e) ? e : new Error(e);
13100       }
13101     });
13102
13103     /**
13104      * Binds methods of an object to the object itself, overwriting the existing
13105      * method.
13106      *
13107      * **Note:** This method doesn't set the "length" property of bound functions.
13108      *
13109      * @static
13110      * @memberOf _
13111      * @category Util
13112      * @param {Object} object The object to bind and assign the bound methods to.
13113      * @param {...(string|string[])} methodNames The object method names to bind,
13114      *  specified individually or in arrays.
13115      * @returns {Object} Returns `object`.
13116      * @example
13117      *
13118      * var view = {
13119      *   'label': 'docs',
13120      *   'onClick': function() {
13121      *     console.log('clicked ' + this.label);
13122      *   }
13123      * };
13124      *
13125      * _.bindAll(view, 'onClick');
13126      * jQuery(element).on('click', view.onClick);
13127      * // => logs 'clicked docs' when clicked
13128      */
13129     var bindAll = rest(function(object, methodNames) {
13130       arrayEach(baseFlatten(methodNames), function(key) {
13131         object[key] = bind(object[key], object);
13132       });
13133       return object;
13134     });
13135
13136     /**
13137      * Creates a function that iterates over `pairs` invoking the corresponding
13138      * function of the first predicate to return truthy. The predicate-function
13139      * pairs are invoked with the `this` binding and arguments of the created
13140      * function.
13141      *
13142      * @static
13143      * @memberOf _
13144      * @category Util
13145      * @param {Array} pairs The predicate-function pairs.
13146      * @returns {Function} Returns the new function.
13147      * @example
13148      *
13149      * var func = _.cond([
13150      *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
13151      *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
13152      *   [_.constant(true),                _.constant('no match')]
13153      * ]);
13154      *
13155      * func({ 'a': 1, 'b': 2 });
13156      * // => 'matches A'
13157      *
13158      * func({ 'a': 0, 'b': 1 });
13159      * // => 'matches B'
13160      *
13161      * func({ 'a': '1', 'b': '2' });
13162      * // => 'no match'
13163      */
13164     function cond(pairs) {
13165       var length = pairs ? pairs.length : 0,
13166           toIteratee = getIteratee();
13167
13168       pairs = !length ? [] : arrayMap(pairs, function(pair) {
13169         if (typeof pair[1] != 'function') {
13170           throw new TypeError(FUNC_ERROR_TEXT);
13171         }
13172         return [toIteratee(pair[0]), pair[1]];
13173       });
13174
13175       return rest(function(args) {
13176         var index = -1;
13177         while (++index < length) {
13178           var pair = pairs[index];
13179           if (apply(pair[0], this, args)) {
13180             return apply(pair[1], this, args);
13181           }
13182         }
13183       });
13184     }
13185
13186     /**
13187      * Creates a function that invokes the predicate properties of `source` with
13188      * the corresponding property values of a given object, returning `true` if
13189      * all predicates return truthy, else `false`.
13190      *
13191      * @static
13192      * @memberOf _
13193      * @category Util
13194      * @param {Object} source The object of property predicates to conform to.
13195      * @returns {Function} Returns the new function.
13196      * @example
13197      *
13198      * var users = [
13199      *   { 'user': 'barney', 'age': 36 },
13200      *   { 'user': 'fred',   'age': 40 }
13201      * ];
13202      *
13203      * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
13204      * // => [{ 'user': 'fred', 'age': 40 }]
13205      */
13206     function conforms(source) {
13207       return baseConforms(baseClone(source, true));
13208     }
13209
13210     /**
13211      * Creates a function that returns `value`.
13212      *
13213      * @static
13214      * @memberOf _
13215      * @category Util
13216      * @param {*} value The value to return from the new function.
13217      * @returns {Function} Returns the new function.
13218      * @example
13219      *
13220      * var object = { 'user': 'fred' };
13221      * var getter = _.constant(object);
13222      *
13223      * getter() === object;
13224      * // => true
13225      */
13226     function constant(value) {
13227       return function() {
13228         return value;
13229       };
13230     }
13231
13232     /**
13233      * Creates a function that returns the result of invoking the given functions
13234      * with the `this` binding of the created function, where each successive
13235      * invocation is supplied the return value of the previous.
13236      *
13237      * @static
13238      * @memberOf _
13239      * @category Util
13240      * @param {...(Function|Function[])} [funcs] Functions to invoke.
13241      * @returns {Function} Returns the new function.
13242      * @example
13243      *
13244      * function square(n) {
13245      *   return n * n;
13246      * }
13247      *
13248      * var addSquare = _.flow(_.add, square);
13249      * addSquare(1, 2);
13250      * // => 9
13251      */
13252     var flow = createFlow();
13253
13254     /**
13255      * This method is like `_.flow` except that it creates a function that
13256      * invokes the given functions from right to left.
13257      *
13258      * @static
13259      * @memberOf _
13260      * @category Util
13261      * @param {...(Function|Function[])} [funcs] Functions to invoke.
13262      * @returns {Function} Returns the new function.
13263      * @example
13264      *
13265      * function square(n) {
13266      *   return n * n;
13267      * }
13268      *
13269      * var addSquare = _.flowRight(square, _.add);
13270      * addSquare(1, 2);
13271      * // => 9
13272      */
13273     var flowRight = createFlow(true);
13274
13275     /**
13276      * This method returns the first argument given to it.
13277      *
13278      * @static
13279      * @memberOf _
13280      * @category Util
13281      * @param {*} value Any value.
13282      * @returns {*} Returns `value`.
13283      * @example
13284      *
13285      * var object = { 'user': 'fred' };
13286      *
13287      * _.identity(object) === object;
13288      * // => true
13289      */
13290     function identity(value) {
13291       return value;
13292     }
13293
13294     /**
13295      * Creates a function that invokes `func` with the arguments of the created
13296      * function. If `func` is a property name the created callback returns the
13297      * property value for a given element. If `func` is an object the created
13298      * callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`.
13299      *
13300      * @static
13301      * @memberOf _
13302      * @category Util
13303      * @param {*} [func=_.identity] The value to convert to a callback.
13304      * @returns {Function} Returns the callback.
13305      * @example
13306      *
13307      * var users = [
13308      *   { 'user': 'barney', 'age': 36 },
13309      *   { 'user': 'fred',   'age': 40 }
13310      * ];
13311      *
13312      * // Create custom iteratee shorthands.
13313      * _.iteratee = _.wrap(_.iteratee, function(callback, func) {
13314      *   var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func);
13315      *   return !p ? callback(func) : function(object) {
13316      *     return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]);
13317      *   };
13318      * });
13319      *
13320      * _.filter(users, 'age > 36');
13321      * // => [{ 'user': 'fred', 'age': 40 }]
13322      */
13323     function iteratee(func) {
13324       return baseIteratee(typeof func == 'function' ? func : baseClone(func, true));
13325     }
13326
13327     /**
13328      * Creates a function that performs a deep partial comparison between a given
13329      * object and `source`, returning `true` if the given object has equivalent
13330      * property values, else `false`.
13331      *
13332      * **Note:** This method supports comparing the same values as `_.isEqual`.
13333      *
13334      * @static
13335      * @memberOf _
13336      * @category Util
13337      * @param {Object} source The object of property values to match.
13338      * @returns {Function} Returns the new function.
13339      * @example
13340      *
13341      * var users = [
13342      *   { 'user': 'barney', 'age': 36, 'active': true },
13343      *   { 'user': 'fred',   'age': 40, 'active': false }
13344      * ];
13345      *
13346      * _.filter(users, _.matches({ 'age': 40, 'active': false }));
13347      * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
13348      */
13349     function matches(source) {
13350       return baseMatches(baseClone(source, true));
13351     }
13352
13353     /**
13354      * Creates a function that performs a deep partial comparison between the
13355      * value at `path` of a given object to `srcValue`, returning `true` if the
13356      * object value is equivalent, else `false`.
13357      *
13358      * **Note:** This method supports comparing the same values as `_.isEqual`.
13359      *
13360      * @static
13361      * @memberOf _
13362      * @category Util
13363      * @param {Array|string} path The path of the property to get.
13364      * @param {*} srcValue The value to match.
13365      * @returns {Function} Returns the new function.
13366      * @example
13367      *
13368      * var users = [
13369      *   { 'user': 'barney' },
13370      *   { 'user': 'fred' }
13371      * ];
13372      *
13373      * _.find(users, _.matchesProperty('user', 'fred'));
13374      * // => { 'user': 'fred' }
13375      */
13376     function matchesProperty(path, srcValue) {
13377       return baseMatchesProperty(path, baseClone(srcValue, true));
13378     }
13379
13380     /**
13381      * Creates a function that invokes the method at `path` of a given object.
13382      * Any additional arguments are provided to the invoked method.
13383      *
13384      * @static
13385      * @memberOf _
13386      * @category Util
13387      * @param {Array|string} path The path of the method to invoke.
13388      * @param {...*} [args] The arguments to invoke the method with.
13389      * @returns {Function} Returns the new function.
13390      * @example
13391      *
13392      * var objects = [
13393      *   { 'a': { 'b': { 'c': _.constant(2) } } },
13394      *   { 'a': { 'b': { 'c': _.constant(1) } } }
13395      * ];
13396      *
13397      * _.map(objects, _.method('a.b.c'));
13398      * // => [2, 1]
13399      *
13400      * _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
13401      * // => [1, 2]
13402      */
13403     var method = rest(function(path, args) {
13404       return function(object) {
13405         return baseInvoke(object, path, args);
13406       };
13407     });
13408
13409     /**
13410      * The opposite of `_.method`; this method creates a function that invokes
13411      * the method at a given path of `object`. Any additional arguments are
13412      * provided to the invoked method.
13413      *
13414      * @static
13415      * @memberOf _
13416      * @category Util
13417      * @param {Object} object The object to query.
13418      * @param {...*} [args] The arguments to invoke the method with.
13419      * @returns {Function} Returns the new function.
13420      * @example
13421      *
13422      * var array = _.times(3, _.constant),
13423      *     object = { 'a': array, 'b': array, 'c': array };
13424      *
13425      * _.map(['a[2]', 'c[0]'], _.methodOf(object));
13426      * // => [2, 0]
13427      *
13428      * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
13429      * // => [2, 0]
13430      */
13431     var methodOf = rest(function(object, args) {
13432       return function(path) {
13433         return baseInvoke(object, path, args);
13434       };
13435     });
13436
13437     /**
13438      * Adds all own enumerable function properties of a source object to the
13439      * destination object. If `object` is a function then methods are added to
13440      * its prototype as well.
13441      *
13442      * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
13443      * avoid conflicts caused by modifying the original.
13444      *
13445      * @static
13446      * @memberOf _
13447      * @category Util
13448      * @param {Function|Object} [object=lodash] The destination object.
13449      * @param {Object} source The object of functions to add.
13450      * @param {Object} [options] The options object.
13451      * @param {boolean} [options.chain=true] Specify whether the functions added
13452      *  are chainable.
13453      * @returns {Function|Object} Returns `object`.
13454      * @example
13455      *
13456      * function vowels(string) {
13457      *   return _.filter(string, function(v) {
13458      *     return /[aeiou]/i.test(v);
13459      *   });
13460      * }
13461      *
13462      * _.mixin({ 'vowels': vowels });
13463      * _.vowels('fred');
13464      * // => ['e']
13465      *
13466      * _('fred').vowels().value();
13467      * // => ['e']
13468      *
13469      * _.mixin({ 'vowels': vowels }, { 'chain': false });
13470      * _('fred').vowels();
13471      * // => ['e']
13472      */
13473     function mixin(object, source, options) {
13474       var props = keys(source),
13475           methodNames = baseFunctions(source, props);
13476
13477       if (options == null &&
13478           !(isObject(source) && (methodNames.length || !props.length))) {
13479         options = source;
13480         source = object;
13481         object = this;
13482         methodNames = baseFunctions(source, keys(source));
13483       }
13484       var chain = (isObject(options) && 'chain' in options) ? options.chain : true,
13485           isFunc = isFunction(object);
13486
13487       arrayEach(methodNames, function(methodName) {
13488         var func = source[methodName];
13489         object[methodName] = func;
13490         if (isFunc) {
13491           object.prototype[methodName] = function() {
13492             var chainAll = this.__chain__;
13493             if (chain || chainAll) {
13494               var result = object(this.__wrapped__),
13495                   actions = result.__actions__ = copyArray(this.__actions__);
13496
13497               actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
13498               result.__chain__ = chainAll;
13499               return result;
13500             }
13501             return func.apply(object, arrayPush([this.value()], arguments));
13502           };
13503         }
13504       });
13505
13506       return object;
13507     }
13508
13509     /**
13510      * Reverts the `_` variable to its previous value and returns a reference to
13511      * the `lodash` function.
13512      *
13513      * @static
13514      * @memberOf _
13515      * @category Util
13516      * @returns {Function} Returns the `lodash` function.
13517      * @example
13518      *
13519      * var lodash = _.noConflict();
13520      */
13521     function noConflict() {
13522       if (root._ === this) {
13523         root._ = oldDash;
13524       }
13525       return this;
13526     }
13527
13528     /**
13529      * A no-operation function that returns `undefined` regardless of the
13530      * arguments it receives.
13531      *
13532      * @static
13533      * @memberOf _
13534      * @category Util
13535      * @example
13536      *
13537      * var object = { 'user': 'fred' };
13538      *
13539      * _.noop(object) === undefined;
13540      * // => true
13541      */
13542     function noop() {
13543       // No operation performed.
13544     }
13545
13546     /**
13547      * Creates a function that returns its nth argument.
13548      *
13549      * @static
13550      * @memberOf _
13551      * @category Util
13552      * @param {number} [n=0] The index of the argument to return.
13553      * @returns {Function} Returns the new function.
13554      * @example
13555      *
13556      * var func = _.nthArg(1);
13557      *
13558      * func('a', 'b', 'c');
13559      * // => 'b'
13560      */
13561     function nthArg(n) {
13562       n = toInteger(n);
13563       return function() {
13564         return arguments[n];
13565       };
13566     }
13567
13568     /**
13569      * Creates a function that invokes `iteratees` with the arguments provided
13570      * to the created function and returns their results.
13571      *
13572      * @static
13573      * @memberOf _
13574      * @category Util
13575      * @param {...(Function|Function[])} iteratees The iteratees to invoke.
13576      * @returns {Function} Returns the new function.
13577      * @example
13578      *
13579      * var func = _.over(Math.max, Math.min);
13580      *
13581      * func(1, 2, 3, 4);
13582      * // => [4, 1]
13583      */
13584     var over = createOver(arrayMap);
13585
13586     /**
13587      * Creates a function that checks if **all** of the `predicates` return
13588      * truthy when invoked with the arguments provided to the created function.
13589      *
13590      * @static
13591      * @memberOf _
13592      * @category Util
13593      * @param {...(Function|Function[])} predicates The predicates to check.
13594      * @returns {Function} Returns the new function.
13595      * @example
13596      *
13597      * var func = _.overEvery(Boolean, isFinite);
13598      *
13599      * func('1');
13600      * // => true
13601      *
13602      * func(null);
13603      * // => false
13604      *
13605      * func(NaN);
13606      * // => false
13607      */
13608     var overEvery = createOver(arrayEvery);
13609
13610     /**
13611      * Creates a function that checks if **any** of the `predicates` return
13612      * truthy when invoked with the arguments provided to the created function.
13613      *
13614      * @static
13615      * @memberOf _
13616      * @category Util
13617      * @param {...(Function|Function[])} predicates The predicates to check.
13618      * @returns {Function} Returns the new function.
13619      * @example
13620      *
13621      * var func = _.overSome(Boolean, isFinite);
13622      *
13623      * func('1');
13624      * // => true
13625      *
13626      * func(null);
13627      * // => true
13628      *
13629      * func(NaN);
13630      * // => false
13631      */
13632     var overSome = createOver(arraySome);
13633
13634     /**
13635      * Creates a function that returns the value at `path` of a given object.
13636      *
13637      * @static
13638      * @memberOf _
13639      * @category Util
13640      * @param {Array|string} path The path of the property to get.
13641      * @returns {Function} Returns the new function.
13642      * @example
13643      *
13644      * var objects = [
13645      *   { 'a': { 'b': { 'c': 2 } } },
13646      *   { 'a': { 'b': { 'c': 1 } } }
13647      * ];
13648      *
13649      * _.map(objects, _.property('a.b.c'));
13650      * // => [2, 1]
13651      *
13652      * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
13653      * // => [1, 2]
13654      */
13655     function property(path) {
13656       return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
13657     }
13658
13659     /**
13660      * The opposite of `_.property`; this method creates a function that returns
13661      * the value at a given path of `object`.
13662      *
13663      * @static
13664      * @memberOf _
13665      * @category Util
13666      * @param {Object} object The object to query.
13667      * @returns {Function} Returns the new function.
13668      * @example
13669      *
13670      * var array = [0, 1, 2],
13671      *     object = { 'a': array, 'b': array, 'c': array };
13672      *
13673      * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
13674      * // => [2, 0]
13675      *
13676      * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
13677      * // => [2, 0]
13678      */
13679     function propertyOf(object) {
13680       return function(path) {
13681         return object == null ? undefined : baseGet(object, path);
13682       };
13683     }
13684
13685     /**
13686      * Creates an array of numbers (positive and/or negative) progressing from
13687      * `start` up to, but not including, `end`. A step of `-1` is used if a negative
13688      * `start` is specified without an `end` or `step`. If `end` is not specified
13689      * it's set to `start` with `start` then set to `0`.
13690      *
13691      * **Note:** JavaScript follows the IEEE-754 standard for resolving
13692      * floating-point values which can produce unexpected results.
13693      *
13694      * @static
13695      * @memberOf _
13696      * @category Util
13697      * @param {number} [start=0] The start of the range.
13698      * @param {number} end The end of the range.
13699      * @param {number} [step=1] The value to increment or decrement by.
13700      * @returns {Array} Returns the new array of numbers.
13701      * @example
13702      *
13703      * _.range(4);
13704      * // => [0, 1, 2, 3]
13705      *
13706      * _.range(-4);
13707      * // => [0, -1, -2, -3]
13708      *
13709      * _.range(1, 5);
13710      * // => [1, 2, 3, 4]
13711      *
13712      * _.range(0, 20, 5);
13713      * // => [0, 5, 10, 15]
13714      *
13715      * _.range(0, -4, -1);
13716      * // => [0, -1, -2, -3]
13717      *
13718      * _.range(1, 4, 0);
13719      * // => [1, 1, 1]
13720      *
13721      * _.range(0);
13722      * // => []
13723      */
13724     var range = createRange();
13725
13726     /**
13727      * This method is like `_.range` except that it populates values in
13728      * descending order.
13729      *
13730      * @static
13731      * @memberOf _
13732      * @category Util
13733      * @param {number} [start=0] The start of the range.
13734      * @param {number} end The end of the range.
13735      * @param {number} [step=1] The value to increment or decrement by.
13736      * @returns {Array} Returns the new array of numbers.
13737      * @example
13738      *
13739      * _.rangeRight(4);
13740      * // => [3, 2, 1, 0]
13741      *
13742      * _.rangeRight(-4);
13743      * // => [-3, -2, -1, 0]
13744      *
13745      * _.rangeRight(1, 5);
13746      * // => [4, 3, 2, 1]
13747      *
13748      * _.rangeRight(0, 20, 5);
13749      * // => [15, 10, 5, 0]
13750      *
13751      * _.rangeRight(0, -4, -1);
13752      * // => [-3, -2, -1, 0]
13753      *
13754      * _.rangeRight(1, 4, 0);
13755      * // => [1, 1, 1]
13756      *
13757      * _.rangeRight(0);
13758      * // => []
13759      */
13760     var rangeRight = createRange(true);
13761
13762     /**
13763      * Invokes the iteratee function `n` times, returning an array of the results
13764      * of each invocation. The iteratee is invoked with one argument; (index).
13765      *
13766      * @static
13767      * @memberOf _
13768      * @category Util
13769      * @param {number} n The number of times to invoke `iteratee`.
13770      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13771      * @returns {Array} Returns the array of results.
13772      * @example
13773      *
13774      * _.times(3, String);
13775      * // => ['0', '1', '2']
13776      *
13777      *  _.times(4, _.constant(true));
13778      * // => [true, true, true, true]
13779      */
13780     function times(n, iteratee) {
13781       n = toInteger(n);
13782       if (n < 1 || n > MAX_SAFE_INTEGER) {
13783         return [];
13784       }
13785       var index = MAX_ARRAY_LENGTH,
13786           length = nativeMin(n, MAX_ARRAY_LENGTH);
13787
13788       iteratee = toFunction(iteratee);
13789       n -= MAX_ARRAY_LENGTH;
13790
13791       var result = baseTimes(length, iteratee);
13792       while (++index < n) {
13793         iteratee(index);
13794       }
13795       return result;
13796     }
13797
13798     /**
13799      * Converts `value` to a property path array.
13800      *
13801      * @static
13802      * @memberOf _
13803      * @category Util
13804      * @param {*} value The value to convert.
13805      * @returns {Array} Returns the new property path array.
13806      * @example
13807      *
13808      * _.toPath('a.b.c');
13809      * // => ['a', 'b', 'c']
13810      *
13811      * _.toPath('a[0].b.c');
13812      * // => ['a', '0', 'b', 'c']
13813      *
13814      * var path = ['a', 'b', 'c'],
13815      *     newPath = _.toPath(path);
13816      *
13817      * console.log(newPath);
13818      * // => ['a', 'b', 'c']
13819      *
13820      * console.log(path === newPath);
13821      * // => false
13822      */
13823     function toPath(value) {
13824       return isArray(value) ? arrayMap(value, String) : stringToPath(value);
13825     }
13826
13827     /**
13828      * Generates a unique ID. If `prefix` is given the ID is appended to it.
13829      *
13830      * @static
13831      * @memberOf _
13832      * @category Util
13833      * @param {string} [prefix] The value to prefix the ID with.
13834      * @returns {string} Returns the unique ID.
13835      * @example
13836      *
13837      * _.uniqueId('contact_');
13838      * // => 'contact_104'
13839      *
13840      * _.uniqueId();
13841      * // => '105'
13842      */
13843     function uniqueId(prefix) {
13844       var id = ++idCounter;
13845       return toString(prefix) + id;
13846     }
13847
13848     /*------------------------------------------------------------------------*/
13849
13850     /**
13851      * Adds two numbers.
13852      *
13853      * @static
13854      * @memberOf _
13855      * @category Math
13856      * @param {number} augend The first number in an addition.
13857      * @param {number} addend The second number in an addition.
13858      * @returns {number} Returns the total.
13859      * @example
13860      *
13861      * _.add(6, 4);
13862      * // => 10
13863      */
13864     function add(augend, addend) {
13865       var result;
13866       if (augend === undefined && addend === undefined) {
13867         return 0;
13868       }
13869       if (augend !== undefined) {
13870         result = augend;
13871       }
13872       if (addend !== undefined) {
13873         result = result === undefined ? addend : (result + addend);
13874       }
13875       return result;
13876     }
13877
13878     /**
13879      * Computes `number` rounded up to `precision`.
13880      *
13881      * @static
13882      * @memberOf _
13883      * @category Math
13884      * @param {number} number The number to round up.
13885      * @param {number} [precision=0] The precision to round up to.
13886      * @returns {number} Returns the rounded up number.
13887      * @example
13888      *
13889      * _.ceil(4.006);
13890      * // => 5
13891      *
13892      * _.ceil(6.004, 2);
13893      * // => 6.01
13894      *
13895      * _.ceil(6040, -2);
13896      * // => 6100
13897      */
13898     var ceil = createRound('ceil');
13899
13900     /**
13901      * Computes `number` rounded down to `precision`.
13902      *
13903      * @static
13904      * @memberOf _
13905      * @category Math
13906      * @param {number} number The number to round down.
13907      * @param {number} [precision=0] The precision to round down to.
13908      * @returns {number} Returns the rounded down number.
13909      * @example
13910      *
13911      * _.floor(4.006);
13912      * // => 4
13913      *
13914      * _.floor(0.046, 2);
13915      * // => 0.04
13916      *
13917      * _.floor(4060, -2);
13918      * // => 4000
13919      */
13920     var floor = createRound('floor');
13921
13922     /**
13923      * Computes the maximum value of `array`. If `array` is empty or falsey
13924      * `undefined` is returned.
13925      *
13926      * @static
13927      * @memberOf _
13928      * @category Math
13929      * @param {Array} array The array to iterate over.
13930      * @returns {*} Returns the maximum value.
13931      * @example
13932      *
13933      * _.max([4, 2, 8, 6]);
13934      * // => 8
13935      *
13936      * _.max([]);
13937      * // => undefined
13938      */
13939     function max(array) {
13940       return (array && array.length)
13941         ? baseExtremum(array, identity, gt)
13942         : undefined;
13943     }
13944
13945     /**
13946      * This method is like `_.max` except that it accepts `iteratee` which is
13947      * invoked for each element in `array` to generate the criterion by which
13948      * the value is ranked. The iteratee is invoked with one argument: (value).
13949      *
13950      * @static
13951      * @memberOf _
13952      * @category Math
13953      * @param {Array} array The array to iterate over.
13954      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
13955      * @returns {*} Returns the maximum value.
13956      * @example
13957      *
13958      * var objects = [{ 'n': 1 }, { 'n': 2 }];
13959      *
13960      * _.maxBy(objects, function(o) { return o.n; });
13961      * // => { 'n': 2 }
13962      *
13963      * // The `_.property` iteratee shorthand.
13964      * _.maxBy(objects, 'n');
13965      * // => { 'n': 2 }
13966      */
13967     function maxBy(array, iteratee) {
13968       return (array && array.length)
13969         ? baseExtremum(array, getIteratee(iteratee), gt)
13970         : undefined;
13971     }
13972
13973     /**
13974      * Computes the mean of the values in `array`.
13975      *
13976      * @static
13977      * @memberOf _
13978      * @category Math
13979      * @param {Array} array The array to iterate over.
13980      * @returns {number} Returns the mean.
13981      * @example
13982      *
13983      * _.mean([4, 2, 8, 6]);
13984      * // => 5
13985      */
13986     function mean(array) {
13987       return sum(array) / (array ? array.length : 0);
13988     }
13989
13990     /**
13991      * Computes the minimum value of `array`. If `array` is empty or falsey
13992      * `undefined` is returned.
13993      *
13994      * @static
13995      * @memberOf _
13996      * @category Math
13997      * @param {Array} array The array to iterate over.
13998      * @returns {*} Returns the minimum value.
13999      * @example
14000      *
14001      * _.min([4, 2, 8, 6]);
14002      * // => 2
14003      *
14004      * _.min([]);
14005      * // => undefined
14006      */
14007     function min(array) {
14008       return (array && array.length)
14009         ? baseExtremum(array, identity, lt)
14010         : undefined;
14011     }
14012
14013     /**
14014      * This method is like `_.min` except that it accepts `iteratee` which is
14015      * invoked for each element in `array` to generate the criterion by which
14016      * the value is ranked. The iteratee is invoked with one argument: (value).
14017      *
14018      * @static
14019      * @memberOf _
14020      * @category Math
14021      * @param {Array} array The array to iterate over.
14022      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
14023      * @returns {*} Returns the minimum value.
14024      * @example
14025      *
14026      * var objects = [{ 'n': 1 }, { 'n': 2 }];
14027      *
14028      * _.minBy(objects, function(o) { return o.n; });
14029      * // => { 'n': 1 }
14030      *
14031      * // The `_.property` iteratee shorthand.
14032      * _.minBy(objects, 'n');
14033      * // => { 'n': 1 }
14034      */
14035     function minBy(array, iteratee) {
14036       return (array && array.length)
14037         ? baseExtremum(array, getIteratee(iteratee), lt)
14038         : undefined;
14039     }
14040
14041     /**
14042      * Computes `number` rounded to `precision`.
14043      *
14044      * @static
14045      * @memberOf _
14046      * @category Math
14047      * @param {number} number The number to round.
14048      * @param {number} [precision=0] The precision to round to.
14049      * @returns {number} Returns the rounded number.
14050      * @example
14051      *
14052      * _.round(4.006);
14053      * // => 4
14054      *
14055      * _.round(4.006, 2);
14056      * // => 4.01
14057      *
14058      * _.round(4060, -2);
14059      * // => 4100
14060      */
14061     var round = createRound('round');
14062
14063     /**
14064      * Subtract two numbers.
14065      *
14066      * @static
14067      * @memberOf _
14068      * @category Math
14069      * @param {number} minuend The first number in a subtraction.
14070      * @param {number} subtrahend The second number in a subtraction.
14071      * @returns {number} Returns the difference.
14072      * @example
14073      *
14074      * _.subtract(6, 4);
14075      * // => 2
14076      */
14077     function subtract(minuend, subtrahend) {
14078       var result;
14079       if (minuend === undefined && subtrahend === undefined) {
14080         return 0;
14081       }
14082       if (minuend !== undefined) {
14083         result = minuend;
14084       }
14085       if (subtrahend !== undefined) {
14086         result = result === undefined ? subtrahend : (result - subtrahend);
14087       }
14088       return result;
14089     }
14090
14091     /**
14092      * Computes the sum of the values in `array`.
14093      *
14094      * @static
14095      * @memberOf _
14096      * @category Math
14097      * @param {Array} array The array to iterate over.
14098      * @returns {number} Returns the sum.
14099      * @example
14100      *
14101      * _.sum([4, 2, 8, 6]);
14102      * // => 20
14103      */
14104     function sum(array) {
14105       return (array && array.length)
14106         ? baseSum(array, identity)
14107         : 0;
14108     }
14109
14110     /**
14111      * This method is like `_.sum` except that it accepts `iteratee` which is
14112      * invoked for each element in `array` to generate the value to be summed.
14113      * The iteratee is invoked with one argument: (value).
14114      *
14115      * @static
14116      * @memberOf _
14117      * @category Math
14118      * @param {Array} array The array to iterate over.
14119      * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
14120      * @returns {number} Returns the sum.
14121      * @example
14122      *
14123      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
14124      *
14125      * _.sumBy(objects, function(o) { return o.n; });
14126      * // => 20
14127      *
14128      * // The `_.property` iteratee shorthand.
14129      * _.sumBy(objects, 'n');
14130      * // => 20
14131      */
14132     function sumBy(array, iteratee) {
14133       return (array && array.length)
14134         ? baseSum(array, getIteratee(iteratee))
14135         : 0;
14136     }
14137
14138     /*------------------------------------------------------------------------*/
14139
14140     // Ensure wrappers are instances of `baseLodash`.
14141     lodash.prototype = baseLodash.prototype;
14142
14143     LodashWrapper.prototype = baseCreate(baseLodash.prototype);
14144     LodashWrapper.prototype.constructor = LodashWrapper;
14145
14146     LazyWrapper.prototype = baseCreate(baseLodash.prototype);
14147     LazyWrapper.prototype.constructor = LazyWrapper;
14148
14149     // Avoid inheriting from `Object.prototype` when possible.
14150     Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
14151
14152     // Add functions to the `MapCache`.
14153     MapCache.prototype.clear = mapClear;
14154     MapCache.prototype['delete'] = mapDelete;
14155     MapCache.prototype.get = mapGet;
14156     MapCache.prototype.has = mapHas;
14157     MapCache.prototype.set = mapSet;
14158
14159     // Add functions to the `SetCache`.
14160     SetCache.prototype.push = cachePush;
14161
14162     // Add functions to the `Stack` cache.
14163     Stack.prototype.clear = stackClear;
14164     Stack.prototype['delete'] = stackDelete;
14165     Stack.prototype.get = stackGet;
14166     Stack.prototype.has = stackHas;
14167     Stack.prototype.set = stackSet;
14168
14169     // Assign cache to `_.memoize`.
14170     memoize.Cache = MapCache;
14171
14172     // Add functions that return wrapped values when chaining.
14173     lodash.after = after;
14174     lodash.ary = ary;
14175     lodash.assign = assign;
14176     lodash.assignIn = assignIn;
14177     lodash.assignInWith = assignInWith;
14178     lodash.assignWith = assignWith;
14179     lodash.at = at;
14180     lodash.before = before;
14181     lodash.bind = bind;
14182     lodash.bindAll = bindAll;
14183     lodash.bindKey = bindKey;
14184     lodash.chain = chain;
14185     lodash.chunk = chunk;
14186     lodash.compact = compact;
14187     lodash.concat = concat;
14188     lodash.cond = cond;
14189     lodash.conforms = conforms;
14190     lodash.constant = constant;
14191     lodash.countBy = countBy;
14192     lodash.create = create;
14193     lodash.curry = curry;
14194     lodash.curryRight = curryRight;
14195     lodash.debounce = debounce;
14196     lodash.defaults = defaults;
14197     lodash.defaultsDeep = defaultsDeep;
14198     lodash.defer = defer;
14199     lodash.delay = delay;
14200     lodash.difference = difference;
14201     lodash.differenceBy = differenceBy;
14202     lodash.differenceWith = differenceWith;
14203     lodash.drop = drop;
14204     lodash.dropRight = dropRight;
14205     lodash.dropRightWhile = dropRightWhile;
14206     lodash.dropWhile = dropWhile;
14207     lodash.fill = fill;
14208     lodash.filter = filter;
14209     lodash.flatMap = flatMap;
14210     lodash.flatten = flatten;
14211     lodash.flattenDeep = flattenDeep;
14212     lodash.flip = flip;
14213     lodash.flow = flow;
14214     lodash.flowRight = flowRight;
14215     lodash.fromPairs = fromPairs;
14216     lodash.functions = functions;
14217     lodash.functionsIn = functionsIn;
14218     lodash.groupBy = groupBy;
14219     lodash.initial = initial;
14220     lodash.intersection = intersection;
14221     lodash.intersectionBy = intersectionBy;
14222     lodash.intersectionWith = intersectionWith;
14223     lodash.invert = invert;
14224     lodash.invertBy = invertBy;
14225     lodash.invokeMap = invokeMap;
14226     lodash.iteratee = iteratee;
14227     lodash.keyBy = keyBy;
14228     lodash.keys = keys;
14229     lodash.keysIn = keysIn;
14230     lodash.map = map;
14231     lodash.mapKeys = mapKeys;
14232     lodash.mapValues = mapValues;
14233     lodash.matches = matches;
14234     lodash.matchesProperty = matchesProperty;
14235     lodash.memoize = memoize;
14236     lodash.merge = merge;
14237     lodash.mergeWith = mergeWith;
14238     lodash.method = method;
14239     lodash.methodOf = methodOf;
14240     lodash.mixin = mixin;
14241     lodash.negate = negate;
14242     lodash.nthArg = nthArg;
14243     lodash.omit = omit;
14244     lodash.omitBy = omitBy;
14245     lodash.once = once;
14246     lodash.orderBy = orderBy;
14247     lodash.over = over;
14248     lodash.overArgs = overArgs;
14249     lodash.overEvery = overEvery;
14250     lodash.overSome = overSome;
14251     lodash.partial = partial;
14252     lodash.partialRight = partialRight;
14253     lodash.partition = partition;
14254     lodash.pick = pick;
14255     lodash.pickBy = pickBy;
14256     lodash.property = property;
14257     lodash.propertyOf = propertyOf;
14258     lodash.pull = pull;
14259     lodash.pullAll = pullAll;
14260     lodash.pullAllBy = pullAllBy;
14261     lodash.pullAt = pullAt;
14262     lodash.range = range;
14263     lodash.rangeRight = rangeRight;
14264     lodash.rearg = rearg;
14265     lodash.reject = reject;
14266     lodash.remove = remove;
14267     lodash.rest = rest;
14268     lodash.reverse = reverse;
14269     lodash.sampleSize = sampleSize;
14270     lodash.set = set;
14271     lodash.setWith = setWith;
14272     lodash.shuffle = shuffle;
14273     lodash.slice = slice;
14274     lodash.sortBy = sortBy;
14275     lodash.sortedUniq = sortedUniq;
14276     lodash.sortedUniqBy = sortedUniqBy;
14277     lodash.split = split;
14278     lodash.spread = spread;
14279     lodash.tail = tail;
14280     lodash.take = take;
14281     lodash.takeRight = takeRight;
14282     lodash.takeRightWhile = takeRightWhile;
14283     lodash.takeWhile = takeWhile;
14284     lodash.tap = tap;
14285     lodash.throttle = throttle;
14286     lodash.thru = thru;
14287     lodash.toArray = toArray;
14288     lodash.toPairs = toPairs;
14289     lodash.toPairsIn = toPairsIn;
14290     lodash.toPath = toPath;
14291     lodash.toPlainObject = toPlainObject;
14292     lodash.transform = transform;
14293     lodash.unary = unary;
14294     lodash.union = union;
14295     lodash.unionBy = unionBy;
14296     lodash.unionWith = unionWith;
14297     lodash.uniq = uniq;
14298     lodash.uniqBy = uniqBy;
14299     lodash.uniqWith = uniqWith;
14300     lodash.unset = unset;
14301     lodash.unzip = unzip;
14302     lodash.unzipWith = unzipWith;
14303     lodash.values = values;
14304     lodash.valuesIn = valuesIn;
14305     lodash.without = without;
14306     lodash.words = words;
14307     lodash.wrap = wrap;
14308     lodash.xor = xor;
14309     lodash.xorBy = xorBy;
14310     lodash.xorWith = xorWith;
14311     lodash.zip = zip;
14312     lodash.zipObject = zipObject;
14313     lodash.zipObjectDeep = zipObjectDeep;
14314     lodash.zipWith = zipWith;
14315
14316     // Add aliases.
14317     lodash.extend = assignIn;
14318     lodash.extendWith = assignInWith;
14319
14320     // Add functions to `lodash.prototype`.
14321     mixin(lodash, lodash);
14322
14323     /*------------------------------------------------------------------------*/
14324
14325     // Add functions that return unwrapped values when chaining.
14326     lodash.add = add;
14327     lodash.attempt = attempt;
14328     lodash.camelCase = camelCase;
14329     lodash.capitalize = capitalize;
14330     lodash.ceil = ceil;
14331     lodash.clamp = clamp;
14332     lodash.clone = clone;
14333     lodash.cloneDeep = cloneDeep;
14334     lodash.cloneDeepWith = cloneDeepWith;
14335     lodash.cloneWith = cloneWith;
14336     lodash.deburr = deburr;
14337     lodash.endsWith = endsWith;
14338     lodash.eq = eq;
14339     lodash.escape = escape;
14340     lodash.escapeRegExp = escapeRegExp;
14341     lodash.every = every;
14342     lodash.find = find;
14343     lodash.findIndex = findIndex;
14344     lodash.findKey = findKey;
14345     lodash.findLast = findLast;
14346     lodash.findLastIndex = findLastIndex;
14347     lodash.findLastKey = findLastKey;
14348     lodash.floor = floor;
14349     lodash.forEach = forEach;
14350     lodash.forEachRight = forEachRight;
14351     lodash.forIn = forIn;
14352     lodash.forInRight = forInRight;
14353     lodash.forOwn = forOwn;
14354     lodash.forOwnRight = forOwnRight;
14355     lodash.get = get;
14356     lodash.gt = gt;
14357     lodash.gte = gte;
14358     lodash.has = has;
14359     lodash.hasIn = hasIn;
14360     lodash.head = head;
14361     lodash.identity = identity;
14362     lodash.includes = includes;
14363     lodash.indexOf = indexOf;
14364     lodash.inRange = inRange;
14365     lodash.invoke = invoke;
14366     lodash.isArguments = isArguments;
14367     lodash.isArray = isArray;
14368     lodash.isArrayBuffer = isArrayBuffer;
14369     lodash.isArrayLike = isArrayLike;
14370     lodash.isArrayLikeObject = isArrayLikeObject;
14371     lodash.isBoolean = isBoolean;
14372     lodash.isBuffer = isBuffer;
14373     lodash.isDate = isDate;
14374     lodash.isElement = isElement;
14375     lodash.isEmpty = isEmpty;
14376     lodash.isEqual = isEqual;
14377     lodash.isEqualWith = isEqualWith;
14378     lodash.isError = isError;
14379     lodash.isFinite = isFinite;
14380     lodash.isFunction = isFunction;
14381     lodash.isInteger = isInteger;
14382     lodash.isLength = isLength;
14383     lodash.isMap = isMap;
14384     lodash.isMatch = isMatch;
14385     lodash.isMatchWith = isMatchWith;
14386     lodash.isNaN = isNaN;
14387     lodash.isNative = isNative;
14388     lodash.isNil = isNil;
14389     lodash.isNull = isNull;
14390     lodash.isNumber = isNumber;
14391     lodash.isObject = isObject;
14392     lodash.isObjectLike = isObjectLike;
14393     lodash.isPlainObject = isPlainObject;
14394     lodash.isRegExp = isRegExp;
14395     lodash.isSafeInteger = isSafeInteger;
14396     lodash.isSet = isSet;
14397     lodash.isString = isString;
14398     lodash.isSymbol = isSymbol;
14399     lodash.isTypedArray = isTypedArray;
14400     lodash.isUndefined = isUndefined;
14401     lodash.isWeakMap = isWeakMap;
14402     lodash.isWeakSet = isWeakSet;
14403     lodash.join = join;
14404     lodash.kebabCase = kebabCase;
14405     lodash.last = last;
14406     lodash.lastIndexOf = lastIndexOf;
14407     lodash.lowerCase = lowerCase;
14408     lodash.lowerFirst = lowerFirst;
14409     lodash.lt = lt;
14410     lodash.lte = lte;
14411     lodash.max = max;
14412     lodash.maxBy = maxBy;
14413     lodash.mean = mean;
14414     lodash.min = min;
14415     lodash.minBy = minBy;
14416     lodash.noConflict = noConflict;
14417     lodash.noop = noop;
14418     lodash.now = now;
14419     lodash.pad = pad;
14420     lodash.padEnd = padEnd;
14421     lodash.padStart = padStart;
14422     lodash.parseInt = parseInt;
14423     lodash.random = random;
14424     lodash.reduce = reduce;
14425     lodash.reduceRight = reduceRight;
14426     lodash.repeat = repeat;
14427     lodash.replace = replace;
14428     lodash.result = result;
14429     lodash.round = round;
14430     lodash.runInContext = runInContext;
14431     lodash.sample = sample;
14432     lodash.size = size;
14433     lodash.snakeCase = snakeCase;
14434     lodash.some = some;
14435     lodash.sortedIndex = sortedIndex;
14436     lodash.sortedIndexBy = sortedIndexBy;
14437     lodash.sortedIndexOf = sortedIndexOf;
14438     lodash.sortedLastIndex = sortedLastIndex;
14439     lodash.sortedLastIndexBy = sortedLastIndexBy;
14440     lodash.sortedLastIndexOf = sortedLastIndexOf;
14441     lodash.startCase = startCase;
14442     lodash.startsWith = startsWith;
14443     lodash.subtract = subtract;
14444     lodash.sum = sum;
14445     lodash.sumBy = sumBy;
14446     lodash.template = template;
14447     lodash.times = times;
14448     lodash.toInteger = toInteger;
14449     lodash.toLength = toLength;
14450     lodash.toLower = toLower;
14451     lodash.toNumber = toNumber;
14452     lodash.toSafeInteger = toSafeInteger;
14453     lodash.toString = toString;
14454     lodash.toUpper = toUpper;
14455     lodash.trim = trim;
14456     lodash.trimEnd = trimEnd;
14457     lodash.trimStart = trimStart;
14458     lodash.truncate = truncate;
14459     lodash.unescape = unescape;
14460     lodash.uniqueId = uniqueId;
14461     lodash.upperCase = upperCase;
14462     lodash.upperFirst = upperFirst;
14463
14464     // Add aliases.
14465     lodash.each = forEach;
14466     lodash.eachRight = forEachRight;
14467     lodash.first = head;
14468
14469     mixin(lodash, (function() {
14470       var source = {};
14471       baseForOwn(lodash, function(func, methodName) {
14472         if (!hasOwnProperty.call(lodash.prototype, methodName)) {
14473           source[methodName] = func;
14474         }
14475       });
14476       return source;
14477     }()), { 'chain': false });
14478
14479     /*------------------------------------------------------------------------*/
14480
14481     /**
14482      * The semantic version number.
14483      *
14484      * @static
14485      * @memberOf _
14486      * @type string
14487      */
14488     lodash.VERSION = VERSION;
14489
14490     // Assign default placeholders.
14491     arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
14492       lodash[methodName].placeholder = lodash;
14493     });
14494
14495     // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
14496     arrayEach(['drop', 'take'], function(methodName, index) {
14497       LazyWrapper.prototype[methodName] = function(n) {
14498         var filtered = this.__filtered__;
14499         if (filtered && !index) {
14500           return new LazyWrapper(this);
14501         }
14502         n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
14503
14504         var result = this.clone();
14505         if (filtered) {
14506           result.__takeCount__ = nativeMin(n, result.__takeCount__);
14507         } else {
14508           result.__views__.push({ 'size': nativeMin(n, MAX_ARRAY_LENGTH), 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
14509         }
14510         return result;
14511       };
14512
14513       LazyWrapper.prototype[methodName + 'Right'] = function(n) {
14514         return this.reverse()[methodName](n).reverse();
14515       };
14516     });
14517
14518     // Add `LazyWrapper` methods that accept an `iteratee` value.
14519     arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
14520       var type = index + 1,
14521           isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
14522
14523       LazyWrapper.prototype[methodName] = function(iteratee) {
14524         var result = this.clone();
14525         result.__iteratees__.push({ 'iteratee': getIteratee(iteratee, 3), 'type': type });
14526         result.__filtered__ = result.__filtered__ || isFilter;
14527         return result;
14528       };
14529     });
14530
14531     // Add `LazyWrapper` methods for `_.head` and `_.last`.
14532     arrayEach(['head', 'last'], function(methodName, index) {
14533       var takeName = 'take' + (index ? 'Right' : '');
14534
14535       LazyWrapper.prototype[methodName] = function() {
14536         return this[takeName](1).value()[0];
14537       };
14538     });
14539
14540     // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
14541     arrayEach(['initial', 'tail'], function(methodName, index) {
14542       var dropName = 'drop' + (index ? '' : 'Right');
14543
14544       LazyWrapper.prototype[methodName] = function() {
14545         return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
14546       };
14547     });
14548
14549     LazyWrapper.prototype.compact = function() {
14550       return this.filter(identity);
14551     };
14552
14553     LazyWrapper.prototype.find = function(predicate) {
14554       return this.filter(predicate).head();
14555     };
14556
14557     LazyWrapper.prototype.findLast = function(predicate) {
14558       return this.reverse().find(predicate);
14559     };
14560
14561     LazyWrapper.prototype.invokeMap = rest(function(path, args) {
14562       if (typeof path == 'function') {
14563         return new LazyWrapper(this);
14564       }
14565       return this.map(function(value) {
14566         return baseInvoke(value, path, args);
14567       });
14568     });
14569
14570     LazyWrapper.prototype.reject = function(predicate) {
14571       predicate = getIteratee(predicate, 3);
14572       return this.filter(function(value) {
14573         return !predicate(value);
14574       });
14575     };
14576
14577     LazyWrapper.prototype.slice = function(start, end) {
14578       start = toInteger(start);
14579
14580       var result = this;
14581       if (result.__filtered__ && (start > 0 || end < 0)) {
14582         return new LazyWrapper(result);
14583       }
14584       if (start < 0) {
14585         result = result.takeRight(-start);
14586       } else if (start) {
14587         result = result.drop(start);
14588       }
14589       if (end !== undefined) {
14590         end = toInteger(end);
14591         result = end < 0 ? result.dropRight(-end) : result.take(end - start);
14592       }
14593       return result;
14594     };
14595
14596     LazyWrapper.prototype.takeRightWhile = function(predicate) {
14597       return this.reverse().takeWhile(predicate).reverse();
14598     };
14599
14600     LazyWrapper.prototype.toArray = function() {
14601       return this.take(MAX_ARRAY_LENGTH);
14602     };
14603
14604     // Add `LazyWrapper` methods to `lodash.prototype`.
14605     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14606       var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
14607           isTaker = /^(?:head|last)$/.test(methodName),
14608           lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
14609           retUnwrapped = isTaker || /^find/.test(methodName);
14610
14611       if (!lodashFunc) {
14612         return;
14613       }
14614       lodash.prototype[methodName] = function() {
14615         var value = this.__wrapped__,
14616             args = isTaker ? [1] : arguments,
14617             isLazy = value instanceof LazyWrapper,
14618             iteratee = args[0],
14619             useLazy = isLazy || isArray(value);
14620
14621         var interceptor = function(value) {
14622           var result = lodashFunc.apply(lodash, arrayPush([value], args));
14623           return (isTaker && chainAll) ? result[0] : result;
14624         };
14625
14626         if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
14627           // Avoid lazy use if the iteratee has a "length" value other than `1`.
14628           isLazy = useLazy = false;
14629         }
14630         var chainAll = this.__chain__,
14631             isHybrid = !!this.__actions__.length,
14632             isUnwrapped = retUnwrapped && !chainAll,
14633             onlyLazy = isLazy && !isHybrid;
14634
14635         if (!retUnwrapped && useLazy) {
14636           value = onlyLazy ? value : new LazyWrapper(this);
14637           var result = func.apply(value, args);
14638           result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
14639           return new LodashWrapper(result, chainAll);
14640         }
14641         if (isUnwrapped && onlyLazy) {
14642           return func.apply(this, args);
14643         }
14644         result = this.thru(interceptor);
14645         return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
14646       };
14647     });
14648
14649     // Add `Array` and `String` methods to `lodash.prototype`.
14650     arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
14651       var func = arrayProto[methodName],
14652           chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
14653           retUnwrapped = /^(?:pop|shift)$/.test(methodName);
14654
14655       lodash.prototype[methodName] = function() {
14656         var args = arguments;
14657         if (retUnwrapped && !this.__chain__) {
14658           return func.apply(this.value(), args);
14659         }
14660         return this[chainName](function(value) {
14661           return func.apply(value, args);
14662         });
14663       };
14664     });
14665
14666     // Map minified function names to their real names.
14667     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14668       var lodashFunc = lodash[methodName];
14669       if (lodashFunc) {
14670         var key = (lodashFunc.name + ''),
14671             names = realNames[key] || (realNames[key] = []);
14672
14673         names.push({ 'name': methodName, 'func': lodashFunc });
14674       }
14675     });
14676
14677     realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }];
14678
14679     // Add functions to the lazy wrapper.
14680     LazyWrapper.prototype.clone = lazyClone;
14681     LazyWrapper.prototype.reverse = lazyReverse;
14682     LazyWrapper.prototype.value = lazyValue;
14683
14684     // Add chaining functions to the `lodash` wrapper.
14685     lodash.prototype.at = wrapperAt;
14686     lodash.prototype.chain = wrapperChain;
14687     lodash.prototype.commit = wrapperCommit;
14688     lodash.prototype.flatMap = wrapperFlatMap;
14689     lodash.prototype.next = wrapperNext;
14690     lodash.prototype.plant = wrapperPlant;
14691     lodash.prototype.reverse = wrapperReverse;
14692     lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
14693
14694     if (iteratorSymbol) {
14695       lodash.prototype[iteratorSymbol] = wrapperToIterator;
14696     }
14697     return lodash;
14698   }
14699
14700   /*--------------------------------------------------------------------------*/
14701
14702   // Export lodash.
14703   var _ = runInContext();
14704
14705   // Expose lodash on the free variable `window` or `self` when available. This
14706   // prevents errors in cases where lodash is loaded by a script tag in the presence
14707   // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details.
14708   (freeWindow || freeSelf || {})._ = _;
14709
14710   // Some AMD build optimizers like r.js check for condition patterns like the following:
14711   if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
14712     // Define as an anonymous module so, through path mapping, it can be
14713     // referenced as the "underscore" module.
14714     define(function() {
14715       return _;
14716     });
14717   }
14718   // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
14719   else if (freeExports && freeModule) {
14720     // Export for Node.js.
14721     if (moduleExports) {
14722       (freeModule.exports = _)._ = _;
14723     }
14724     // Export for CommonJS support.
14725     freeExports._ = _;
14726   }
14727   else {
14728     // Export to the global object.
14729     root._ = _;
14730   }
14731 }.call(this));