9f472f69109a3a2a45d4b875c73dacf0439c46e0
[motion.git] / public / bower_components / lodash / lodash.js
1 /**
2  * @license
3  * lodash 4.11.2 <https://lodash.com/>
4  * Copyright jQuery Foundation and other contributors <https://jquery.org/>
5  * Released under MIT license <https://lodash.com/license>
6  * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7  * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
8  */
9 ;(function() {
10
11   /** Used as a safe reference for `undefined` in pre-ES5 environments. */
12   var undefined;
13
14   /** Used as the semantic version number. */
15   var VERSION = '4.11.2';
16
17   /** Used as the size to enable large array optimizations. */
18   var LARGE_ARRAY_SIZE = 200;
19
20   /** Used as the `TypeError` message for "Functions" methods. */
21   var FUNC_ERROR_TEXT = 'Expected a function';
22
23   /** Used to stand-in for `undefined` hash values. */
24   var HASH_UNDEFINED = '__lodash_hash_undefined__';
25
26   /** Used as the internal argument placeholder. */
27   var PLACEHOLDER = '__lodash_placeholder__';
28
29   /** Used to compose bitmasks for wrapper metadata. */
30   var BIND_FLAG = 1,
31       BIND_KEY_FLAG = 2,
32       CURRY_BOUND_FLAG = 4,
33       CURRY_FLAG = 8,
34       CURRY_RIGHT_FLAG = 16,
35       PARTIAL_FLAG = 32,
36       PARTIAL_RIGHT_FLAG = 64,
37       ARY_FLAG = 128,
38       REARG_FLAG = 256,
39       FLIP_FLAG = 512;
40
41   /** Used to compose bitmasks for comparison styles. */
42   var UNORDERED_COMPARE_FLAG = 1,
43       PARTIAL_COMPARE_FLAG = 2;
44
45   /** Used as default options for `_.truncate`. */
46   var DEFAULT_TRUNC_LENGTH = 30,
47       DEFAULT_TRUNC_OMISSION = '...';
48
49   /** Used to detect hot functions by number of calls within a span of milliseconds. */
50   var HOT_COUNT = 150,
51       HOT_SPAN = 16;
52
53   /** Used to indicate the type of lazy iteratees. */
54   var LAZY_FILTER_FLAG = 1,
55       LAZY_MAP_FLAG = 2,
56       LAZY_WHILE_FLAG = 3;
57
58   /** Used as references for various `Number` constants. */
59   var INFINITY = 1 / 0,
60       MAX_SAFE_INTEGER = 9007199254740991,
61       MAX_INTEGER = 1.7976931348623157e+308,
62       NAN = 0 / 0;
63
64   /** Used as references for the maximum length and index of an array. */
65   var MAX_ARRAY_LENGTH = 4294967295,
66       MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
67       HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
68
69   /** `Object#toString` result references. */
70   var argsTag = '[object Arguments]',
71       arrayTag = '[object Array]',
72       boolTag = '[object Boolean]',
73       dateTag = '[object Date]',
74       errorTag = '[object Error]',
75       funcTag = '[object Function]',
76       genTag = '[object GeneratorFunction]',
77       mapTag = '[object Map]',
78       numberTag = '[object Number]',
79       objectTag = '[object Object]',
80       promiseTag = '[object Promise]',
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       dataViewTag = '[object DataView]',
90       float32Tag = '[object Float32Array]',
91       float64Tag = '[object Float64Array]',
92       int8Tag = '[object Int8Array]',
93       int16Tag = '[object Int16Array]',
94       int32Tag = '[object Int32Array]',
95       uint8Tag = '[object Uint8Array]',
96       uint8ClampedTag = '[object Uint8ClampedArray]',
97       uint16Tag = '[object Uint16Array]',
98       uint32Tag = '[object Uint32Array]';
99
100   /** Used to match empty string literals in compiled template source. */
101   var reEmptyStringLeading = /\b__p \+= '';/g,
102       reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
103       reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
104
105   /** Used to match HTML entities and HTML characters. */
106   var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
107       reUnescapedHtml = /[&<>"'`]/g,
108       reHasEscapedHtml = RegExp(reEscapedHtml.source),
109       reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
110
111   /** Used to match template delimiters. */
112   var reEscape = /<%-([\s\S]+?)%>/g,
113       reEvaluate = /<%([\s\S]+?)%>/g,
114       reInterpolate = /<%=([\s\S]+?)%>/g;
115
116   /** Used to match property names within property paths. */
117   var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
118       reIsPlainProp = /^\w*$/,
119       rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
120
121   /**
122    * Used to match `RegExp`
123    * [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns).
124    */
125   var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
126       reHasRegExpChar = RegExp(reRegExpChar.source);
127
128   /** Used to match leading and trailing whitespace. */
129   var reTrim = /^\s+|\s+$/g,
130       reTrimStart = /^\s+/,
131       reTrimEnd = /\s+$/;
132
133   /** Used to match non-compound words composed of alphanumeric characters. */
134   var reBasicWord = /[a-zA-Z0-9]+/g;
135
136   /** Used to match backslashes in property paths. */
137   var reEscapeChar = /\\(\\)?/g;
138
139   /**
140    * Used to match
141    * [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components).
142    */
143   var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
144
145   /** Used to match `RegExp` flags from their coerced string values. */
146   var reFlags = /\w*$/;
147
148   /** Used to detect hexadecimal string values. */
149   var reHasHexPrefix = /^0x/i;
150
151   /** Used to detect bad signed hexadecimal string values. */
152   var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
153
154   /** Used to detect binary string values. */
155   var reIsBinary = /^0b[01]+$/i;
156
157   /** Used to detect host constructors (Safari). */
158   var reIsHostCtor = /^\[object .+?Constructor\]$/;
159
160   /** Used to detect octal string values. */
161   var reIsOctal = /^0o[0-7]+$/i;
162
163   /** Used to detect unsigned integer values. */
164   var reIsUint = /^(?:0|[1-9]\d*)$/;
165
166   /** Used to match latin-1 supplementary letters (excluding mathematical operators). */
167   var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
168
169   /** Used to ensure capturing order of template delimiters. */
170   var reNoMatch = /($^)/;
171
172   /** Used to match unescaped characters in compiled string literals. */
173   var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
174
175   /** Used to compose unicode character classes. */
176   var rsAstralRange = '\\ud800-\\udfff',
177       rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
178       rsComboSymbolsRange = '\\u20d0-\\u20f0',
179       rsDingbatRange = '\\u2700-\\u27bf',
180       rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
181       rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
182       rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
183       rsPunctuationRange = '\\u2000-\\u206f',
184       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',
185       rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
186       rsVarRange = '\\ufe0e\\ufe0f',
187       rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
188
189   /** Used to compose unicode capture groups. */
190   var rsApos = "['\u2019]",
191       rsAstral = '[' + rsAstralRange + ']',
192       rsBreak = '[' + rsBreakRange + ']',
193       rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
194       rsDigits = '\\d+',
195       rsDingbat = '[' + rsDingbatRange + ']',
196       rsLower = '[' + rsLowerRange + ']',
197       rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
198       rsFitz = '\\ud83c[\\udffb-\\udfff]',
199       rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
200       rsNonAstral = '[^' + rsAstralRange + ']',
201       rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
202       rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
203       rsUpper = '[' + rsUpperRange + ']',
204       rsZWJ = '\\u200d';
205
206   /** Used to compose unicode regexes. */
207   var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
208       rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
209       rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
210       rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
211       reOptMod = rsModifier + '?',
212       rsOptVar = '[' + rsVarRange + ']?',
213       rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
214       rsSeq = rsOptVar + reOptMod + rsOptJoin,
215       rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
216       rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
217
218   /** Used to match apostrophes. */
219   var reApos = RegExp(rsApos, 'g');
220
221   /**
222    * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
223    * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
224    */
225   var reComboMark = RegExp(rsCombo, 'g');
226
227   /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
228   var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
229
230   /** Used to match complex or compound words. */
231   var reComplexWord = RegExp([
232     rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
233     rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
234     rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr,
235     rsUpper + '+' + rsOptUpperContr,
236     rsDigits,
237     rsEmoji
238   ].join('|'), 'g');
239
240   /** 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/). */
241   var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange  + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
242
243   /** Used to detect strings that need a more robust regexp to match words. */
244   var reHasComplexWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
245
246   /** Used to assign default `context` object properties. */
247   var contextProps = [
248     'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
249     'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
250     'Promise', 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError',
251     'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
252     '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
253   ];
254
255   /** Used to make template sourceURLs easier to identify. */
256   var templateCounter = -1;
257
258   /** Used to identify `toStringTag` values of typed arrays. */
259   var typedArrayTags = {};
260   typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
261   typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
262   typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
263   typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
264   typedArrayTags[uint32Tag] = true;
265   typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
266   typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
267   typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
268   typedArrayTags[errorTag] = typedArrayTags[funcTag] =
269   typedArrayTags[mapTag] = typedArrayTags[numberTag] =
270   typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
271   typedArrayTags[setTag] = typedArrayTags[stringTag] =
272   typedArrayTags[weakMapTag] = false;
273
274   /** Used to identify `toStringTag` values supported by `_.clone`. */
275   var cloneableTags = {};
276   cloneableTags[argsTag] = cloneableTags[arrayTag] =
277   cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
278   cloneableTags[boolTag] = cloneableTags[dateTag] =
279   cloneableTags[float32Tag] = cloneableTags[float64Tag] =
280   cloneableTags[int8Tag] = cloneableTags[int16Tag] =
281   cloneableTags[int32Tag] = cloneableTags[mapTag] =
282   cloneableTags[numberTag] = cloneableTags[objectTag] =
283   cloneableTags[regexpTag] = cloneableTags[setTag] =
284   cloneableTags[stringTag] = cloneableTags[symbolTag] =
285   cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
286   cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
287   cloneableTags[errorTag] = cloneableTags[funcTag] =
288   cloneableTags[weakMapTag] = false;
289
290   /** Used to map latin-1 supplementary letters to basic latin letters. */
291   var deburredLetters = {
292     '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
293     '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
294     '\xc7': 'C',  '\xe7': 'c',
295     '\xd0': 'D',  '\xf0': 'd',
296     '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
297     '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
298     '\xcC': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
299     '\xeC': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
300     '\xd1': 'N',  '\xf1': 'n',
301     '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
302     '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
303     '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
304     '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
305     '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
306     '\xc6': 'Ae', '\xe6': 'ae',
307     '\xde': 'Th', '\xfe': 'th',
308     '\xdf': 'ss'
309   };
310
311   /** Used to map characters to HTML entities. */
312   var htmlEscapes = {
313     '&': '&amp;',
314     '<': '&lt;',
315     '>': '&gt;',
316     '"': '&quot;',
317     "'": '&#39;',
318     '`': '&#96;'
319   };
320
321   /** Used to map HTML entities to characters. */
322   var htmlUnescapes = {
323     '&amp;': '&',
324     '&lt;': '<',
325     '&gt;': '>',
326     '&quot;': '"',
327     '&#39;': "'",
328     '&#96;': '`'
329   };
330
331   /** Used to determine if values are of the language type `Object`. */
332   var objectTypes = {
333     'function': true,
334     'object': true
335   };
336
337   /** Used to escape characters for inclusion in compiled string literals. */
338   var stringEscapes = {
339     '\\': '\\',
340     "'": "'",
341     '\n': 'n',
342     '\r': 'r',
343     '\u2028': 'u2028',
344     '\u2029': 'u2029'
345   };
346
347   /** Built-in method references without a dependency on `root`. */
348   var freeParseFloat = parseFloat,
349       freeParseInt = parseInt;
350
351   /** Detect free variable `exports`. */
352   var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
353     ? exports
354     : undefined;
355
356   /** Detect free variable `module`. */
357   var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
358     ? module
359     : undefined;
360
361   /** Detect the popular CommonJS extension `module.exports`. */
362   var moduleExports = (freeModule && freeModule.exports === freeExports)
363     ? freeExports
364     : undefined;
365
366   /** Detect free variable `global` from Node.js. */
367   var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
368
369   /** Detect free variable `self`. */
370   var freeSelf = checkGlobal(objectTypes[typeof self] && self);
371
372   /** Detect free variable `window`. */
373   var freeWindow = checkGlobal(objectTypes[typeof window] && window);
374
375   /** Detect `this` as the global object. */
376   var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
377
378   /**
379    * Used as a reference to the global object.
380    *
381    * The `this` value is used if it's the global object to avoid Greasemonkey's
382    * restricted `window` object, otherwise the `window` object is used.
383    */
384   var root = freeGlobal ||
385     ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
386       freeSelf || thisGlobal || Function('return this')();
387
388   /*--------------------------------------------------------------------------*/
389
390   /**
391    * Adds the key-value `pair` to `map`.
392    *
393    * @private
394    * @param {Object} map The map to modify.
395    * @param {Array} pair The key-value pair to add.
396    * @returns {Object} Returns `map`.
397    */
398   function addMapEntry(map, pair) {
399     // Don't return `Map#set` because it doesn't return the map instance in IE 11.
400     map.set(pair[0], pair[1]);
401     return map;
402   }
403
404   /**
405    * Adds `value` to `set`.
406    *
407    * @private
408    * @param {Object} set The set to modify.
409    * @param {*} value The value to add.
410    * @returns {Object} Returns `set`.
411    */
412   function addSetEntry(set, value) {
413     set.add(value);
414     return set;
415   }
416
417   /**
418    * A faster alternative to `Function#apply`, this function invokes `func`
419    * with the `this` binding of `thisArg` and the arguments of `args`.
420    *
421    * @private
422    * @param {Function} func The function to invoke.
423    * @param {*} thisArg The `this` binding of `func`.
424    * @param {Array} args The arguments to invoke `func` with.
425    * @returns {*} Returns the result of `func`.
426    */
427   function apply(func, thisArg, args) {
428     var length = args.length;
429     switch (length) {
430       case 0: return func.call(thisArg);
431       case 1: return func.call(thisArg, args[0]);
432       case 2: return func.call(thisArg, args[0], args[1]);
433       case 3: return func.call(thisArg, args[0], args[1], args[2]);
434     }
435     return func.apply(thisArg, args);
436   }
437
438   /**
439    * A specialized version of `baseAggregator` for arrays.
440    *
441    * @private
442    * @param {Array} array The array to iterate over.
443    * @param {Function} setter The function to set `accumulator` values.
444    * @param {Function} iteratee The iteratee to transform keys.
445    * @param {Object} accumulator The initial aggregated object.
446    * @returns {Function} Returns `accumulator`.
447    */
448   function arrayAggregator(array, setter, iteratee, accumulator) {
449     var index = -1,
450         length = array.length;
451
452     while (++index < length) {
453       var value = array[index];
454       setter(accumulator, value, iteratee(value), array);
455     }
456     return accumulator;
457   }
458
459   /**
460    * Creates a new array concatenating `array` with `other`.
461    *
462    * @private
463    * @param {Array} array The first array to concatenate.
464    * @param {Array} other The second array to concatenate.
465    * @returns {Array} Returns the new concatenated array.
466    */
467   function arrayConcat(array, other) {
468     var index = -1,
469         length = array.length,
470         othIndex = -1,
471         othLength = other.length,
472         result = Array(length + othLength);
473
474     while (++index < length) {
475       result[index] = array[index];
476     }
477     while (++othIndex < othLength) {
478       result[index++] = other[othIndex];
479     }
480     return result;
481   }
482
483   /**
484    * A specialized version of `_.forEach` for arrays without support for
485    * iteratee shorthands.
486    *
487    * @private
488    * @param {Array} array The array to iterate over.
489    * @param {Function} iteratee The function invoked per iteration.
490    * @returns {Array} Returns `array`.
491    */
492   function arrayEach(array, iteratee) {
493     var index = -1,
494         length = array.length;
495
496     while (++index < length) {
497       if (iteratee(array[index], index, array) === false) {
498         break;
499       }
500     }
501     return array;
502   }
503
504   /**
505    * A specialized version of `_.forEachRight` for arrays without support for
506    * iteratee shorthands.
507    *
508    * @private
509    * @param {Array} array The array to iterate over.
510    * @param {Function} iteratee The function invoked per iteration.
511    * @returns {Array} Returns `array`.
512    */
513   function arrayEachRight(array, iteratee) {
514     var length = array.length;
515
516     while (length--) {
517       if (iteratee(array[length], length, array) === false) {
518         break;
519       }
520     }
521     return array;
522   }
523
524   /**
525    * A specialized version of `_.every` for arrays without support for
526    * iteratee shorthands.
527    *
528    * @private
529    * @param {Array} array The array to iterate over.
530    * @param {Function} predicate The function invoked per iteration.
531    * @returns {boolean} Returns `true` if all elements pass the predicate check,
532    *  else `false`.
533    */
534   function arrayEvery(array, predicate) {
535     var index = -1,
536         length = array.length;
537
538     while (++index < length) {
539       if (!predicate(array[index], index, array)) {
540         return false;
541       }
542     }
543     return true;
544   }
545
546   /**
547    * A specialized version of `_.filter` for arrays without support for
548    * iteratee shorthands.
549    *
550    * @private
551    * @param {Array} array The array to iterate over.
552    * @param {Function} predicate The function invoked per iteration.
553    * @returns {Array} Returns the new filtered array.
554    */
555   function arrayFilter(array, predicate) {
556     var index = -1,
557         length = array.length,
558         resIndex = 0,
559         result = [];
560
561     while (++index < length) {
562       var value = array[index];
563       if (predicate(value, index, array)) {
564         result[resIndex++] = value;
565       }
566     }
567     return result;
568   }
569
570   /**
571    * A specialized version of `_.includes` for arrays without support for
572    * specifying an index to search from.
573    *
574    * @private
575    * @param {Array} array The array to search.
576    * @param {*} target The value to search for.
577    * @returns {boolean} Returns `true` if `target` is found, else `false`.
578    */
579   function arrayIncludes(array, value) {
580     return !!array.length && baseIndexOf(array, value, 0) > -1;
581   }
582
583   /**
584    * This function is like `arrayIncludes` except that it accepts a comparator.
585    *
586    * @private
587    * @param {Array} array The array to search.
588    * @param {*} target The value to search for.
589    * @param {Function} comparator The comparator invoked per element.
590    * @returns {boolean} Returns `true` if `target` is found, else `false`.
591    */
592   function arrayIncludesWith(array, value, comparator) {
593     var index = -1,
594         length = array.length;
595
596     while (++index < length) {
597       if (comparator(value, array[index])) {
598         return true;
599       }
600     }
601     return false;
602   }
603
604   /**
605    * A specialized version of `_.map` for arrays without support for iteratee
606    * shorthands.
607    *
608    * @private
609    * @param {Array} array The array to iterate over.
610    * @param {Function} iteratee The function invoked per iteration.
611    * @returns {Array} Returns the new mapped array.
612    */
613   function arrayMap(array, iteratee) {
614     var index = -1,
615         length = array.length,
616         result = Array(length);
617
618     while (++index < length) {
619       result[index] = iteratee(array[index], index, array);
620     }
621     return result;
622   }
623
624   /**
625    * Appends the elements of `values` to `array`.
626    *
627    * @private
628    * @param {Array} array The array to modify.
629    * @param {Array} values The values to append.
630    * @returns {Array} Returns `array`.
631    */
632   function arrayPush(array, values) {
633     var index = -1,
634         length = values.length,
635         offset = array.length;
636
637     while (++index < length) {
638       array[offset + index] = values[index];
639     }
640     return array;
641   }
642
643   /**
644    * A specialized version of `_.reduce` for arrays without support for
645    * iteratee shorthands.
646    *
647    * @private
648    * @param {Array} array The array to iterate over.
649    * @param {Function} iteratee The function invoked per iteration.
650    * @param {*} [accumulator] The initial value.
651    * @param {boolean} [initAccum] Specify using the first element of `array` as
652    *  the initial value.
653    * @returns {*} Returns the accumulated value.
654    */
655   function arrayReduce(array, iteratee, accumulator, initAccum) {
656     var index = -1,
657         length = array.length;
658
659     if (initAccum && length) {
660       accumulator = array[++index];
661     }
662     while (++index < length) {
663       accumulator = iteratee(accumulator, array[index], index, array);
664     }
665     return accumulator;
666   }
667
668   /**
669    * A specialized version of `_.reduceRight` for arrays without support for
670    * iteratee shorthands.
671    *
672    * @private
673    * @param {Array} array The array to iterate over.
674    * @param {Function} iteratee The function invoked per iteration.
675    * @param {*} [accumulator] The initial value.
676    * @param {boolean} [initAccum] Specify using the last element of `array` as
677    *  the initial value.
678    * @returns {*} Returns the accumulated value.
679    */
680   function arrayReduceRight(array, iteratee, accumulator, initAccum) {
681     var length = array.length;
682     if (initAccum && length) {
683       accumulator = array[--length];
684     }
685     while (length--) {
686       accumulator = iteratee(accumulator, array[length], length, array);
687     }
688     return accumulator;
689   }
690
691   /**
692    * A specialized version of `_.some` for arrays without support for iteratee
693    * shorthands.
694    *
695    * @private
696    * @param {Array} array The array to iterate over.
697    * @param {Function} predicate The function invoked per iteration.
698    * @returns {boolean} Returns `true` if any element passes the predicate check,
699    *  else `false`.
700    */
701   function arraySome(array, predicate) {
702     var index = -1,
703         length = array.length;
704
705     while (++index < length) {
706       if (predicate(array[index], index, array)) {
707         return true;
708       }
709     }
710     return false;
711   }
712
713   /**
714    * The base implementation of methods like `_.find` and `_.findKey`, without
715    * support for iteratee shorthands, which iterates over `collection` using
716    * `eachFunc`.
717    *
718    * @private
719    * @param {Array|Object} collection The collection to search.
720    * @param {Function} predicate The function invoked per iteration.
721    * @param {Function} eachFunc The function to iterate over `collection`.
722    * @param {boolean} [retKey] Specify returning the key of the found element
723    *  instead of the element itself.
724    * @returns {*} Returns the found element or its key, else `undefined`.
725    */
726   function baseFind(collection, predicate, eachFunc, retKey) {
727     var result;
728     eachFunc(collection, function(value, key, collection) {
729       if (predicate(value, key, collection)) {
730         result = retKey ? key : value;
731         return false;
732       }
733     });
734     return result;
735   }
736
737   /**
738    * The base implementation of `_.findIndex` and `_.findLastIndex` without
739    * support for iteratee shorthands.
740    *
741    * @private
742    * @param {Array} array The array to search.
743    * @param {Function} predicate The function invoked per iteration.
744    * @param {boolean} [fromRight] Specify iterating from right to left.
745    * @returns {number} Returns the index of the matched value, else `-1`.
746    */
747   function baseFindIndex(array, predicate, fromRight) {
748     var length = array.length,
749         index = fromRight ? length : -1;
750
751     while ((fromRight ? index-- : ++index < length)) {
752       if (predicate(array[index], index, array)) {
753         return index;
754       }
755     }
756     return -1;
757   }
758
759   /**
760    * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
761    *
762    * @private
763    * @param {Array} array The array to search.
764    * @param {*} value The value to search for.
765    * @param {number} fromIndex The index to search from.
766    * @returns {number} Returns the index of the matched value, else `-1`.
767    */
768   function baseIndexOf(array, value, fromIndex) {
769     if (value !== value) {
770       return indexOfNaN(array, fromIndex);
771     }
772     var index = fromIndex - 1,
773         length = array.length;
774
775     while (++index < length) {
776       if (array[index] === value) {
777         return index;
778       }
779     }
780     return -1;
781   }
782
783   /**
784    * This function is like `baseIndexOf` except that it accepts a comparator.
785    *
786    * @private
787    * @param {Array} array The array to search.
788    * @param {*} value The value to search for.
789    * @param {number} fromIndex The index to search from.
790    * @param {Function} comparator The comparator invoked per element.
791    * @returns {number} Returns the index of the matched value, else `-1`.
792    */
793   function baseIndexOfWith(array, value, fromIndex, comparator) {
794     var index = fromIndex - 1,
795         length = array.length;
796
797     while (++index < length) {
798       if (comparator(array[index], value)) {
799         return index;
800       }
801     }
802     return -1;
803   }
804
805   /**
806    * The base implementation of `_.mean` and `_.meanBy` without support for
807    * iteratee shorthands.
808    *
809    * @private
810    * @param {Array} array The array to iterate over.
811    * @param {Function} iteratee The function invoked per iteration.
812    * @returns {number} Returns the mean.
813    */
814   function baseMean(array, iteratee) {
815     var length = array ? array.length : 0;
816     return length ? (baseSum(array, iteratee) / length) : NAN;
817   }
818
819   /**
820    * The base implementation of `_.reduce` and `_.reduceRight`, without support
821    * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
822    *
823    * @private
824    * @param {Array|Object} collection The collection to iterate over.
825    * @param {Function} iteratee The function invoked per iteration.
826    * @param {*} accumulator The initial value.
827    * @param {boolean} initAccum Specify using the first or last element of
828    *  `collection` as the initial value.
829    * @param {Function} eachFunc The function to iterate over `collection`.
830    * @returns {*} Returns the accumulated value.
831    */
832   function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
833     eachFunc(collection, function(value, index, collection) {
834       accumulator = initAccum
835         ? (initAccum = false, value)
836         : iteratee(accumulator, value, index, collection);
837     });
838     return accumulator;
839   }
840
841   /**
842    * The base implementation of `_.sortBy` which uses `comparer` to define the
843    * sort order of `array` and replaces criteria objects with their corresponding
844    * values.
845    *
846    * @private
847    * @param {Array} array The array to sort.
848    * @param {Function} comparer The function to define sort order.
849    * @returns {Array} Returns `array`.
850    */
851   function baseSortBy(array, comparer) {
852     var length = array.length;
853
854     array.sort(comparer);
855     while (length--) {
856       array[length] = array[length].value;
857     }
858     return array;
859   }
860
861   /**
862    * The base implementation of `_.sum` and `_.sumBy` without support for
863    * iteratee shorthands.
864    *
865    * @private
866    * @param {Array} array The array to iterate over.
867    * @param {Function} iteratee The function invoked per iteration.
868    * @returns {number} Returns the sum.
869    */
870   function baseSum(array, iteratee) {
871     var result,
872         index = -1,
873         length = array.length;
874
875     while (++index < length) {
876       var current = iteratee(array[index]);
877       if (current !== undefined) {
878         result = result === undefined ? current : (result + current);
879       }
880     }
881     return result;
882   }
883
884   /**
885    * The base implementation of `_.times` without support for iteratee shorthands
886    * or max array length checks.
887    *
888    * @private
889    * @param {number} n The number of times to invoke `iteratee`.
890    * @param {Function} iteratee The function invoked per iteration.
891    * @returns {Array} Returns the array of results.
892    */
893   function baseTimes(n, iteratee) {
894     var index = -1,
895         result = Array(n);
896
897     while (++index < n) {
898       result[index] = iteratee(index);
899     }
900     return result;
901   }
902
903   /**
904    * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
905    * of key-value pairs for `object` corresponding to the property names of `props`.
906    *
907    * @private
908    * @param {Object} object The object to query.
909    * @param {Array} props The property names to get values for.
910    * @returns {Object} Returns the new array of key-value pairs.
911    */
912   function baseToPairs(object, props) {
913     return arrayMap(props, function(key) {
914       return [key, object[key]];
915     });
916   }
917
918   /**
919    * The base implementation of `_.unary` without support for storing wrapper metadata.
920    *
921    * @private
922    * @param {Function} func The function to cap arguments for.
923    * @returns {Function} Returns the new function.
924    */
925   function baseUnary(func) {
926     return function(value) {
927       return func(value);
928     };
929   }
930
931   /**
932    * The base implementation of `_.values` and `_.valuesIn` which creates an
933    * array of `object` property values corresponding to the property names
934    * of `props`.
935    *
936    * @private
937    * @param {Object} object The object to query.
938    * @param {Array} props The property names to get values for.
939    * @returns {Object} Returns the array of property values.
940    */
941   function baseValues(object, props) {
942     return arrayMap(props, function(key) {
943       return object[key];
944     });
945   }
946
947   /**
948    * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
949    * that is not found in the character symbols.
950    *
951    * @private
952    * @param {Array} strSymbols The string symbols to inspect.
953    * @param {Array} chrSymbols The character symbols to find.
954    * @returns {number} Returns the index of the first unmatched string symbol.
955    */
956   function charsStartIndex(strSymbols, chrSymbols) {
957     var index = -1,
958         length = strSymbols.length;
959
960     while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
961     return index;
962   }
963
964   /**
965    * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
966    * that is not found in the character symbols.
967    *
968    * @private
969    * @param {Array} strSymbols The string symbols to inspect.
970    * @param {Array} chrSymbols The character symbols to find.
971    * @returns {number} Returns the index of the last unmatched string symbol.
972    */
973   function charsEndIndex(strSymbols, chrSymbols) {
974     var index = strSymbols.length;
975
976     while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
977     return index;
978   }
979
980   /**
981    * Checks if `value` is a global object.
982    *
983    * @private
984    * @param {*} value The value to check.
985    * @returns {null|Object} Returns `value` if it's a global object, else `null`.
986    */
987   function checkGlobal(value) {
988     return (value && value.Object === Object) ? value : null;
989   }
990
991   /**
992    * Gets the number of `placeholder` occurrences in `array`.
993    *
994    * @private
995    * @param {Array} array The array to inspect.
996    * @param {*} placeholder The placeholder to search for.
997    * @returns {number} Returns the placeholder count.
998    */
999   function countHolders(array, placeholder) {
1000     var length = array.length,
1001         result = 0;
1002
1003     while (length--) {
1004       if (array[length] === placeholder) {
1005         result++;
1006       }
1007     }
1008     return result;
1009   }
1010
1011   /**
1012    * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
1013    *
1014    * @private
1015    * @param {string} letter The matched letter to deburr.
1016    * @returns {string} Returns the deburred letter.
1017    */
1018   function deburrLetter(letter) {
1019     return deburredLetters[letter];
1020   }
1021
1022   /**
1023    * Used by `_.escape` to convert characters to HTML entities.
1024    *
1025    * @private
1026    * @param {string} chr The matched character to escape.
1027    * @returns {string} Returns the escaped character.
1028    */
1029   function escapeHtmlChar(chr) {
1030     return htmlEscapes[chr];
1031   }
1032
1033   /**
1034    * Used by `_.template` to escape characters for inclusion in compiled string literals.
1035    *
1036    * @private
1037    * @param {string} chr The matched character to escape.
1038    * @returns {string} Returns the escaped character.
1039    */
1040   function escapeStringChar(chr) {
1041     return '\\' + stringEscapes[chr];
1042   }
1043
1044   /**
1045    * Gets the index at which the first occurrence of `NaN` is found in `array`.
1046    *
1047    * @private
1048    * @param {Array} array The array to search.
1049    * @param {number} fromIndex The index to search from.
1050    * @param {boolean} [fromRight] Specify iterating from right to left.
1051    * @returns {number} Returns the index of the matched `NaN`, else `-1`.
1052    */
1053   function indexOfNaN(array, fromIndex, fromRight) {
1054     var length = array.length,
1055         index = fromIndex + (fromRight ? 0 : -1);
1056
1057     while ((fromRight ? index-- : ++index < length)) {
1058       var other = array[index];
1059       if (other !== other) {
1060         return index;
1061       }
1062     }
1063     return -1;
1064   }
1065
1066   /**
1067    * Checks if `value` is a host object in IE < 9.
1068    *
1069    * @private
1070    * @param {*} value The value to check.
1071    * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
1072    */
1073   function isHostObject(value) {
1074     // Many host objects are `Object` objects that can coerce to strings
1075     // despite having improperly defined `toString` methods.
1076     var result = false;
1077     if (value != null && typeof value.toString != 'function') {
1078       try {
1079         result = !!(value + '');
1080       } catch (e) {}
1081     }
1082     return result;
1083   }
1084
1085   /**
1086    * Converts `iterator` to an array.
1087    *
1088    * @private
1089    * @param {Object} iterator The iterator to convert.
1090    * @returns {Array} Returns the converted array.
1091    */
1092   function iteratorToArray(iterator) {
1093     var data,
1094         result = [];
1095
1096     while (!(data = iterator.next()).done) {
1097       result.push(data.value);
1098     }
1099     return result;
1100   }
1101
1102   /**
1103    * Converts `map` to an array.
1104    *
1105    * @private
1106    * @param {Object} map The map to convert.
1107    * @returns {Array} Returns the converted array.
1108    */
1109   function mapToArray(map) {
1110     var index = -1,
1111         result = Array(map.size);
1112
1113     map.forEach(function(value, key) {
1114       result[++index] = [key, value];
1115     });
1116     return result;
1117   }
1118
1119   /**
1120    * Replaces all `placeholder` elements in `array` with an internal placeholder
1121    * and returns an array of their indexes.
1122    *
1123    * @private
1124    * @param {Array} array The array to modify.
1125    * @param {*} placeholder The placeholder to replace.
1126    * @returns {Array} Returns the new array of placeholder indexes.
1127    */
1128   function replaceHolders(array, placeholder) {
1129     var index = -1,
1130         length = array.length,
1131         resIndex = 0,
1132         result = [];
1133
1134     while (++index < length) {
1135       var value = array[index];
1136       if (value === placeholder || value === PLACEHOLDER) {
1137         array[index] = PLACEHOLDER;
1138         result[resIndex++] = index;
1139       }
1140     }
1141     return result;
1142   }
1143
1144   /**
1145    * Converts `set` to an array.
1146    *
1147    * @private
1148    * @param {Object} set The set to convert.
1149    * @returns {Array} Returns the converted array.
1150    */
1151   function setToArray(set) {
1152     var index = -1,
1153         result = Array(set.size);
1154
1155     set.forEach(function(value) {
1156       result[++index] = value;
1157     });
1158     return result;
1159   }
1160
1161   /**
1162    * Gets the number of symbols in `string`.
1163    *
1164    * @private
1165    * @param {string} string The string to inspect.
1166    * @returns {number} Returns the string size.
1167    */
1168   function stringSize(string) {
1169     if (!(string && reHasComplexSymbol.test(string))) {
1170       return string.length;
1171     }
1172     var result = reComplexSymbol.lastIndex = 0;
1173     while (reComplexSymbol.test(string)) {
1174       result++;
1175     }
1176     return result;
1177   }
1178
1179   /**
1180    * Converts `string` to an array.
1181    *
1182    * @private
1183    * @param {string} string The string to convert.
1184    * @returns {Array} Returns the converted array.
1185    */
1186   function stringToArray(string) {
1187     return string.match(reComplexSymbol);
1188   }
1189
1190   /**
1191    * Used by `_.unescape` to convert HTML entities to characters.
1192    *
1193    * @private
1194    * @param {string} chr The matched character to unescape.
1195    * @returns {string} Returns the unescaped character.
1196    */
1197   function unescapeHtmlChar(chr) {
1198     return htmlUnescapes[chr];
1199   }
1200
1201   /*--------------------------------------------------------------------------*/
1202
1203   /**
1204    * Create a new pristine `lodash` function using the `context` object.
1205    *
1206    * @static
1207    * @memberOf _
1208    * @since 1.1.0
1209    * @category Util
1210    * @param {Object} [context=root] The context object.
1211    * @returns {Function} Returns a new `lodash` function.
1212    * @example
1213    *
1214    * _.mixin({ 'foo': _.constant('foo') });
1215    *
1216    * var lodash = _.runInContext();
1217    * lodash.mixin({ 'bar': lodash.constant('bar') });
1218    *
1219    * _.isFunction(_.foo);
1220    * // => true
1221    * _.isFunction(_.bar);
1222    * // => false
1223    *
1224    * lodash.isFunction(lodash.foo);
1225    * // => false
1226    * lodash.isFunction(lodash.bar);
1227    * // => true
1228    *
1229    * // Use `context` to mock `Date#getTime` use in `_.now`.
1230    * var mock = _.runInContext({
1231    *   'Date': function() {
1232    *     return { 'getTime': getTimeMock };
1233    *   }
1234    * });
1235    *
1236    * // Create a suped-up `defer` in Node.js.
1237    * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1238    */
1239   function runInContext(context) {
1240     context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
1241
1242     /** Built-in constructor references. */
1243     var Date = context.Date,
1244         Error = context.Error,
1245         Math = context.Math,
1246         RegExp = context.RegExp,
1247         TypeError = context.TypeError;
1248
1249     /** Used for built-in method references. */
1250     var arrayProto = context.Array.prototype,
1251         objectProto = context.Object.prototype,
1252         stringProto = context.String.prototype;
1253
1254     /** Used to resolve the decompiled source of functions. */
1255     var funcToString = context.Function.prototype.toString;
1256
1257     /** Used to check objects for own properties. */
1258     var hasOwnProperty = objectProto.hasOwnProperty;
1259
1260     /** Used to generate unique IDs. */
1261     var idCounter = 0;
1262
1263     /** Used to infer the `Object` constructor. */
1264     var objectCtorString = funcToString.call(Object);
1265
1266     /**
1267      * Used to resolve the
1268      * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1269      * of values.
1270      */
1271     var objectToString = objectProto.toString;
1272
1273     /** Used to restore the original `_` reference in `_.noConflict`. */
1274     var oldDash = root._;
1275
1276     /** Used to detect if a method is native. */
1277     var reIsNative = RegExp('^' +
1278       funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1279       .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1280     );
1281
1282     /** Built-in value references. */
1283     var Buffer = moduleExports ? context.Buffer : undefined,
1284         Reflect = context.Reflect,
1285         Symbol = context.Symbol,
1286         Uint8Array = context.Uint8Array,
1287         clearTimeout = context.clearTimeout,
1288         enumerate = Reflect ? Reflect.enumerate : undefined,
1289         getOwnPropertySymbols = Object.getOwnPropertySymbols,
1290         iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
1291         objectCreate = Object.create,
1292         propertyIsEnumerable = objectProto.propertyIsEnumerable,
1293         setTimeout = context.setTimeout,
1294         splice = arrayProto.splice;
1295
1296     /* Built-in method references for those with the same name as other `lodash` methods. */
1297     var nativeCeil = Math.ceil,
1298         nativeFloor = Math.floor,
1299         nativeGetPrototype = Object.getPrototypeOf,
1300         nativeIsFinite = context.isFinite,
1301         nativeJoin = arrayProto.join,
1302         nativeKeys = Object.keys,
1303         nativeMax = Math.max,
1304         nativeMin = Math.min,
1305         nativeParseInt = context.parseInt,
1306         nativeRandom = Math.random,
1307         nativeReplace = stringProto.replace,
1308         nativeReverse = arrayProto.reverse,
1309         nativeSplit = stringProto.split;
1310
1311     /* Built-in method references that are verified to be native. */
1312     var DataView = getNative(context, 'DataView'),
1313         Map = getNative(context, 'Map'),
1314         Promise = getNative(context, 'Promise'),
1315         Set = getNative(context, 'Set'),
1316         WeakMap = getNative(context, 'WeakMap'),
1317         nativeCreate = getNative(Object, 'create');
1318
1319     /** Used to store function metadata. */
1320     var metaMap = WeakMap && new WeakMap;
1321
1322     /** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */
1323     var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');
1324
1325     /** Used to lookup unminified function names. */
1326     var realNames = {};
1327
1328     /** Used to detect maps, sets, and weakmaps. */
1329     var dataViewCtorString = toSource(DataView),
1330         mapCtorString = toSource(Map),
1331         promiseCtorString = toSource(Promise),
1332         setCtorString = toSource(Set),
1333         weakMapCtorString = toSource(WeakMap);
1334
1335     /** Used to convert symbols to primitives and strings. */
1336     var symbolProto = Symbol ? Symbol.prototype : undefined,
1337         symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
1338         symbolToString = symbolProto ? symbolProto.toString : undefined;
1339
1340     /*------------------------------------------------------------------------*/
1341
1342     /**
1343      * Creates a `lodash` object which wraps `value` to enable implicit method
1344      * chain sequences. Methods that operate on and return arrays, collections,
1345      * and functions can be chained together. Methods that retrieve a single value
1346      * or may return a primitive value will automatically end the chain sequence
1347      * and return the unwrapped value. Otherwise, the value must be unwrapped
1348      * with `_#value`.
1349      *
1350      * Explicit chain sequences, which must be unwrapped with `_#value`, may be
1351      * enabled using `_.chain`.
1352      *
1353      * The execution of chained methods is lazy, that is, it's deferred until
1354      * `_#value` is implicitly or explicitly called.
1355      *
1356      * Lazy evaluation allows several methods to support shortcut fusion.
1357      * Shortcut fusion is an optimization to merge iteratee calls; this avoids
1358      * the creation of intermediate arrays and can greatly reduce the number of
1359      * iteratee executions. Sections of a chain sequence qualify for shortcut
1360      * fusion if the section is applied to an array of at least `200` elements
1361      * and any iteratees accept only one argument. The heuristic for whether a
1362      * section qualifies for shortcut fusion is subject to change.
1363      *
1364      * Chaining is supported in custom builds as long as the `_#value` method is
1365      * directly or indirectly included in the build.
1366      *
1367      * In addition to lodash methods, wrappers have `Array` and `String` methods.
1368      *
1369      * The wrapper `Array` methods are:
1370      * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1371      *
1372      * The wrapper `String` methods are:
1373      * `replace` and `split`
1374      *
1375      * The wrapper methods that support shortcut fusion are:
1376      * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1377      * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1378      * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1379      *
1380      * The chainable wrapper methods are:
1381      * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
1382      * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
1383      * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
1384      * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
1385      * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
1386      * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
1387      * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
1388      * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
1389      * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
1390      * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
1391      * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
1392      * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
1393      * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
1394      * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
1395      * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
1396      * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
1397      * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
1398      * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
1399      * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
1400      * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
1401      * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
1402      * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
1403      * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
1404      * `zipObject`, `zipObjectDeep`, and `zipWith`
1405      *
1406      * The wrapper methods that are **not** chainable by default are:
1407      * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1408      * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `divide`, `each`,
1409      * `eachRight`, `endsWith`, `eq`, `escape`, `escapeRegExp`, `every`, `find`,
1410      * `findIndex`, `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `first`,
1411      * `floor`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,
1412      * `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`,
1413      * `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`,
1414      * `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, `isBuffer`,
1415      * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`,
1416      * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`, `isMatch`,
1417      * `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`,
1418      * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`,
1419      * `isSet`, `isString`, `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`,
1420      * `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`,
1421      * `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, `min`, `minBy`, `multiply`,
1422      * `noConflict`, `noop`, `now`, `nth`, `pad`, `padEnd`, `padStart`, `parseInt`,
1423      * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`,
1424      * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
1425      * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`,
1426      * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toInteger`,
1427      * `toJSON`, `toLength`, `toLower`, `toNumber`, `toSafeInteger`, `toString`,
1428      * `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`,
1429      * `uniqueId`, `upperCase`, `upperFirst`, `value`, and `words`
1430      *
1431      * @name _
1432      * @constructor
1433      * @category Seq
1434      * @param {*} value The value to wrap in a `lodash` instance.
1435      * @returns {Object} Returns the new `lodash` wrapper instance.
1436      * @example
1437      *
1438      * function square(n) {
1439      *   return n * n;
1440      * }
1441      *
1442      * var wrapped = _([1, 2, 3]);
1443      *
1444      * // Returns an unwrapped value.
1445      * wrapped.reduce(_.add);
1446      * // => 6
1447      *
1448      * // Returns a wrapped value.
1449      * var squares = wrapped.map(square);
1450      *
1451      * _.isArray(squares);
1452      * // => false
1453      *
1454      * _.isArray(squares.value());
1455      * // => true
1456      */
1457     function lodash(value) {
1458       if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1459         if (value instanceof LodashWrapper) {
1460           return value;
1461         }
1462         if (hasOwnProperty.call(value, '__wrapped__')) {
1463           return wrapperClone(value);
1464         }
1465       }
1466       return new LodashWrapper(value);
1467     }
1468
1469     /**
1470      * The function whose prototype chain sequence wrappers inherit from.
1471      *
1472      * @private
1473      */
1474     function baseLodash() {
1475       // No operation performed.
1476     }
1477
1478     /**
1479      * The base constructor for creating `lodash` wrapper objects.
1480      *
1481      * @private
1482      * @param {*} value The value to wrap.
1483      * @param {boolean} [chainAll] Enable explicit method chain sequences.
1484      */
1485     function LodashWrapper(value, chainAll) {
1486       this.__wrapped__ = value;
1487       this.__actions__ = [];
1488       this.__chain__ = !!chainAll;
1489       this.__index__ = 0;
1490       this.__values__ = undefined;
1491     }
1492
1493     /**
1494      * By default, the template delimiters used by lodash are like those in
1495      * embedded Ruby (ERB). Change the following template settings to use
1496      * alternative delimiters.
1497      *
1498      * @static
1499      * @memberOf _
1500      * @type {Object}
1501      */
1502     lodash.templateSettings = {
1503
1504       /**
1505        * Used to detect `data` property values to be HTML-escaped.
1506        *
1507        * @memberOf _.templateSettings
1508        * @type {RegExp}
1509        */
1510       'escape': reEscape,
1511
1512       /**
1513        * Used to detect code to be evaluated.
1514        *
1515        * @memberOf _.templateSettings
1516        * @type {RegExp}
1517        */
1518       'evaluate': reEvaluate,
1519
1520       /**
1521        * Used to detect `data` property values to inject.
1522        *
1523        * @memberOf _.templateSettings
1524        * @type {RegExp}
1525        */
1526       'interpolate': reInterpolate,
1527
1528       /**
1529        * Used to reference the data object in the template text.
1530        *
1531        * @memberOf _.templateSettings
1532        * @type {string}
1533        */
1534       'variable': '',
1535
1536       /**
1537        * Used to import variables into the compiled template.
1538        *
1539        * @memberOf _.templateSettings
1540        * @type {Object}
1541        */
1542       'imports': {
1543
1544         /**
1545          * A reference to the `lodash` function.
1546          *
1547          * @memberOf _.templateSettings.imports
1548          * @type {Function}
1549          */
1550         '_': lodash
1551       }
1552     };
1553
1554     // Ensure wrappers are instances of `baseLodash`.
1555     lodash.prototype = baseLodash.prototype;
1556     lodash.prototype.constructor = lodash;
1557
1558     LodashWrapper.prototype = baseCreate(baseLodash.prototype);
1559     LodashWrapper.prototype.constructor = LodashWrapper;
1560
1561     /*------------------------------------------------------------------------*/
1562
1563     /**
1564      * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1565      *
1566      * @private
1567      * @constructor
1568      * @param {*} value The value to wrap.
1569      */
1570     function LazyWrapper(value) {
1571       this.__wrapped__ = value;
1572       this.__actions__ = [];
1573       this.__dir__ = 1;
1574       this.__filtered__ = false;
1575       this.__iteratees__ = [];
1576       this.__takeCount__ = MAX_ARRAY_LENGTH;
1577       this.__views__ = [];
1578     }
1579
1580     /**
1581      * Creates a clone of the lazy wrapper object.
1582      *
1583      * @private
1584      * @name clone
1585      * @memberOf LazyWrapper
1586      * @returns {Object} Returns the cloned `LazyWrapper` object.
1587      */
1588     function lazyClone() {
1589       var result = new LazyWrapper(this.__wrapped__);
1590       result.__actions__ = copyArray(this.__actions__);
1591       result.__dir__ = this.__dir__;
1592       result.__filtered__ = this.__filtered__;
1593       result.__iteratees__ = copyArray(this.__iteratees__);
1594       result.__takeCount__ = this.__takeCount__;
1595       result.__views__ = copyArray(this.__views__);
1596       return result;
1597     }
1598
1599     /**
1600      * Reverses the direction of lazy iteration.
1601      *
1602      * @private
1603      * @name reverse
1604      * @memberOf LazyWrapper
1605      * @returns {Object} Returns the new reversed `LazyWrapper` object.
1606      */
1607     function lazyReverse() {
1608       if (this.__filtered__) {
1609         var result = new LazyWrapper(this);
1610         result.__dir__ = -1;
1611         result.__filtered__ = true;
1612       } else {
1613         result = this.clone();
1614         result.__dir__ *= -1;
1615       }
1616       return result;
1617     }
1618
1619     /**
1620      * Extracts the unwrapped value from its lazy wrapper.
1621      *
1622      * @private
1623      * @name value
1624      * @memberOf LazyWrapper
1625      * @returns {*} Returns the unwrapped value.
1626      */
1627     function lazyValue() {
1628       var array = this.__wrapped__.value(),
1629           dir = this.__dir__,
1630           isArr = isArray(array),
1631           isRight = dir < 0,
1632           arrLength = isArr ? array.length : 0,
1633           view = getView(0, arrLength, this.__views__),
1634           start = view.start,
1635           end = view.end,
1636           length = end - start,
1637           index = isRight ? end : (start - 1),
1638           iteratees = this.__iteratees__,
1639           iterLength = iteratees.length,
1640           resIndex = 0,
1641           takeCount = nativeMin(length, this.__takeCount__);
1642
1643       if (!isArr || arrLength < LARGE_ARRAY_SIZE ||
1644           (arrLength == length && takeCount == length)) {
1645         return baseWrapperValue(array, this.__actions__);
1646       }
1647       var result = [];
1648
1649       outer:
1650       while (length-- && resIndex < takeCount) {
1651         index += dir;
1652
1653         var iterIndex = -1,
1654             value = array[index];
1655
1656         while (++iterIndex < iterLength) {
1657           var data = iteratees[iterIndex],
1658               iteratee = data.iteratee,
1659               type = data.type,
1660               computed = iteratee(value);
1661
1662           if (type == LAZY_MAP_FLAG) {
1663             value = computed;
1664           } else if (!computed) {
1665             if (type == LAZY_FILTER_FLAG) {
1666               continue outer;
1667             } else {
1668               break outer;
1669             }
1670           }
1671         }
1672         result[resIndex++] = value;
1673       }
1674       return result;
1675     }
1676
1677     // Ensure `LazyWrapper` is an instance of `baseLodash`.
1678     LazyWrapper.prototype = baseCreate(baseLodash.prototype);
1679     LazyWrapper.prototype.constructor = LazyWrapper;
1680
1681     /*------------------------------------------------------------------------*/
1682
1683     /**
1684      * Creates a hash object.
1685      *
1686      * @private
1687      * @constructor
1688      * @returns {Object} Returns the new hash object.
1689      */
1690     function Hash() {}
1691
1692     /**
1693      * Removes `key` and its value from the hash.
1694      *
1695      * @private
1696      * @param {Object} hash The hash to modify.
1697      * @param {string} key The key of the value to remove.
1698      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1699      */
1700     function hashDelete(hash, key) {
1701       return hashHas(hash, key) && delete hash[key];
1702     }
1703
1704     /**
1705      * Gets the hash value for `key`.
1706      *
1707      * @private
1708      * @param {Object} hash The hash to query.
1709      * @param {string} key The key of the value to get.
1710      * @returns {*} Returns the entry value.
1711      */
1712     function hashGet(hash, key) {
1713       if (nativeCreate) {
1714         var result = hash[key];
1715         return result === HASH_UNDEFINED ? undefined : result;
1716       }
1717       return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
1718     }
1719
1720     /**
1721      * Checks if a hash value for `key` exists.
1722      *
1723      * @private
1724      * @param {Object} hash The hash to query.
1725      * @param {string} key The key of the entry to check.
1726      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1727      */
1728     function hashHas(hash, key) {
1729       return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
1730     }
1731
1732     /**
1733      * Sets the hash `key` to `value`.
1734      *
1735      * @private
1736      * @param {Object} hash The hash to modify.
1737      * @param {string} key The key of the value to set.
1738      * @param {*} value The value to set.
1739      */
1740     function hashSet(hash, key, value) {
1741       hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
1742     }
1743
1744     // Avoid inheriting from `Object.prototype` when possible.
1745     Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
1746
1747     /*------------------------------------------------------------------------*/
1748
1749     /**
1750      * Creates a map cache object to store key-value pairs.
1751      *
1752      * @private
1753      * @constructor
1754      * @param {Array} [values] The values to cache.
1755      */
1756     function MapCache(values) {
1757       var index = -1,
1758           length = values ? values.length : 0;
1759
1760       this.clear();
1761       while (++index < length) {
1762         var entry = values[index];
1763         this.set(entry[0], entry[1]);
1764       }
1765     }
1766
1767     /**
1768      * Removes all key-value entries from the map.
1769      *
1770      * @private
1771      * @name clear
1772      * @memberOf MapCache
1773      */
1774     function mapClear() {
1775       this.__data__ = {
1776         'hash': new Hash,
1777         'map': Map ? new Map : [],
1778         'string': new Hash
1779       };
1780     }
1781
1782     /**
1783      * Removes `key` and its value from the map.
1784      *
1785      * @private
1786      * @name delete
1787      * @memberOf MapCache
1788      * @param {string} key The key of the value to remove.
1789      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1790      */
1791     function mapDelete(key) {
1792       var data = this.__data__;
1793       if (isKeyable(key)) {
1794         return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
1795       }
1796       return Map ? data.map['delete'](key) : assocDelete(data.map, key);
1797     }
1798
1799     /**
1800      * Gets the map value for `key`.
1801      *
1802      * @private
1803      * @name get
1804      * @memberOf MapCache
1805      * @param {string} key The key of the value to get.
1806      * @returns {*} Returns the entry value.
1807      */
1808     function mapGet(key) {
1809       var data = this.__data__;
1810       if (isKeyable(key)) {
1811         return hashGet(typeof key == 'string' ? data.string : data.hash, key);
1812       }
1813       return Map ? data.map.get(key) : assocGet(data.map, key);
1814     }
1815
1816     /**
1817      * Checks if a map value for `key` exists.
1818      *
1819      * @private
1820      * @name has
1821      * @memberOf MapCache
1822      * @param {string} key The key of the entry to check.
1823      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1824      */
1825     function mapHas(key) {
1826       var data = this.__data__;
1827       if (isKeyable(key)) {
1828         return hashHas(typeof key == 'string' ? data.string : data.hash, key);
1829       }
1830       return Map ? data.map.has(key) : assocHas(data.map, key);
1831     }
1832
1833     /**
1834      * Sets the map `key` to `value`.
1835      *
1836      * @private
1837      * @name set
1838      * @memberOf MapCache
1839      * @param {string} key The key of the value to set.
1840      * @param {*} value The value to set.
1841      * @returns {Object} Returns the map cache instance.
1842      */
1843     function mapSet(key, value) {
1844       var data = this.__data__;
1845       if (isKeyable(key)) {
1846         hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
1847       } else if (Map) {
1848         data.map.set(key, value);
1849       } else {
1850         assocSet(data.map, key, value);
1851       }
1852       return this;
1853     }
1854
1855     // Add methods to `MapCache`.
1856     MapCache.prototype.clear = mapClear;
1857     MapCache.prototype['delete'] = mapDelete;
1858     MapCache.prototype.get = mapGet;
1859     MapCache.prototype.has = mapHas;
1860     MapCache.prototype.set = mapSet;
1861
1862     /*------------------------------------------------------------------------*/
1863
1864     /**
1865      *
1866      * Creates a set cache object to store unique values.
1867      *
1868      * @private
1869      * @constructor
1870      * @param {Array} [values] The values to cache.
1871      */
1872     function SetCache(values) {
1873       var index = -1,
1874           length = values ? values.length : 0;
1875
1876       this.__data__ = new MapCache;
1877       while (++index < length) {
1878         this.push(values[index]);
1879       }
1880     }
1881
1882     /**
1883      * Checks if `value` is in `cache`.
1884      *
1885      * @private
1886      * @param {Object} cache The set cache to search.
1887      * @param {*} value The value to search for.
1888      * @returns {number} Returns `true` if `value` is found, else `false`.
1889      */
1890     function cacheHas(cache, value) {
1891       var map = cache.__data__;
1892       if (isKeyable(value)) {
1893         var data = map.__data__,
1894             hash = typeof value == 'string' ? data.string : data.hash;
1895
1896         return hash[value] === HASH_UNDEFINED;
1897       }
1898       return map.has(value);
1899     }
1900
1901     /**
1902      * Adds `value` to the set cache.
1903      *
1904      * @private
1905      * @name push
1906      * @memberOf SetCache
1907      * @param {*} value The value to cache.
1908      */
1909     function cachePush(value) {
1910       var map = this.__data__;
1911       if (isKeyable(value)) {
1912         var data = map.__data__,
1913             hash = typeof value == 'string' ? data.string : data.hash;
1914
1915         hash[value] = HASH_UNDEFINED;
1916       }
1917       else {
1918         map.set(value, HASH_UNDEFINED);
1919       }
1920     }
1921
1922     // Add methods to `SetCache`.
1923     SetCache.prototype.push = cachePush;
1924
1925     /*------------------------------------------------------------------------*/
1926
1927     /**
1928      * Creates a stack cache object to store key-value pairs.
1929      *
1930      * @private
1931      * @constructor
1932      * @param {Array} [values] The values to cache.
1933      */
1934     function Stack(values) {
1935       var index = -1,
1936           length = values ? values.length : 0;
1937
1938       this.clear();
1939       while (++index < length) {
1940         var entry = values[index];
1941         this.set(entry[0], entry[1]);
1942       }
1943     }
1944
1945     /**
1946      * Removes all key-value entries from the stack.
1947      *
1948      * @private
1949      * @name clear
1950      * @memberOf Stack
1951      */
1952     function stackClear() {
1953       this.__data__ = { 'array': [], 'map': null };
1954     }
1955
1956     /**
1957      * Removes `key` and its value from the stack.
1958      *
1959      * @private
1960      * @name delete
1961      * @memberOf Stack
1962      * @param {string} key The key of the value to remove.
1963      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1964      */
1965     function stackDelete(key) {
1966       var data = this.__data__,
1967           array = data.array;
1968
1969       return array ? assocDelete(array, key) : data.map['delete'](key);
1970     }
1971
1972     /**
1973      * Gets the stack value for `key`.
1974      *
1975      * @private
1976      * @name get
1977      * @memberOf Stack
1978      * @param {string} key The key of the value to get.
1979      * @returns {*} Returns the entry value.
1980      */
1981     function stackGet(key) {
1982       var data = this.__data__,
1983           array = data.array;
1984
1985       return array ? assocGet(array, key) : data.map.get(key);
1986     }
1987
1988     /**
1989      * Checks if a stack value for `key` exists.
1990      *
1991      * @private
1992      * @name has
1993      * @memberOf Stack
1994      * @param {string} key The key of the entry to check.
1995      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1996      */
1997     function stackHas(key) {
1998       var data = this.__data__,
1999           array = data.array;
2000
2001       return array ? assocHas(array, key) : data.map.has(key);
2002     }
2003
2004     /**
2005      * Sets the stack `key` to `value`.
2006      *
2007      * @private
2008      * @name set
2009      * @memberOf Stack
2010      * @param {string} key The key of the value to set.
2011      * @param {*} value The value to set.
2012      * @returns {Object} Returns the stack cache instance.
2013      */
2014     function stackSet(key, value) {
2015       var data = this.__data__,
2016           array = data.array;
2017
2018       if (array) {
2019         if (array.length < (LARGE_ARRAY_SIZE - 1)) {
2020           assocSet(array, key, value);
2021         } else {
2022           data.array = null;
2023           data.map = new MapCache(array);
2024         }
2025       }
2026       var map = data.map;
2027       if (map) {
2028         map.set(key, value);
2029       }
2030       return this;
2031     }
2032
2033     // Add methods to `Stack`.
2034     Stack.prototype.clear = stackClear;
2035     Stack.prototype['delete'] = stackDelete;
2036     Stack.prototype.get = stackGet;
2037     Stack.prototype.has = stackHas;
2038     Stack.prototype.set = stackSet;
2039
2040     /*------------------------------------------------------------------------*/
2041
2042     /**
2043      * Removes `key` and its value from the associative array.
2044      *
2045      * @private
2046      * @param {Array} array The array to modify.
2047      * @param {string} key The key of the value to remove.
2048      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2049      */
2050     function assocDelete(array, key) {
2051       var index = assocIndexOf(array, key);
2052       if (index < 0) {
2053         return false;
2054       }
2055       var lastIndex = array.length - 1;
2056       if (index == lastIndex) {
2057         array.pop();
2058       } else {
2059         splice.call(array, index, 1);
2060       }
2061       return true;
2062     }
2063
2064     /**
2065      * Gets the associative array value for `key`.
2066      *
2067      * @private
2068      * @param {Array} array The array to query.
2069      * @param {string} key The key of the value to get.
2070      * @returns {*} Returns the entry value.
2071      */
2072     function assocGet(array, key) {
2073       var index = assocIndexOf(array, key);
2074       return index < 0 ? undefined : array[index][1];
2075     }
2076
2077     /**
2078      * Checks if an associative array value for `key` exists.
2079      *
2080      * @private
2081      * @param {Array} array The array to query.
2082      * @param {string} key The key of the entry to check.
2083      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2084      */
2085     function assocHas(array, key) {
2086       return assocIndexOf(array, key) > -1;
2087     }
2088
2089     /**
2090      * Gets the index at which the `key` is found in `array` of key-value pairs.
2091      *
2092      * @private
2093      * @param {Array} array The array to search.
2094      * @param {*} key The key to search for.
2095      * @returns {number} Returns the index of the matched value, else `-1`.
2096      */
2097     function assocIndexOf(array, key) {
2098       var length = array.length;
2099       while (length--) {
2100         if (eq(array[length][0], key)) {
2101           return length;
2102         }
2103       }
2104       return -1;
2105     }
2106
2107     /**
2108      * Sets the associative array `key` to `value`.
2109      *
2110      * @private
2111      * @param {Array} array The array to modify.
2112      * @param {string} key The key of the value to set.
2113      * @param {*} value The value to set.
2114      */
2115     function assocSet(array, key, value) {
2116       var index = assocIndexOf(array, key);
2117       if (index < 0) {
2118         array.push([key, value]);
2119       } else {
2120         array[index][1] = value;
2121       }
2122     }
2123
2124     /*------------------------------------------------------------------------*/
2125
2126     /**
2127      * Used by `_.defaults` to customize its `_.assignIn` use.
2128      *
2129      * @private
2130      * @param {*} objValue The destination value.
2131      * @param {*} srcValue The source value.
2132      * @param {string} key The key of the property to assign.
2133      * @param {Object} object The parent object of `objValue`.
2134      * @returns {*} Returns the value to assign.
2135      */
2136     function assignInDefaults(objValue, srcValue, key, object) {
2137       if (objValue === undefined ||
2138           (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
2139         return srcValue;
2140       }
2141       return objValue;
2142     }
2143
2144     /**
2145      * This function is like `assignValue` except that it doesn't assign
2146      * `undefined` values.
2147      *
2148      * @private
2149      * @param {Object} object The object to modify.
2150      * @param {string} key The key of the property to assign.
2151      * @param {*} value The value to assign.
2152      */
2153     function assignMergeValue(object, key, value) {
2154       if ((value !== undefined && !eq(object[key], value)) ||
2155           (typeof key == 'number' && value === undefined && !(key in object))) {
2156         object[key] = value;
2157       }
2158     }
2159
2160     /**
2161      * Assigns `value` to `key` of `object` if the existing value is not equivalent
2162      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
2163      * for equality comparisons.
2164      *
2165      * @private
2166      * @param {Object} object The object to modify.
2167      * @param {string} key The key of the property to assign.
2168      * @param {*} value The value to assign.
2169      */
2170     function assignValue(object, key, value) {
2171       var objValue = object[key];
2172       if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
2173           (value === undefined && !(key in object))) {
2174         object[key] = value;
2175       }
2176     }
2177
2178     /**
2179      * Aggregates elements of `collection` on `accumulator` with keys transformed
2180      * by `iteratee` and values set by `setter`.
2181      *
2182      * @private
2183      * @param {Array|Object} collection The collection to iterate over.
2184      * @param {Function} setter The function to set `accumulator` values.
2185      * @param {Function} iteratee The iteratee to transform keys.
2186      * @param {Object} accumulator The initial aggregated object.
2187      * @returns {Function} Returns `accumulator`.
2188      */
2189     function baseAggregator(collection, setter, iteratee, accumulator) {
2190       baseEach(collection, function(value, key, collection) {
2191         setter(accumulator, value, iteratee(value), collection);
2192       });
2193       return accumulator;
2194     }
2195
2196     /**
2197      * The base implementation of `_.assign` without support for multiple sources
2198      * or `customizer` functions.
2199      *
2200      * @private
2201      * @param {Object} object The destination object.
2202      * @param {Object} source The source object.
2203      * @returns {Object} Returns `object`.
2204      */
2205     function baseAssign(object, source) {
2206       return object && copyObject(source, keys(source), object);
2207     }
2208
2209     /**
2210      * The base implementation of `_.at` without support for individual paths.
2211      *
2212      * @private
2213      * @param {Object} object The object to iterate over.
2214      * @param {string[]} paths The property paths of elements to pick.
2215      * @returns {Array} Returns the new array of picked elements.
2216      */
2217     function baseAt(object, paths) {
2218       var index = -1,
2219           isNil = object == null,
2220           length = paths.length,
2221           result = Array(length);
2222
2223       while (++index < length) {
2224         result[index] = isNil ? undefined : get(object, paths[index]);
2225       }
2226       return result;
2227     }
2228
2229     /**
2230      * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
2231      *
2232      * @private
2233      * @param {number} number The number to clamp.
2234      * @param {number} [lower] The lower bound.
2235      * @param {number} upper The upper bound.
2236      * @returns {number} Returns the clamped number.
2237      */
2238     function baseClamp(number, lower, upper) {
2239       if (number === number) {
2240         if (upper !== undefined) {
2241           number = number <= upper ? number : upper;
2242         }
2243         if (lower !== undefined) {
2244           number = number >= lower ? number : lower;
2245         }
2246       }
2247       return number;
2248     }
2249
2250     /**
2251      * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2252      * traversed objects.
2253      *
2254      * @private
2255      * @param {*} value The value to clone.
2256      * @param {boolean} [isDeep] Specify a deep clone.
2257      * @param {boolean} [isFull] Specify a clone including symbols.
2258      * @param {Function} [customizer] The function to customize cloning.
2259      * @param {string} [key] The key of `value`.
2260      * @param {Object} [object] The parent object of `value`.
2261      * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2262      * @returns {*} Returns the cloned value.
2263      */
2264     function baseClone(value, isDeep, isFull, customizer, key, object, stack) {
2265       var result;
2266       if (customizer) {
2267         result = object ? customizer(value, key, object, stack) : customizer(value);
2268       }
2269       if (result !== undefined) {
2270         return result;
2271       }
2272       if (!isObject(value)) {
2273         return value;
2274       }
2275       var isArr = isArray(value);
2276       if (isArr) {
2277         result = initCloneArray(value);
2278         if (!isDeep) {
2279           return copyArray(value, result);
2280         }
2281       } else {
2282         var tag = getTag(value),
2283             isFunc = tag == funcTag || tag == genTag;
2284
2285         if (isBuffer(value)) {
2286           return cloneBuffer(value, isDeep);
2287         }
2288         if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2289           if (isHostObject(value)) {
2290             return object ? value : {};
2291           }
2292           result = initCloneObject(isFunc ? {} : value);
2293           if (!isDeep) {
2294             return copySymbols(value, baseAssign(result, value));
2295           }
2296         } else {
2297           if (!cloneableTags[tag]) {
2298             return object ? value : {};
2299           }
2300           result = initCloneByTag(value, tag, baseClone, isDeep);
2301         }
2302       }
2303       // Check for circular references and return its corresponding clone.
2304       stack || (stack = new Stack);
2305       var stacked = stack.get(value);
2306       if (stacked) {
2307         return stacked;
2308       }
2309       stack.set(value, result);
2310
2311       if (!isArr) {
2312         var props = isFull ? getAllKeys(value) : keys(value);
2313       }
2314       // Recursively populate clone (susceptible to call stack limits).
2315       arrayEach(props || value, function(subValue, key) {
2316         if (props) {
2317           key = subValue;
2318           subValue = value[key];
2319         }
2320         assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));
2321       });
2322       return result;
2323     }
2324
2325     /**
2326      * The base implementation of `_.conforms` which doesn't clone `source`.
2327      *
2328      * @private
2329      * @param {Object} source The object of property predicates to conform to.
2330      * @returns {Function} Returns the new function.
2331      */
2332     function baseConforms(source) {
2333       var props = keys(source),
2334           length = props.length;
2335
2336       return function(object) {
2337         if (object == null) {
2338           return !length;
2339         }
2340         var index = length;
2341         while (index--) {
2342           var key = props[index],
2343               predicate = source[key],
2344               value = object[key];
2345
2346           if ((value === undefined &&
2347               !(key in Object(object))) || !predicate(value)) {
2348             return false;
2349           }
2350         }
2351         return true;
2352       };
2353     }
2354
2355     /**
2356      * The base implementation of `_.create` without support for assigning
2357      * properties to the created object.
2358      *
2359      * @private
2360      * @param {Object} prototype The object to inherit from.
2361      * @returns {Object} Returns the new object.
2362      */
2363     function baseCreate(proto) {
2364       return isObject(proto) ? objectCreate(proto) : {};
2365     }
2366
2367     /**
2368      * The base implementation of `_.delay` and `_.defer` which accepts an array
2369      * of `func` arguments.
2370      *
2371      * @private
2372      * @param {Function} func The function to delay.
2373      * @param {number} wait The number of milliseconds to delay invocation.
2374      * @param {Object} args The arguments to provide to `func`.
2375      * @returns {number} Returns the timer id.
2376      */
2377     function baseDelay(func, wait, args) {
2378       if (typeof func != 'function') {
2379         throw new TypeError(FUNC_ERROR_TEXT);
2380       }
2381       return setTimeout(function() { func.apply(undefined, args); }, wait);
2382     }
2383
2384     /**
2385      * The base implementation of methods like `_.difference` without support
2386      * for excluding multiple arrays or iteratee shorthands.
2387      *
2388      * @private
2389      * @param {Array} array The array to inspect.
2390      * @param {Array} values The values to exclude.
2391      * @param {Function} [iteratee] The iteratee invoked per element.
2392      * @param {Function} [comparator] The comparator invoked per element.
2393      * @returns {Array} Returns the new array of filtered values.
2394      */
2395     function baseDifference(array, values, iteratee, comparator) {
2396       var index = -1,
2397           includes = arrayIncludes,
2398           isCommon = true,
2399           length = array.length,
2400           result = [],
2401           valuesLength = values.length;
2402
2403       if (!length) {
2404         return result;
2405       }
2406       if (iteratee) {
2407         values = arrayMap(values, baseUnary(iteratee));
2408       }
2409       if (comparator) {
2410         includes = arrayIncludesWith;
2411         isCommon = false;
2412       }
2413       else if (values.length >= LARGE_ARRAY_SIZE) {
2414         includes = cacheHas;
2415         isCommon = false;
2416         values = new SetCache(values);
2417       }
2418       outer:
2419       while (++index < length) {
2420         var value = array[index],
2421             computed = iteratee ? iteratee(value) : value;
2422
2423         value = (comparator || value !== 0) ? value : 0;
2424         if (isCommon && computed === computed) {
2425           var valuesIndex = valuesLength;
2426           while (valuesIndex--) {
2427             if (values[valuesIndex] === computed) {
2428               continue outer;
2429             }
2430           }
2431           result.push(value);
2432         }
2433         else if (!includes(values, computed, comparator)) {
2434           result.push(value);
2435         }
2436       }
2437       return result;
2438     }
2439
2440     /**
2441      * The base implementation of `_.forEach` without support for iteratee shorthands.
2442      *
2443      * @private
2444      * @param {Array|Object} collection The collection to iterate over.
2445      * @param {Function} iteratee The function invoked per iteration.
2446      * @returns {Array|Object} Returns `collection`.
2447      */
2448     var baseEach = createBaseEach(baseForOwn);
2449
2450     /**
2451      * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2452      *
2453      * @private
2454      * @param {Array|Object} collection The collection to iterate over.
2455      * @param {Function} iteratee The function invoked per iteration.
2456      * @returns {Array|Object} Returns `collection`.
2457      */
2458     var baseEachRight = createBaseEach(baseForOwnRight, true);
2459
2460     /**
2461      * The base implementation of `_.every` without support for iteratee shorthands.
2462      *
2463      * @private
2464      * @param {Array|Object} collection The collection to iterate over.
2465      * @param {Function} predicate The function invoked per iteration.
2466      * @returns {boolean} Returns `true` if all elements pass the predicate check,
2467      *  else `false`
2468      */
2469     function baseEvery(collection, predicate) {
2470       var result = true;
2471       baseEach(collection, function(value, index, collection) {
2472         result = !!predicate(value, index, collection);
2473         return result;
2474       });
2475       return result;
2476     }
2477
2478     /**
2479      * The base implementation of methods like `_.max` and `_.min` which accepts a
2480      * `comparator` to determine the extremum value.
2481      *
2482      * @private
2483      * @param {Array} array The array to iterate over.
2484      * @param {Function} iteratee The iteratee invoked per iteration.
2485      * @param {Function} comparator The comparator used to compare values.
2486      * @returns {*} Returns the extremum value.
2487      */
2488     function baseExtremum(array, iteratee, comparator) {
2489       var index = -1,
2490           length = array.length;
2491
2492       while (++index < length) {
2493         var value = array[index],
2494             current = iteratee(value);
2495
2496         if (current != null && (computed === undefined
2497               ? (current === current && !isSymbol(current))
2498               : comparator(current, computed)
2499             )) {
2500           var computed = current,
2501               result = value;
2502         }
2503       }
2504       return result;
2505     }
2506
2507     /**
2508      * The base implementation of `_.fill` without an iteratee call guard.
2509      *
2510      * @private
2511      * @param {Array} array The array to fill.
2512      * @param {*} value The value to fill `array` with.
2513      * @param {number} [start=0] The start position.
2514      * @param {number} [end=array.length] The end position.
2515      * @returns {Array} Returns `array`.
2516      */
2517     function baseFill(array, value, start, end) {
2518       var length = array.length;
2519
2520       start = toInteger(start);
2521       if (start < 0) {
2522         start = -start > length ? 0 : (length + start);
2523       }
2524       end = (end === undefined || end > length) ? length : toInteger(end);
2525       if (end < 0) {
2526         end += length;
2527       }
2528       end = start > end ? 0 : toLength(end);
2529       while (start < end) {
2530         array[start++] = value;
2531       }
2532       return array;
2533     }
2534
2535     /**
2536      * The base implementation of `_.filter` without support for iteratee shorthands.
2537      *
2538      * @private
2539      * @param {Array|Object} collection The collection to iterate over.
2540      * @param {Function} predicate The function invoked per iteration.
2541      * @returns {Array} Returns the new filtered array.
2542      */
2543     function baseFilter(collection, predicate) {
2544       var result = [];
2545       baseEach(collection, function(value, index, collection) {
2546         if (predicate(value, index, collection)) {
2547           result.push(value);
2548         }
2549       });
2550       return result;
2551     }
2552
2553     /**
2554      * The base implementation of `_.flatten` with support for restricting flattening.
2555      *
2556      * @private
2557      * @param {Array} array The array to flatten.
2558      * @param {number} depth The maximum recursion depth.
2559      * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
2560      * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
2561      * @param {Array} [result=[]] The initial result value.
2562      * @returns {Array} Returns the new flattened array.
2563      */
2564     function baseFlatten(array, depth, predicate, isStrict, result) {
2565       var index = -1,
2566           length = array.length;
2567
2568       predicate || (predicate = isFlattenable);
2569       result || (result = []);
2570
2571       while (++index < length) {
2572         var value = array[index];
2573         if (depth > 0 && predicate(value)) {
2574           if (depth > 1) {
2575             // Recursively flatten arrays (susceptible to call stack limits).
2576             baseFlatten(value, depth - 1, predicate, isStrict, result);
2577           } else {
2578             arrayPush(result, value);
2579           }
2580         } else if (!isStrict) {
2581           result[result.length] = value;
2582         }
2583       }
2584       return result;
2585     }
2586
2587     /**
2588      * The base implementation of `baseForOwn` which iterates over `object`
2589      * properties returned by `keysFunc` and invokes `iteratee` for each property.
2590      * Iteratee functions may exit iteration early by explicitly returning `false`.
2591      *
2592      * @private
2593      * @param {Object} object The object to iterate over.
2594      * @param {Function} iteratee The function invoked per iteration.
2595      * @param {Function} keysFunc The function to get the keys of `object`.
2596      * @returns {Object} Returns `object`.
2597      */
2598     var baseFor = createBaseFor();
2599
2600     /**
2601      * This function is like `baseFor` except that it iterates over properties
2602      * in the opposite order.
2603      *
2604      * @private
2605      * @param {Object} object The object to iterate over.
2606      * @param {Function} iteratee The function invoked per iteration.
2607      * @param {Function} keysFunc The function to get the keys of `object`.
2608      * @returns {Object} Returns `object`.
2609      */
2610     var baseForRight = createBaseFor(true);
2611
2612     /**
2613      * The base implementation of `_.forOwn` without support for iteratee shorthands.
2614      *
2615      * @private
2616      * @param {Object} object The object to iterate over.
2617      * @param {Function} iteratee The function invoked per iteration.
2618      * @returns {Object} Returns `object`.
2619      */
2620     function baseForOwn(object, iteratee) {
2621       return object && baseFor(object, iteratee, keys);
2622     }
2623
2624     /**
2625      * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
2626      *
2627      * @private
2628      * @param {Object} object The object to iterate over.
2629      * @param {Function} iteratee The function invoked per iteration.
2630      * @returns {Object} Returns `object`.
2631      */
2632     function baseForOwnRight(object, iteratee) {
2633       return object && baseForRight(object, iteratee, keys);
2634     }
2635
2636     /**
2637      * The base implementation of `_.functions` which creates an array of
2638      * `object` function property names filtered from `props`.
2639      *
2640      * @private
2641      * @param {Object} object The object to inspect.
2642      * @param {Array} props The property names to filter.
2643      * @returns {Array} Returns the new array of filtered property names.
2644      */
2645     function baseFunctions(object, props) {
2646       return arrayFilter(props, function(key) {
2647         return isFunction(object[key]);
2648       });
2649     }
2650
2651     /**
2652      * The base implementation of `_.get` without support for default values.
2653      *
2654      * @private
2655      * @param {Object} object The object to query.
2656      * @param {Array|string} path The path of the property to get.
2657      * @returns {*} Returns the resolved value.
2658      */
2659     function baseGet(object, path) {
2660       path = isKey(path, object) ? [path] : castPath(path);
2661
2662       var index = 0,
2663           length = path.length;
2664
2665       while (object != null && index < length) {
2666         object = object[toKey(path[index++])];
2667       }
2668       return (index && index == length) ? object : undefined;
2669     }
2670
2671     /**
2672      * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
2673      * `keysFunc` and `symbolsFunc` to get the enumerable property names and
2674      * symbols of `object`.
2675      *
2676      * @private
2677      * @param {Object} object The object to query.
2678      * @param {Function} keysFunc The function to get the keys of `object`.
2679      * @param {Function} symbolsFunc The function to get the symbols of `object`.
2680      * @returns {Array} Returns the array of property names and symbols.
2681      */
2682     function baseGetAllKeys(object, keysFunc, symbolsFunc) {
2683       var result = keysFunc(object);
2684       return isArray(object)
2685         ? result
2686         : arrayPush(result, symbolsFunc(object));
2687     }
2688
2689     /**
2690      * The base implementation of `_.gt` which doesn't coerce arguments to numbers.
2691      *
2692      * @private
2693      * @param {*} value The value to compare.
2694      * @param {*} other The other value to compare.
2695      * @returns {boolean} Returns `true` if `value` is greater than `other`,
2696      *  else `false`.
2697      */
2698     function baseGt(value, other) {
2699       return value > other;
2700     }
2701
2702     /**
2703      * The base implementation of `_.has` without support for deep paths.
2704      *
2705      * @private
2706      * @param {Object} object The object to query.
2707      * @param {Array|string} key The key to check.
2708      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2709      */
2710     function baseHas(object, key) {
2711       // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
2712       // that are composed entirely of index properties, return `false` for
2713       // `hasOwnProperty` checks of them.
2714       return hasOwnProperty.call(object, key) ||
2715         (typeof object == 'object' && key in object && getPrototype(object) === null);
2716     }
2717
2718     /**
2719      * The base implementation of `_.hasIn` without support for deep paths.
2720      *
2721      * @private
2722      * @param {Object} object The object to query.
2723      * @param {Array|string} key The key to check.
2724      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2725      */
2726     function baseHasIn(object, key) {
2727       return key in Object(object);
2728     }
2729
2730     /**
2731      * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
2732      *
2733      * @private
2734      * @param {number} number The number to check.
2735      * @param {number} start The start of the range.
2736      * @param {number} end The end of the range.
2737      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
2738      */
2739     function baseInRange(number, start, end) {
2740       return number >= nativeMin(start, end) && number < nativeMax(start, end);
2741     }
2742
2743     /**
2744      * The base implementation of methods like `_.intersection`, without support
2745      * for iteratee shorthands, that accepts an array of arrays to inspect.
2746      *
2747      * @private
2748      * @param {Array} arrays The arrays to inspect.
2749      * @param {Function} [iteratee] The iteratee invoked per element.
2750      * @param {Function} [comparator] The comparator invoked per element.
2751      * @returns {Array} Returns the new array of shared values.
2752      */
2753     function baseIntersection(arrays, iteratee, comparator) {
2754       var includes = comparator ? arrayIncludesWith : arrayIncludes,
2755           length = arrays[0].length,
2756           othLength = arrays.length,
2757           othIndex = othLength,
2758           caches = Array(othLength),
2759           maxLength = Infinity,
2760           result = [];
2761
2762       while (othIndex--) {
2763         var array = arrays[othIndex];
2764         if (othIndex && iteratee) {
2765           array = arrayMap(array, baseUnary(iteratee));
2766         }
2767         maxLength = nativeMin(array.length, maxLength);
2768         caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
2769           ? new SetCache(othIndex && array)
2770           : undefined;
2771       }
2772       array = arrays[0];
2773
2774       var index = -1,
2775           seen = caches[0];
2776
2777       outer:
2778       while (++index < length && result.length < maxLength) {
2779         var value = array[index],
2780             computed = iteratee ? iteratee(value) : value;
2781
2782         value = (comparator || value !== 0) ? value : 0;
2783         if (!(seen
2784               ? cacheHas(seen, computed)
2785               : includes(result, computed, comparator)
2786             )) {
2787           othIndex = othLength;
2788           while (--othIndex) {
2789             var cache = caches[othIndex];
2790             if (!(cache
2791                   ? cacheHas(cache, computed)
2792                   : includes(arrays[othIndex], computed, comparator))
2793                 ) {
2794               continue outer;
2795             }
2796           }
2797           if (seen) {
2798             seen.push(computed);
2799           }
2800           result.push(value);
2801         }
2802       }
2803       return result;
2804     }
2805
2806     /**
2807      * The base implementation of `_.invert` and `_.invertBy` which inverts
2808      * `object` with values transformed by `iteratee` and set by `setter`.
2809      *
2810      * @private
2811      * @param {Object} object The object to iterate over.
2812      * @param {Function} setter The function to set `accumulator` values.
2813      * @param {Function} iteratee The iteratee to transform values.
2814      * @param {Object} accumulator The initial inverted object.
2815      * @returns {Function} Returns `accumulator`.
2816      */
2817     function baseInverter(object, setter, iteratee, accumulator) {
2818       baseForOwn(object, function(value, key, object) {
2819         setter(accumulator, iteratee(value), key, object);
2820       });
2821       return accumulator;
2822     }
2823
2824     /**
2825      * The base implementation of `_.invoke` without support for individual
2826      * method arguments.
2827      *
2828      * @private
2829      * @param {Object} object The object to query.
2830      * @param {Array|string} path The path of the method to invoke.
2831      * @param {Array} args The arguments to invoke the method with.
2832      * @returns {*} Returns the result of the invoked method.
2833      */
2834     function baseInvoke(object, path, args) {
2835       if (!isKey(path, object)) {
2836         path = castPath(path);
2837         object = parent(object, path);
2838         path = last(path);
2839       }
2840       var func = object == null ? object : object[toKey(path)];
2841       return func == null ? undefined : apply(func, object, args);
2842     }
2843
2844     /**
2845      * The base implementation of `_.isEqual` which supports partial comparisons
2846      * and tracks traversed objects.
2847      *
2848      * @private
2849      * @param {*} value The value to compare.
2850      * @param {*} other The other value to compare.
2851      * @param {Function} [customizer] The function to customize comparisons.
2852      * @param {boolean} [bitmask] The bitmask of comparison flags.
2853      *  The bitmask may be composed of the following flags:
2854      *     1 - Unordered comparison
2855      *     2 - Partial comparison
2856      * @param {Object} [stack] Tracks traversed `value` and `other` objects.
2857      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2858      */
2859     function baseIsEqual(value, other, customizer, bitmask, stack) {
2860       if (value === other) {
2861         return true;
2862       }
2863       if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
2864         return value !== value && other !== other;
2865       }
2866       return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
2867     }
2868
2869     /**
2870      * A specialized version of `baseIsEqual` for arrays and objects which performs
2871      * deep comparisons and tracks traversed objects enabling objects with circular
2872      * references to be compared.
2873      *
2874      * @private
2875      * @param {Object} object The object to compare.
2876      * @param {Object} other The other object to compare.
2877      * @param {Function} equalFunc The function to determine equivalents of values.
2878      * @param {Function} [customizer] The function to customize comparisons.
2879      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual`
2880      *  for more details.
2881      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
2882      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
2883      */
2884     function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
2885       var objIsArr = isArray(object),
2886           othIsArr = isArray(other),
2887           objTag = arrayTag,
2888           othTag = arrayTag;
2889
2890       if (!objIsArr) {
2891         objTag = getTag(object);
2892         objTag = objTag == argsTag ? objectTag : objTag;
2893       }
2894       if (!othIsArr) {
2895         othTag = getTag(other);
2896         othTag = othTag == argsTag ? objectTag : othTag;
2897       }
2898       var objIsObj = objTag == objectTag && !isHostObject(object),
2899           othIsObj = othTag == objectTag && !isHostObject(other),
2900           isSameTag = objTag == othTag;
2901
2902       if (isSameTag && !objIsObj) {
2903         stack || (stack = new Stack);
2904         return (objIsArr || isTypedArray(object))
2905           ? equalArrays(object, other, equalFunc, customizer, bitmask, stack)
2906           : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack);
2907       }
2908       if (!(bitmask & PARTIAL_COMPARE_FLAG)) {
2909         var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
2910             othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
2911
2912         if (objIsWrapped || othIsWrapped) {
2913           var objUnwrapped = objIsWrapped ? object.value() : object,
2914               othUnwrapped = othIsWrapped ? other.value() : other;
2915
2916           stack || (stack = new Stack);
2917           return equalFunc(objUnwrapped, othUnwrapped, customizer, bitmask, stack);
2918         }
2919       }
2920       if (!isSameTag) {
2921         return false;
2922       }
2923       stack || (stack = new Stack);
2924       return equalObjects(object, other, equalFunc, customizer, bitmask, stack);
2925     }
2926
2927     /**
2928      * The base implementation of `_.isMatch` without support for iteratee shorthands.
2929      *
2930      * @private
2931      * @param {Object} object The object to inspect.
2932      * @param {Object} source The object of property values to match.
2933      * @param {Array} matchData The property names, values, and compare flags to match.
2934      * @param {Function} [customizer] The function to customize comparisons.
2935      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
2936      */
2937     function baseIsMatch(object, source, matchData, customizer) {
2938       var index = matchData.length,
2939           length = index,
2940           noCustomizer = !customizer;
2941
2942       if (object == null) {
2943         return !length;
2944       }
2945       object = Object(object);
2946       while (index--) {
2947         var data = matchData[index];
2948         if ((noCustomizer && data[2])
2949               ? data[1] !== object[data[0]]
2950               : !(data[0] in object)
2951             ) {
2952           return false;
2953         }
2954       }
2955       while (++index < length) {
2956         data = matchData[index];
2957         var key = data[0],
2958             objValue = object[key],
2959             srcValue = data[1];
2960
2961         if (noCustomizer && data[2]) {
2962           if (objValue === undefined && !(key in object)) {
2963             return false;
2964           }
2965         } else {
2966           var stack = new Stack;
2967           if (customizer) {
2968             var result = customizer(objValue, srcValue, key, object, source, stack);
2969           }
2970           if (!(result === undefined
2971                 ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
2972                 : result
2973               )) {
2974             return false;
2975           }
2976         }
2977       }
2978       return true;
2979     }
2980
2981     /**
2982      * The base implementation of `_.iteratee`.
2983      *
2984      * @private
2985      * @param {*} [value=_.identity] The value to convert to an iteratee.
2986      * @returns {Function} Returns the iteratee.
2987      */
2988     function baseIteratee(value) {
2989       // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
2990       // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
2991       if (typeof value == 'function') {
2992         return value;
2993       }
2994       if (value == null) {
2995         return identity;
2996       }
2997       if (typeof value == 'object') {
2998         return isArray(value)
2999           ? baseMatchesProperty(value[0], value[1])
3000           : baseMatches(value);
3001       }
3002       return property(value);
3003     }
3004
3005     /**
3006      * The base implementation of `_.keys` which doesn't skip the constructor
3007      * property of prototypes or treat sparse arrays as dense.
3008      *
3009      * @private
3010      * @param {Object} object The object to query.
3011      * @returns {Array} Returns the array of property names.
3012      */
3013     function baseKeys(object) {
3014       return nativeKeys(Object(object));
3015     }
3016
3017     /**
3018      * The base implementation of `_.keysIn` which doesn't skip the constructor
3019      * property of prototypes or treat sparse arrays as dense.
3020      *
3021      * @private
3022      * @param {Object} object The object to query.
3023      * @returns {Array} Returns the array of property names.
3024      */
3025     function baseKeysIn(object) {
3026       object = object == null ? object : Object(object);
3027
3028       var result = [];
3029       for (var key in object) {
3030         result.push(key);
3031       }
3032       return result;
3033     }
3034
3035     // Fallback for IE < 9 with es6-shim.
3036     if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
3037       baseKeysIn = function(object) {
3038         return iteratorToArray(enumerate(object));
3039       };
3040     }
3041
3042     /**
3043      * The base implementation of `_.lt` which doesn't coerce arguments to numbers.
3044      *
3045      * @private
3046      * @param {*} value The value to compare.
3047      * @param {*} other The other value to compare.
3048      * @returns {boolean} Returns `true` if `value` is less than `other`,
3049      *  else `false`.
3050      */
3051     function baseLt(value, other) {
3052       return value < other;
3053     }
3054
3055     /**
3056      * The base implementation of `_.map` without support for iteratee shorthands.
3057      *
3058      * @private
3059      * @param {Array|Object} collection The collection to iterate over.
3060      * @param {Function} iteratee The function invoked per iteration.
3061      * @returns {Array} Returns the new mapped array.
3062      */
3063     function baseMap(collection, iteratee) {
3064       var index = -1,
3065           result = isArrayLike(collection) ? Array(collection.length) : [];
3066
3067       baseEach(collection, function(value, key, collection) {
3068         result[++index] = iteratee(value, key, collection);
3069       });
3070       return result;
3071     }
3072
3073     /**
3074      * The base implementation of `_.matches` which doesn't clone `source`.
3075      *
3076      * @private
3077      * @param {Object} source The object of property values to match.
3078      * @returns {Function} Returns the new function.
3079      */
3080     function baseMatches(source) {
3081       var matchData = getMatchData(source);
3082       if (matchData.length == 1 && matchData[0][2]) {
3083         return matchesStrictComparable(matchData[0][0], matchData[0][1]);
3084       }
3085       return function(object) {
3086         return object === source || baseIsMatch(object, source, matchData);
3087       };
3088     }
3089
3090     /**
3091      * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3092      *
3093      * @private
3094      * @param {string} path The path of the property to get.
3095      * @param {*} srcValue The value to match.
3096      * @returns {Function} Returns the new function.
3097      */
3098     function baseMatchesProperty(path, srcValue) {
3099       if (isKey(path) && isStrictComparable(srcValue)) {
3100         return matchesStrictComparable(toKey(path), srcValue);
3101       }
3102       return function(object) {
3103         var objValue = get(object, path);
3104         return (objValue === undefined && objValue === srcValue)
3105           ? hasIn(object, path)
3106           : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
3107       };
3108     }
3109
3110     /**
3111      * The base implementation of `_.merge` without support for multiple sources.
3112      *
3113      * @private
3114      * @param {Object} object The destination object.
3115      * @param {Object} source The source object.
3116      * @param {number} srcIndex The index of `source`.
3117      * @param {Function} [customizer] The function to customize merged values.
3118      * @param {Object} [stack] Tracks traversed source values and their merged
3119      *  counterparts.
3120      */
3121     function baseMerge(object, source, srcIndex, customizer, stack) {
3122       if (object === source) {
3123         return;
3124       }
3125       if (!(isArray(source) || isTypedArray(source))) {
3126         var props = keysIn(source);
3127       }
3128       arrayEach(props || source, function(srcValue, key) {
3129         if (props) {
3130           key = srcValue;
3131           srcValue = source[key];
3132         }
3133         if (isObject(srcValue)) {
3134           stack || (stack = new Stack);
3135           baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3136         }
3137         else {
3138           var newValue = customizer
3139             ? customizer(object[key], srcValue, (key + ''), object, source, stack)
3140             : undefined;
3141
3142           if (newValue === undefined) {
3143             newValue = srcValue;
3144           }
3145           assignMergeValue(object, key, newValue);
3146         }
3147       });
3148     }
3149
3150     /**
3151      * A specialized version of `baseMerge` for arrays and objects which performs
3152      * deep merges and tracks traversed objects enabling objects with circular
3153      * references to be merged.
3154      *
3155      * @private
3156      * @param {Object} object The destination object.
3157      * @param {Object} source The source object.
3158      * @param {string} key The key of the value to merge.
3159      * @param {number} srcIndex The index of `source`.
3160      * @param {Function} mergeFunc The function to merge values.
3161      * @param {Function} [customizer] The function to customize assigned values.
3162      * @param {Object} [stack] Tracks traversed source values and their merged
3163      *  counterparts.
3164      */
3165     function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3166       var objValue = object[key],
3167           srcValue = source[key],
3168           stacked = stack.get(srcValue);
3169
3170       if (stacked) {
3171         assignMergeValue(object, key, stacked);
3172         return;
3173       }
3174       var newValue = customizer
3175         ? customizer(objValue, srcValue, (key + ''), object, source, stack)
3176         : undefined;
3177
3178       var isCommon = newValue === undefined;
3179
3180       if (isCommon) {
3181         newValue = srcValue;
3182         if (isArray(srcValue) || isTypedArray(srcValue)) {
3183           if (isArray(objValue)) {
3184             newValue = objValue;
3185           }
3186           else if (isArrayLikeObject(objValue)) {
3187             newValue = copyArray(objValue);
3188           }
3189           else {
3190             isCommon = false;
3191             newValue = baseClone(srcValue, true);
3192           }
3193         }
3194         else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3195           if (isArguments(objValue)) {
3196             newValue = toPlainObject(objValue);
3197           }
3198           else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
3199             isCommon = false;
3200             newValue = baseClone(srcValue, true);
3201           }
3202           else {
3203             newValue = objValue;
3204           }
3205         }
3206         else {
3207           isCommon = false;
3208         }
3209       }
3210       stack.set(srcValue, newValue);
3211
3212       if (isCommon) {
3213         // Recursively merge objects and arrays (susceptible to call stack limits).
3214         mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3215       }
3216       stack['delete'](srcValue);
3217       assignMergeValue(object, key, newValue);
3218     }
3219
3220     /**
3221      * The base implementation of `_.nth` which doesn't coerce `n` to an integer.
3222      *
3223      * @private
3224      * @param {Array} array The array to query.
3225      * @param {number} n The index of the element to return.
3226      * @returns {*} Returns the nth element of `array`.
3227      */
3228     function baseNth(array, n) {
3229       var length = array.length;
3230       if (!length) {
3231         return;
3232       }
3233       n += n < 0 ? length : 0;
3234       return isIndex(n, length) ? array[n] : undefined;
3235     }
3236
3237     /**
3238      * The base implementation of `_.orderBy` without param guards.
3239      *
3240      * @private
3241      * @param {Array|Object} collection The collection to iterate over.
3242      * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3243      * @param {string[]} orders The sort orders of `iteratees`.
3244      * @returns {Array} Returns the new sorted array.
3245      */
3246     function baseOrderBy(collection, iteratees, orders) {
3247       var index = -1;
3248       iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
3249
3250       var result = baseMap(collection, function(value, key, collection) {
3251         var criteria = arrayMap(iteratees, function(iteratee) {
3252           return iteratee(value);
3253         });
3254         return { 'criteria': criteria, 'index': ++index, 'value': value };
3255       });
3256
3257       return baseSortBy(result, function(object, other) {
3258         return compareMultiple(object, other, orders);
3259       });
3260     }
3261
3262     /**
3263      * The base implementation of `_.pick` without support for individual
3264      * property identifiers.
3265      *
3266      * @private
3267      * @param {Object} object The source object.
3268      * @param {string[]} props The property identifiers to pick.
3269      * @returns {Object} Returns the new object.
3270      */
3271     function basePick(object, props) {
3272       object = Object(object);
3273       return arrayReduce(props, function(result, key) {
3274         if (key in object) {
3275           result[key] = object[key];
3276         }
3277         return result;
3278       }, {});
3279     }
3280
3281     /**
3282      * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3283      *
3284      * @private
3285      * @param {Object} object The source object.
3286      * @param {Function} predicate The function invoked per property.
3287      * @returns {Object} Returns the new object.
3288      */
3289     function basePickBy(object, predicate) {
3290       var index = -1,
3291           props = getAllKeysIn(object),
3292           length = props.length,
3293           result = {};
3294
3295       while (++index < length) {
3296         var key = props[index],
3297             value = object[key];
3298
3299         if (predicate(value, key)) {
3300           result[key] = value;
3301         }
3302       }
3303       return result;
3304     }
3305
3306     /**
3307      * The base implementation of `_.property` without support for deep paths.
3308      *
3309      * @private
3310      * @param {string} key The key of the property to get.
3311      * @returns {Function} Returns the new function.
3312      */
3313     function baseProperty(key) {
3314       return function(object) {
3315         return object == null ? undefined : object[key];
3316       };
3317     }
3318
3319     /**
3320      * A specialized version of `baseProperty` which supports deep paths.
3321      *
3322      * @private
3323      * @param {Array|string} path The path of the property to get.
3324      * @returns {Function} Returns the new function.
3325      */
3326     function basePropertyDeep(path) {
3327       return function(object) {
3328         return baseGet(object, path);
3329       };
3330     }
3331
3332     /**
3333      * The base implementation of `_.pullAllBy` without support for iteratee
3334      * shorthands.
3335      *
3336      * @private
3337      * @param {Array} array The array to modify.
3338      * @param {Array} values The values to remove.
3339      * @param {Function} [iteratee] The iteratee invoked per element.
3340      * @param {Function} [comparator] The comparator invoked per element.
3341      * @returns {Array} Returns `array`.
3342      */
3343     function basePullAll(array, values, iteratee, comparator) {
3344       var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
3345           index = -1,
3346           length = values.length,
3347           seen = array;
3348
3349       if (iteratee) {
3350         seen = arrayMap(array, baseUnary(iteratee));
3351       }
3352       while (++index < length) {
3353         var fromIndex = 0,
3354             value = values[index],
3355             computed = iteratee ? iteratee(value) : value;
3356
3357         while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
3358           if (seen !== array) {
3359             splice.call(seen, fromIndex, 1);
3360           }
3361           splice.call(array, fromIndex, 1);
3362         }
3363       }
3364       return array;
3365     }
3366
3367     /**
3368      * The base implementation of `_.pullAt` without support for individual
3369      * indexes or capturing the removed elements.
3370      *
3371      * @private
3372      * @param {Array} array The array to modify.
3373      * @param {number[]} indexes The indexes of elements to remove.
3374      * @returns {Array} Returns `array`.
3375      */
3376     function basePullAt(array, indexes) {
3377       var length = array ? indexes.length : 0,
3378           lastIndex = length - 1;
3379
3380       while (length--) {
3381         var index = indexes[length];
3382         if (length == lastIndex || index !== previous) {
3383           var previous = index;
3384           if (isIndex(index)) {
3385             splice.call(array, index, 1);
3386           }
3387           else if (!isKey(index, array)) {
3388             var path = castPath(index),
3389                 object = parent(array, path);
3390
3391             if (object != null) {
3392               delete object[toKey(last(path))];
3393             }
3394           }
3395           else {
3396             delete array[toKey(index)];
3397           }
3398         }
3399       }
3400       return array;
3401     }
3402
3403     /**
3404      * The base implementation of `_.random` without support for returning
3405      * floating-point numbers.
3406      *
3407      * @private
3408      * @param {number} lower The lower bound.
3409      * @param {number} upper The upper bound.
3410      * @returns {number} Returns the random number.
3411      */
3412     function baseRandom(lower, upper) {
3413       return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3414     }
3415
3416     /**
3417      * The base implementation of `_.range` and `_.rangeRight` which doesn't
3418      * coerce arguments to numbers.
3419      *
3420      * @private
3421      * @param {number} start The start of the range.
3422      * @param {number} end The end of the range.
3423      * @param {number} step The value to increment or decrement by.
3424      * @param {boolean} [fromRight] Specify iterating from right to left.
3425      * @returns {Array} Returns the new array of numbers.
3426      */
3427     function baseRange(start, end, step, fromRight) {
3428       var index = -1,
3429           length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3430           result = Array(length);
3431
3432       while (length--) {
3433         result[fromRight ? length : ++index] = start;
3434         start += step;
3435       }
3436       return result;
3437     }
3438
3439     /**
3440      * The base implementation of `_.repeat` which doesn't coerce arguments.
3441      *
3442      * @private
3443      * @param {string} string The string to repeat.
3444      * @param {number} n The number of times to repeat the string.
3445      * @returns {string} Returns the repeated string.
3446      */
3447     function baseRepeat(string, n) {
3448       var result = '';
3449       if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
3450         return result;
3451       }
3452       // Leverage the exponentiation by squaring algorithm for a faster repeat.
3453       // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
3454       do {
3455         if (n % 2) {
3456           result += string;
3457         }
3458         n = nativeFloor(n / 2);
3459         if (n) {
3460           string += string;
3461         }
3462       } while (n);
3463
3464       return result;
3465     }
3466
3467     /**
3468      * The base implementation of `_.set`.
3469      *
3470      * @private
3471      * @param {Object} object The object to query.
3472      * @param {Array|string} path The path of the property to set.
3473      * @param {*} value The value to set.
3474      * @param {Function} [customizer] The function to customize path creation.
3475      * @returns {Object} Returns `object`.
3476      */
3477     function baseSet(object, path, value, customizer) {
3478       path = isKey(path, object) ? [path] : castPath(path);
3479
3480       var index = -1,
3481           length = path.length,
3482           lastIndex = length - 1,
3483           nested = object;
3484
3485       while (nested != null && ++index < length) {
3486         var key = toKey(path[index]);
3487         if (isObject(nested)) {
3488           var newValue = value;
3489           if (index != lastIndex) {
3490             var objValue = nested[key];
3491             newValue = customizer ? customizer(objValue, key, nested) : undefined;
3492             if (newValue === undefined) {
3493               newValue = objValue == null
3494                 ? (isIndex(path[index + 1]) ? [] : {})
3495                 : objValue;
3496             }
3497           }
3498           assignValue(nested, key, newValue);
3499         }
3500         nested = nested[key];
3501       }
3502       return object;
3503     }
3504
3505     /**
3506      * The base implementation of `setData` without support for hot loop detection.
3507      *
3508      * @private
3509      * @param {Function} func The function to associate metadata with.
3510      * @param {*} data The metadata.
3511      * @returns {Function} Returns `func`.
3512      */
3513     var baseSetData = !metaMap ? identity : function(func, data) {
3514       metaMap.set(func, data);
3515       return func;
3516     };
3517
3518     /**
3519      * The base implementation of `_.slice` without an iteratee call guard.
3520      *
3521      * @private
3522      * @param {Array} array The array to slice.
3523      * @param {number} [start=0] The start position.
3524      * @param {number} [end=array.length] The end position.
3525      * @returns {Array} Returns the slice of `array`.
3526      */
3527     function baseSlice(array, start, end) {
3528       var index = -1,
3529           length = array.length;
3530
3531       if (start < 0) {
3532         start = -start > length ? 0 : (length + start);
3533       }
3534       end = end > length ? length : end;
3535       if (end < 0) {
3536         end += length;
3537       }
3538       length = start > end ? 0 : ((end - start) >>> 0);
3539       start >>>= 0;
3540
3541       var result = Array(length);
3542       while (++index < length) {
3543         result[index] = array[index + start];
3544       }
3545       return result;
3546     }
3547
3548     /**
3549      * The base implementation of `_.some` without support for iteratee shorthands.
3550      *
3551      * @private
3552      * @param {Array|Object} collection The collection to iterate over.
3553      * @param {Function} predicate The function invoked per iteration.
3554      * @returns {boolean} Returns `true` if any element passes the predicate check,
3555      *  else `false`.
3556      */
3557     function baseSome(collection, predicate) {
3558       var result;
3559
3560       baseEach(collection, function(value, index, collection) {
3561         result = predicate(value, index, collection);
3562         return !result;
3563       });
3564       return !!result;
3565     }
3566
3567     /**
3568      * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
3569      * performs a binary search of `array` to determine the index at which `value`
3570      * should be inserted into `array` in order to maintain its sort order.
3571      *
3572      * @private
3573      * @param {Array} array The sorted array to inspect.
3574      * @param {*} value The value to evaluate.
3575      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3576      * @returns {number} Returns the index at which `value` should be inserted
3577      *  into `array`.
3578      */
3579     function baseSortedIndex(array, value, retHighest) {
3580       var low = 0,
3581           high = array ? array.length : low;
3582
3583       if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
3584         while (low < high) {
3585           var mid = (low + high) >>> 1,
3586               computed = array[mid];
3587
3588           if (computed !== null && !isSymbol(computed) &&
3589               (retHighest ? (computed <= value) : (computed < value))) {
3590             low = mid + 1;
3591           } else {
3592             high = mid;
3593           }
3594         }
3595         return high;
3596       }
3597       return baseSortedIndexBy(array, value, identity, retHighest);
3598     }
3599
3600     /**
3601      * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
3602      * which invokes `iteratee` for `value` and each element of `array` to compute
3603      * their sort ranking. The iteratee is invoked with one argument; (value).
3604      *
3605      * @private
3606      * @param {Array} array The sorted array to inspect.
3607      * @param {*} value The value to evaluate.
3608      * @param {Function} iteratee The iteratee invoked per element.
3609      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3610      * @returns {number} Returns the index at which `value` should be inserted
3611      *  into `array`.
3612      */
3613     function baseSortedIndexBy(array, value, iteratee, retHighest) {
3614       value = iteratee(value);
3615
3616       var low = 0,
3617           high = array ? array.length : 0,
3618           valIsNaN = value !== value,
3619           valIsNull = value === null,
3620           valIsSymbol = isSymbol(value),
3621           valIsUndefined = value === undefined;
3622
3623       while (low < high) {
3624         var mid = nativeFloor((low + high) / 2),
3625             computed = iteratee(array[mid]),
3626             othIsDefined = computed !== undefined,
3627             othIsNull = computed === null,
3628             othIsReflexive = computed === computed,
3629             othIsSymbol = isSymbol(computed);
3630
3631         if (valIsNaN) {
3632           var setLow = retHighest || othIsReflexive;
3633         } else if (valIsUndefined) {
3634           setLow = othIsReflexive && (retHighest || othIsDefined);
3635         } else if (valIsNull) {
3636           setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
3637         } else if (valIsSymbol) {
3638           setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
3639         } else if (othIsNull || othIsSymbol) {
3640           setLow = false;
3641         } else {
3642           setLow = retHighest ? (computed <= value) : (computed < value);
3643         }
3644         if (setLow) {
3645           low = mid + 1;
3646         } else {
3647           high = mid;
3648         }
3649       }
3650       return nativeMin(high, MAX_ARRAY_INDEX);
3651     }
3652
3653     /**
3654      * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
3655      * support for iteratee shorthands.
3656      *
3657      * @private
3658      * @param {Array} array The array to inspect.
3659      * @param {Function} [iteratee] The iteratee invoked per element.
3660      * @returns {Array} Returns the new duplicate free array.
3661      */
3662     function baseSortedUniq(array, iteratee) {
3663       var index = -1,
3664           length = array.length,
3665           resIndex = 0,
3666           result = [];
3667
3668       while (++index < length) {
3669         var value = array[index],
3670             computed = iteratee ? iteratee(value) : value;
3671
3672         if (!index || !eq(computed, seen)) {
3673           var seen = computed;
3674           result[resIndex++] = value === 0 ? 0 : value;
3675         }
3676       }
3677       return result;
3678     }
3679
3680     /**
3681      * The base implementation of `_.toNumber` which doesn't ensure correct
3682      * conversions of binary, hexadecimal, or octal string values.
3683      *
3684      * @private
3685      * @param {*} value The value to process.
3686      * @returns {number} Returns the number.
3687      */
3688     function baseToNumber(value) {
3689       if (typeof value == 'number') {
3690         return value;
3691       }
3692       if (isSymbol(value)) {
3693         return NAN;
3694       }
3695       return +value;
3696     }
3697
3698     /**
3699      * The base implementation of `_.toString` which doesn't convert nullish
3700      * values to empty strings.
3701      *
3702      * @private
3703      * @param {*} value The value to process.
3704      * @returns {string} Returns the string.
3705      */
3706     function baseToString(value) {
3707       // Exit early for strings to avoid a performance hit in some environments.
3708       if (typeof value == 'string') {
3709         return value;
3710       }
3711       if (isSymbol(value)) {
3712         return symbolToString ? symbolToString.call(value) : '';
3713       }
3714       var result = (value + '');
3715       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
3716     }
3717
3718     /**
3719      * The base implementation of `_.uniqBy` without support for iteratee shorthands.
3720      *
3721      * @private
3722      * @param {Array} array The array to inspect.
3723      * @param {Function} [iteratee] The iteratee invoked per element.
3724      * @param {Function} [comparator] The comparator invoked per element.
3725      * @returns {Array} Returns the new duplicate free array.
3726      */
3727     function baseUniq(array, iteratee, comparator) {
3728       var index = -1,
3729           includes = arrayIncludes,
3730           length = array.length,
3731           isCommon = true,
3732           result = [],
3733           seen = result;
3734
3735       if (comparator) {
3736         isCommon = false;
3737         includes = arrayIncludesWith;
3738       }
3739       else if (length >= LARGE_ARRAY_SIZE) {
3740         var set = iteratee ? null : createSet(array);
3741         if (set) {
3742           return setToArray(set);
3743         }
3744         isCommon = false;
3745         includes = cacheHas;
3746         seen = new SetCache;
3747       }
3748       else {
3749         seen = iteratee ? [] : result;
3750       }
3751       outer:
3752       while (++index < length) {
3753         var value = array[index],
3754             computed = iteratee ? iteratee(value) : value;
3755
3756         value = (comparator || value !== 0) ? value : 0;
3757         if (isCommon && computed === computed) {
3758           var seenIndex = seen.length;
3759           while (seenIndex--) {
3760             if (seen[seenIndex] === computed) {
3761               continue outer;
3762             }
3763           }
3764           if (iteratee) {
3765             seen.push(computed);
3766           }
3767           result.push(value);
3768         }
3769         else if (!includes(seen, computed, comparator)) {
3770           if (seen !== result) {
3771             seen.push(computed);
3772           }
3773           result.push(value);
3774         }
3775       }
3776       return result;
3777     }
3778
3779     /**
3780      * The base implementation of `_.unset`.
3781      *
3782      * @private
3783      * @param {Object} object The object to modify.
3784      * @param {Array|string} path The path of the property to unset.
3785      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
3786      */
3787     function baseUnset(object, path) {
3788       path = isKey(path, object) ? [path] : castPath(path);
3789       object = parent(object, path);
3790
3791       var key = toKey(last(path));
3792       return !(object != null && baseHas(object, key)) || delete object[key];
3793     }
3794
3795     /**
3796      * The base implementation of `_.update`.
3797      *
3798      * @private
3799      * @param {Object} object The object to query.
3800      * @param {Array|string} path The path of the property to update.
3801      * @param {Function} updater The function to produce the updated value.
3802      * @param {Function} [customizer] The function to customize path creation.
3803      * @returns {Object} Returns `object`.
3804      */
3805     function baseUpdate(object, path, updater, customizer) {
3806       return baseSet(object, path, updater(baseGet(object, path)), customizer);
3807     }
3808
3809     /**
3810      * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
3811      * without support for iteratee shorthands.
3812      *
3813      * @private
3814      * @param {Array} array The array to query.
3815      * @param {Function} predicate The function invoked per iteration.
3816      * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
3817      * @param {boolean} [fromRight] Specify iterating from right to left.
3818      * @returns {Array} Returns the slice of `array`.
3819      */
3820     function baseWhile(array, predicate, isDrop, fromRight) {
3821       var length = array.length,
3822           index = fromRight ? length : -1;
3823
3824       while ((fromRight ? index-- : ++index < length) &&
3825         predicate(array[index], index, array)) {}
3826
3827       return isDrop
3828         ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
3829         : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
3830     }
3831
3832     /**
3833      * The base implementation of `wrapperValue` which returns the result of
3834      * performing a sequence of actions on the unwrapped `value`, where each
3835      * successive action is supplied the return value of the previous.
3836      *
3837      * @private
3838      * @param {*} value The unwrapped value.
3839      * @param {Array} actions Actions to perform to resolve the unwrapped value.
3840      * @returns {*} Returns the resolved value.
3841      */
3842     function baseWrapperValue(value, actions) {
3843       var result = value;
3844       if (result instanceof LazyWrapper) {
3845         result = result.value();
3846       }
3847       return arrayReduce(actions, function(result, action) {
3848         return action.func.apply(action.thisArg, arrayPush([result], action.args));
3849       }, result);
3850     }
3851
3852     /**
3853      * The base implementation of methods like `_.xor`, without support for
3854      * iteratee shorthands, that accepts an array of arrays to inspect.
3855      *
3856      * @private
3857      * @param {Array} arrays The arrays to inspect.
3858      * @param {Function} [iteratee] The iteratee invoked per element.
3859      * @param {Function} [comparator] The comparator invoked per element.
3860      * @returns {Array} Returns the new array of values.
3861      */
3862     function baseXor(arrays, iteratee, comparator) {
3863       var index = -1,
3864           length = arrays.length;
3865
3866       while (++index < length) {
3867         var result = result
3868           ? arrayPush(
3869               baseDifference(result, arrays[index], iteratee, comparator),
3870               baseDifference(arrays[index], result, iteratee, comparator)
3871             )
3872           : arrays[index];
3873       }
3874       return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
3875     }
3876
3877     /**
3878      * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
3879      *
3880      * @private
3881      * @param {Array} props The property identifiers.
3882      * @param {Array} values The property values.
3883      * @param {Function} assignFunc The function to assign values.
3884      * @returns {Object} Returns the new object.
3885      */
3886     function baseZipObject(props, values, assignFunc) {
3887       var index = -1,
3888           length = props.length,
3889           valsLength = values.length,
3890           result = {};
3891
3892       while (++index < length) {
3893         var value = index < valsLength ? values[index] : undefined;
3894         assignFunc(result, props[index], value);
3895       }
3896       return result;
3897     }
3898
3899     /**
3900      * Casts `value` to an empty array if it's not an array like object.
3901      *
3902      * @private
3903      * @param {*} value The value to inspect.
3904      * @returns {Array|Object} Returns the cast array-like object.
3905      */
3906     function castArrayLikeObject(value) {
3907       return isArrayLikeObject(value) ? value : [];
3908     }
3909
3910     /**
3911      * Casts `value` to `identity` if it's not a function.
3912      *
3913      * @private
3914      * @param {*} value The value to inspect.
3915      * @returns {Function} Returns cast function.
3916      */
3917     function castFunction(value) {
3918       return typeof value == 'function' ? value : identity;
3919     }
3920
3921     /**
3922      * Casts `value` to a path array if it's not one.
3923      *
3924      * @private
3925      * @param {*} value The value to inspect.
3926      * @returns {Array} Returns the cast property path array.
3927      */
3928     function castPath(value) {
3929       return isArray(value) ? value : stringToPath(value);
3930     }
3931
3932     /**
3933      * Casts `array` to a slice if it's needed.
3934      *
3935      * @private
3936      * @param {Array} array The array to inspect.
3937      * @param {number} start The start position.
3938      * @param {number} [end=array.length] The end position.
3939      * @returns {Array} Returns the cast slice.
3940      */
3941     function castSlice(array, start, end) {
3942       var length = array.length;
3943       end = end === undefined ? length : end;
3944       return (!start && end >= length) ? array : baseSlice(array, start, end);
3945     }
3946
3947     /**
3948      * Creates a clone of  `buffer`.
3949      *
3950      * @private
3951      * @param {Buffer} buffer The buffer to clone.
3952      * @param {boolean} [isDeep] Specify a deep clone.
3953      * @returns {Buffer} Returns the cloned buffer.
3954      */
3955     function cloneBuffer(buffer, isDeep) {
3956       if (isDeep) {
3957         return buffer.slice();
3958       }
3959       var result = new buffer.constructor(buffer.length);
3960       buffer.copy(result);
3961       return result;
3962     }
3963
3964     /**
3965      * Creates a clone of `arrayBuffer`.
3966      *
3967      * @private
3968      * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
3969      * @returns {ArrayBuffer} Returns the cloned array buffer.
3970      */
3971     function cloneArrayBuffer(arrayBuffer) {
3972       var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
3973       new Uint8Array(result).set(new Uint8Array(arrayBuffer));
3974       return result;
3975     }
3976
3977     /**
3978      * Creates a clone of `dataView`.
3979      *
3980      * @private
3981      * @param {Object} dataView The data view to clone.
3982      * @param {boolean} [isDeep] Specify a deep clone.
3983      * @returns {Object} Returns the cloned data view.
3984      */
3985     function cloneDataView(dataView, isDeep) {
3986       var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
3987       return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
3988     }
3989
3990     /**
3991      * Creates a clone of `map`.
3992      *
3993      * @private
3994      * @param {Object} map The map to clone.
3995      * @param {Function} cloneFunc The function to clone values.
3996      * @param {boolean} [isDeep] Specify a deep clone.
3997      * @returns {Object} Returns the cloned map.
3998      */
3999     function cloneMap(map, isDeep, cloneFunc) {
4000       var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map);
4001       return arrayReduce(array, addMapEntry, new map.constructor);
4002     }
4003
4004     /**
4005      * Creates a clone of `regexp`.
4006      *
4007      * @private
4008      * @param {Object} regexp The regexp to clone.
4009      * @returns {Object} Returns the cloned regexp.
4010      */
4011     function cloneRegExp(regexp) {
4012       var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
4013       result.lastIndex = regexp.lastIndex;
4014       return result;
4015     }
4016
4017     /**
4018      * Creates a clone of `set`.
4019      *
4020      * @private
4021      * @param {Object} set The set to clone.
4022      * @param {Function} cloneFunc The function to clone values.
4023      * @param {boolean} [isDeep] Specify a deep clone.
4024      * @returns {Object} Returns the cloned set.
4025      */
4026     function cloneSet(set, isDeep, cloneFunc) {
4027       var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set);
4028       return arrayReduce(array, addSetEntry, new set.constructor);
4029     }
4030
4031     /**
4032      * Creates a clone of the `symbol` object.
4033      *
4034      * @private
4035      * @param {Object} symbol The symbol object to clone.
4036      * @returns {Object} Returns the cloned symbol object.
4037      */
4038     function cloneSymbol(symbol) {
4039       return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
4040     }
4041
4042     /**
4043      * Creates a clone of `typedArray`.
4044      *
4045      * @private
4046      * @param {Object} typedArray The typed array to clone.
4047      * @param {boolean} [isDeep] Specify a deep clone.
4048      * @returns {Object} Returns the cloned typed array.
4049      */
4050     function cloneTypedArray(typedArray, isDeep) {
4051       var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
4052       return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
4053     }
4054
4055     /**
4056      * Compares values to sort them in ascending order.
4057      *
4058      * @private
4059      * @param {*} value The value to compare.
4060      * @param {*} other The other value to compare.
4061      * @returns {number} Returns the sort order indicator for `value`.
4062      */
4063     function compareAscending(value, other) {
4064       if (value !== other) {
4065         var valIsDefined = value !== undefined,
4066             valIsNull = value === null,
4067             valIsReflexive = value === value,
4068             valIsSymbol = isSymbol(value);
4069
4070         var othIsDefined = other !== undefined,
4071             othIsNull = other === null,
4072             othIsReflexive = other === other,
4073             othIsSymbol = isSymbol(other);
4074
4075         if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
4076             (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
4077             (valIsNull && othIsDefined && othIsReflexive) ||
4078             (!valIsDefined && othIsReflexive) ||
4079             !valIsReflexive) {
4080           return 1;
4081         }
4082         if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
4083             (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
4084             (othIsNull && valIsDefined && valIsReflexive) ||
4085             (!othIsDefined && valIsReflexive) ||
4086             !othIsReflexive) {
4087           return -1;
4088         }
4089       }
4090       return 0;
4091     }
4092
4093     /**
4094      * Used by `_.orderBy` to compare multiple properties of a value to another
4095      * and stable sort them.
4096      *
4097      * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
4098      * specify an order of "desc" for descending or "asc" for ascending sort order
4099      * of corresponding values.
4100      *
4101      * @private
4102      * @param {Object} object The object to compare.
4103      * @param {Object} other The other object to compare.
4104      * @param {boolean[]|string[]} orders The order to sort by for each property.
4105      * @returns {number} Returns the sort order indicator for `object`.
4106      */
4107     function compareMultiple(object, other, orders) {
4108       var index = -1,
4109           objCriteria = object.criteria,
4110           othCriteria = other.criteria,
4111           length = objCriteria.length,
4112           ordersLength = orders.length;
4113
4114       while (++index < length) {
4115         var result = compareAscending(objCriteria[index], othCriteria[index]);
4116         if (result) {
4117           if (index >= ordersLength) {
4118             return result;
4119           }
4120           var order = orders[index];
4121           return result * (order == 'desc' ? -1 : 1);
4122         }
4123       }
4124       // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
4125       // that causes it, under certain circumstances, to provide the same value for
4126       // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
4127       // for more details.
4128       //
4129       // This also ensures a stable sort in V8 and other engines.
4130       // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
4131       return object.index - other.index;
4132     }
4133
4134     /**
4135      * Creates an array that is the composition of partially applied arguments,
4136      * placeholders, and provided arguments into a single array of arguments.
4137      *
4138      * @private
4139      * @param {Array|Object} args The provided arguments.
4140      * @param {Array} partials The arguments to prepend to those provided.
4141      * @param {Array} holders The `partials` placeholder indexes.
4142      * @params {boolean} [isCurried] Specify composing for a curried function.
4143      * @returns {Array} Returns the new array of composed arguments.
4144      */
4145     function composeArgs(args, partials, holders, isCurried) {
4146       var argsIndex = -1,
4147           argsLength = args.length,
4148           holdersLength = holders.length,
4149           leftIndex = -1,
4150           leftLength = partials.length,
4151           rangeLength = nativeMax(argsLength - holdersLength, 0),
4152           result = Array(leftLength + rangeLength),
4153           isUncurried = !isCurried;
4154
4155       while (++leftIndex < leftLength) {
4156         result[leftIndex] = partials[leftIndex];
4157       }
4158       while (++argsIndex < holdersLength) {
4159         if (isUncurried || argsIndex < argsLength) {
4160           result[holders[argsIndex]] = args[argsIndex];
4161         }
4162       }
4163       while (rangeLength--) {
4164         result[leftIndex++] = args[argsIndex++];
4165       }
4166       return result;
4167     }
4168
4169     /**
4170      * This function is like `composeArgs` except that the arguments composition
4171      * is tailored for `_.partialRight`.
4172      *
4173      * @private
4174      * @param {Array|Object} args The provided arguments.
4175      * @param {Array} partials The arguments to append to those provided.
4176      * @param {Array} holders The `partials` placeholder indexes.
4177      * @params {boolean} [isCurried] Specify composing for a curried function.
4178      * @returns {Array} Returns the new array of composed arguments.
4179      */
4180     function composeArgsRight(args, partials, holders, isCurried) {
4181       var argsIndex = -1,
4182           argsLength = args.length,
4183           holdersIndex = -1,
4184           holdersLength = holders.length,
4185           rightIndex = -1,
4186           rightLength = partials.length,
4187           rangeLength = nativeMax(argsLength - holdersLength, 0),
4188           result = Array(rangeLength + rightLength),
4189           isUncurried = !isCurried;
4190
4191       while (++argsIndex < rangeLength) {
4192         result[argsIndex] = args[argsIndex];
4193       }
4194       var offset = argsIndex;
4195       while (++rightIndex < rightLength) {
4196         result[offset + rightIndex] = partials[rightIndex];
4197       }
4198       while (++holdersIndex < holdersLength) {
4199         if (isUncurried || argsIndex < argsLength) {
4200           result[offset + holders[holdersIndex]] = args[argsIndex++];
4201         }
4202       }
4203       return result;
4204     }
4205
4206     /**
4207      * Copies the values of `source` to `array`.
4208      *
4209      * @private
4210      * @param {Array} source The array to copy values from.
4211      * @param {Array} [array=[]] The array to copy values to.
4212      * @returns {Array} Returns `array`.
4213      */
4214     function copyArray(source, array) {
4215       var index = -1,
4216           length = source.length;
4217
4218       array || (array = Array(length));
4219       while (++index < length) {
4220         array[index] = source[index];
4221       }
4222       return array;
4223     }
4224
4225     /**
4226      * Copies properties of `source` to `object`.
4227      *
4228      * @private
4229      * @param {Object} source The object to copy properties from.
4230      * @param {Array} props The property identifiers to copy.
4231      * @param {Object} [object={}] The object to copy properties to.
4232      * @param {Function} [customizer] The function to customize copied values.
4233      * @returns {Object} Returns `object`.
4234      */
4235     function copyObject(source, props, object, customizer) {
4236       object || (object = {});
4237
4238       var index = -1,
4239           length = props.length;
4240
4241       while (++index < length) {
4242         var key = props[index];
4243
4244         var newValue = customizer
4245           ? customizer(object[key], source[key], key, object, source)
4246           : source[key];
4247
4248         assignValue(object, key, newValue);
4249       }
4250       return object;
4251     }
4252
4253     /**
4254      * Copies own symbol properties of `source` to `object`.
4255      *
4256      * @private
4257      * @param {Object} source The object to copy symbols from.
4258      * @param {Object} [object={}] The object to copy symbols to.
4259      * @returns {Object} Returns `object`.
4260      */
4261     function copySymbols(source, object) {
4262       return copyObject(source, getSymbols(source), object);
4263     }
4264
4265     /**
4266      * Creates a function like `_.groupBy`.
4267      *
4268      * @private
4269      * @param {Function} setter The function to set accumulator values.
4270      * @param {Function} [initializer] The accumulator object initializer.
4271      * @returns {Function} Returns the new aggregator function.
4272      */
4273     function createAggregator(setter, initializer) {
4274       return function(collection, iteratee) {
4275         var func = isArray(collection) ? arrayAggregator : baseAggregator,
4276             accumulator = initializer ? initializer() : {};
4277
4278         return func(collection, setter, getIteratee(iteratee), accumulator);
4279       };
4280     }
4281
4282     /**
4283      * Creates a function like `_.assign`.
4284      *
4285      * @private
4286      * @param {Function} assigner The function to assign values.
4287      * @returns {Function} Returns the new assigner function.
4288      */
4289     function createAssigner(assigner) {
4290       return rest(function(object, sources) {
4291         var index = -1,
4292             length = sources.length,
4293             customizer = length > 1 ? sources[length - 1] : undefined,
4294             guard = length > 2 ? sources[2] : undefined;
4295
4296         customizer = typeof customizer == 'function'
4297           ? (length--, customizer)
4298           : undefined;
4299
4300         if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4301           customizer = length < 3 ? undefined : customizer;
4302           length = 1;
4303         }
4304         object = Object(object);
4305         while (++index < length) {
4306           var source = sources[index];
4307           if (source) {
4308             assigner(object, source, index, customizer);
4309           }
4310         }
4311         return object;
4312       });
4313     }
4314
4315     /**
4316      * Creates a `baseEach` or `baseEachRight` function.
4317      *
4318      * @private
4319      * @param {Function} eachFunc The function to iterate over a collection.
4320      * @param {boolean} [fromRight] Specify iterating from right to left.
4321      * @returns {Function} Returns the new base function.
4322      */
4323     function createBaseEach(eachFunc, fromRight) {
4324       return function(collection, iteratee) {
4325         if (collection == null) {
4326           return collection;
4327         }
4328         if (!isArrayLike(collection)) {
4329           return eachFunc(collection, iteratee);
4330         }
4331         var length = collection.length,
4332             index = fromRight ? length : -1,
4333             iterable = Object(collection);
4334
4335         while ((fromRight ? index-- : ++index < length)) {
4336           if (iteratee(iterable[index], index, iterable) === false) {
4337             break;
4338           }
4339         }
4340         return collection;
4341       };
4342     }
4343
4344     /**
4345      * Creates a base function for methods like `_.forIn` and `_.forOwn`.
4346      *
4347      * @private
4348      * @param {boolean} [fromRight] Specify iterating from right to left.
4349      * @returns {Function} Returns the new base function.
4350      */
4351     function createBaseFor(fromRight) {
4352       return function(object, iteratee, keysFunc) {
4353         var index = -1,
4354             iterable = Object(object),
4355             props = keysFunc(object),
4356             length = props.length;
4357
4358         while (length--) {
4359           var key = props[fromRight ? length : ++index];
4360           if (iteratee(iterable[key], key, iterable) === false) {
4361             break;
4362           }
4363         }
4364         return object;
4365       };
4366     }
4367
4368     /**
4369      * Creates a function that wraps `func` to invoke it with the optional `this`
4370      * binding of `thisArg`.
4371      *
4372      * @private
4373      * @param {Function} func The function to wrap.
4374      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
4375      *  for more details.
4376      * @param {*} [thisArg] The `this` binding of `func`.
4377      * @returns {Function} Returns the new wrapped function.
4378      */
4379     function createBaseWrapper(func, bitmask, thisArg) {
4380       var isBind = bitmask & BIND_FLAG,
4381           Ctor = createCtorWrapper(func);
4382
4383       function wrapper() {
4384         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4385         return fn.apply(isBind ? thisArg : this, arguments);
4386       }
4387       return wrapper;
4388     }
4389
4390     /**
4391      * Creates a function like `_.lowerFirst`.
4392      *
4393      * @private
4394      * @param {string} methodName The name of the `String` case method to use.
4395      * @returns {Function} Returns the new function.
4396      */
4397     function createCaseFirst(methodName) {
4398       return function(string) {
4399         string = toString(string);
4400
4401         var strSymbols = reHasComplexSymbol.test(string)
4402           ? stringToArray(string)
4403           : undefined;
4404
4405         var chr = strSymbols
4406           ? strSymbols[0]
4407           : string.charAt(0);
4408
4409         var trailing = strSymbols
4410           ? castSlice(strSymbols, 1).join('')
4411           : string.slice(1);
4412
4413         return chr[methodName]() + trailing;
4414       };
4415     }
4416
4417     /**
4418      * Creates a function like `_.camelCase`.
4419      *
4420      * @private
4421      * @param {Function} callback The function to combine each word.
4422      * @returns {Function} Returns the new compounder function.
4423      */
4424     function createCompounder(callback) {
4425       return function(string) {
4426         return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
4427       };
4428     }
4429
4430     /**
4431      * Creates a function that produces an instance of `Ctor` regardless of
4432      * whether it was invoked as part of a `new` expression or by `call` or `apply`.
4433      *
4434      * @private
4435      * @param {Function} Ctor The constructor to wrap.
4436      * @returns {Function} Returns the new wrapped function.
4437      */
4438     function createCtorWrapper(Ctor) {
4439       return function() {
4440         // Use a `switch` statement to work with class constructors. See
4441         // http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
4442         // for more details.
4443         var args = arguments;
4444         switch (args.length) {
4445           case 0: return new Ctor;
4446           case 1: return new Ctor(args[0]);
4447           case 2: return new Ctor(args[0], args[1]);
4448           case 3: return new Ctor(args[0], args[1], args[2]);
4449           case 4: return new Ctor(args[0], args[1], args[2], args[3]);
4450           case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
4451           case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
4452           case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
4453         }
4454         var thisBinding = baseCreate(Ctor.prototype),
4455             result = Ctor.apply(thisBinding, args);
4456
4457         // Mimic the constructor's `return` behavior.
4458         // See https://es5.github.io/#x13.2.2 for more details.
4459         return isObject(result) ? result : thisBinding;
4460       };
4461     }
4462
4463     /**
4464      * Creates a function that wraps `func` to enable currying.
4465      *
4466      * @private
4467      * @param {Function} func The function to wrap.
4468      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
4469      *  for more details.
4470      * @param {number} arity The arity of `func`.
4471      * @returns {Function} Returns the new wrapped function.
4472      */
4473     function createCurryWrapper(func, bitmask, arity) {
4474       var Ctor = createCtorWrapper(func);
4475
4476       function wrapper() {
4477         var length = arguments.length,
4478             args = Array(length),
4479             index = length,
4480             placeholder = getPlaceholder(wrapper);
4481
4482         while (index--) {
4483           args[index] = arguments[index];
4484         }
4485         var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
4486           ? []
4487           : replaceHolders(args, placeholder);
4488
4489         length -= holders.length;
4490         if (length < arity) {
4491           return createRecurryWrapper(
4492             func, bitmask, createHybridWrapper, wrapper.placeholder, undefined,
4493             args, holders, undefined, undefined, arity - length);
4494         }
4495         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4496         return apply(fn, this, args);
4497       }
4498       return wrapper;
4499     }
4500
4501     /**
4502      * Creates a `_.flow` or `_.flowRight` function.
4503      *
4504      * @private
4505      * @param {boolean} [fromRight] Specify iterating from right to left.
4506      * @returns {Function} Returns the new flow function.
4507      */
4508     function createFlow(fromRight) {
4509       return rest(function(funcs) {
4510         funcs = baseFlatten(funcs, 1);
4511
4512         var length = funcs.length,
4513             index = length,
4514             prereq = LodashWrapper.prototype.thru;
4515
4516         if (fromRight) {
4517           funcs.reverse();
4518         }
4519         while (index--) {
4520           var func = funcs[index];
4521           if (typeof func != 'function') {
4522             throw new TypeError(FUNC_ERROR_TEXT);
4523           }
4524           if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
4525             var wrapper = new LodashWrapper([], true);
4526           }
4527         }
4528         index = wrapper ? index : length;
4529         while (++index < length) {
4530           func = funcs[index];
4531
4532           var funcName = getFuncName(func),
4533               data = funcName == 'wrapper' ? getData(func) : undefined;
4534
4535           if (data && isLaziable(data[0]) &&
4536                 data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) &&
4537                 !data[4].length && data[9] == 1
4538               ) {
4539             wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
4540           } else {
4541             wrapper = (func.length == 1 && isLaziable(func))
4542               ? wrapper[funcName]()
4543               : wrapper.thru(func);
4544           }
4545         }
4546         return function() {
4547           var args = arguments,
4548               value = args[0];
4549
4550           if (wrapper && args.length == 1 &&
4551               isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
4552             return wrapper.plant(value).value();
4553           }
4554           var index = 0,
4555               result = length ? funcs[index].apply(this, args) : value;
4556
4557           while (++index < length) {
4558             result = funcs[index].call(this, result);
4559           }
4560           return result;
4561         };
4562       });
4563     }
4564
4565     /**
4566      * Creates a function that wraps `func` to invoke it with optional `this`
4567      * binding of `thisArg`, partial application, and currying.
4568      *
4569      * @private
4570      * @param {Function|string} func The function or method name to wrap.
4571      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
4572      *  for more details.
4573      * @param {*} [thisArg] The `this` binding of `func`.
4574      * @param {Array} [partials] The arguments to prepend to those provided to
4575      *  the new function.
4576      * @param {Array} [holders] The `partials` placeholder indexes.
4577      * @param {Array} [partialsRight] The arguments to append to those provided
4578      *  to the new function.
4579      * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
4580      * @param {Array} [argPos] The argument positions of the new function.
4581      * @param {number} [ary] The arity cap of `func`.
4582      * @param {number} [arity] The arity of `func`.
4583      * @returns {Function} Returns the new wrapped function.
4584      */
4585     function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
4586       var isAry = bitmask & ARY_FLAG,
4587           isBind = bitmask & BIND_FLAG,
4588           isBindKey = bitmask & BIND_KEY_FLAG,
4589           isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG),
4590           isFlip = bitmask & FLIP_FLAG,
4591           Ctor = isBindKey ? undefined : createCtorWrapper(func);
4592
4593       function wrapper() {
4594         var length = arguments.length,
4595             index = length,
4596             args = Array(length);
4597
4598         while (index--) {
4599           args[index] = arguments[index];
4600         }
4601         if (isCurried) {
4602           var placeholder = getPlaceholder(wrapper),
4603               holdersCount = countHolders(args, placeholder);
4604         }
4605         if (partials) {
4606           args = composeArgs(args, partials, holders, isCurried);
4607         }
4608         if (partialsRight) {
4609           args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
4610         }
4611         length -= holdersCount;
4612         if (isCurried && length < arity) {
4613           var newHolders = replaceHolders(args, placeholder);
4614           return createRecurryWrapper(
4615             func, bitmask, createHybridWrapper, wrapper.placeholder, thisArg,
4616             args, newHolders, argPos, ary, arity - length
4617           );
4618         }
4619         var thisBinding = isBind ? thisArg : this,
4620             fn = isBindKey ? thisBinding[func] : func;
4621
4622         length = args.length;
4623         if (argPos) {
4624           args = reorder(args, argPos);
4625         } else if (isFlip && length > 1) {
4626           args.reverse();
4627         }
4628         if (isAry && ary < length) {
4629           args.length = ary;
4630         }
4631         if (this && this !== root && this instanceof wrapper) {
4632           fn = Ctor || createCtorWrapper(fn);
4633         }
4634         return fn.apply(thisBinding, args);
4635       }
4636       return wrapper;
4637     }
4638
4639     /**
4640      * Creates a function like `_.invertBy`.
4641      *
4642      * @private
4643      * @param {Function} setter The function to set accumulator values.
4644      * @param {Function} toIteratee The function to resolve iteratees.
4645      * @returns {Function} Returns the new inverter function.
4646      */
4647     function createInverter(setter, toIteratee) {
4648       return function(object, iteratee) {
4649         return baseInverter(object, setter, toIteratee(iteratee), {});
4650       };
4651     }
4652
4653     /**
4654      * Creates a function that performs a mathematical operation on two values.
4655      *
4656      * @private
4657      * @param {Function} operator The function to perform the operation.
4658      * @returns {Function} Returns the new mathematical operation function.
4659      */
4660     function createMathOperation(operator) {
4661       return function(value, other) {
4662         var result;
4663         if (value === undefined && other === undefined) {
4664           return 0;
4665         }
4666         if (value !== undefined) {
4667           result = value;
4668         }
4669         if (other !== undefined) {
4670           if (result === undefined) {
4671             return other;
4672           }
4673           if (typeof value == 'string' || typeof other == 'string') {
4674             value = baseToString(value);
4675             other = baseToString(other);
4676           } else {
4677             value = baseToNumber(value);
4678             other = baseToNumber(other);
4679           }
4680           result = operator(value, other);
4681         }
4682         return result;
4683       };
4684     }
4685
4686     /**
4687      * Creates a function like `_.over`.
4688      *
4689      * @private
4690      * @param {Function} arrayFunc The function to iterate over iteratees.
4691      * @returns {Function} Returns the new invoker function.
4692      */
4693     function createOver(arrayFunc) {
4694       return rest(function(iteratees) {
4695         iteratees = (iteratees.length == 1 && isArray(iteratees[0]))
4696           ? arrayMap(iteratees[0], baseUnary(getIteratee()))
4697           : arrayMap(baseFlatten(iteratees, 1, isFlattenableIteratee), baseUnary(getIteratee()));
4698
4699         return rest(function(args) {
4700           var thisArg = this;
4701           return arrayFunc(iteratees, function(iteratee) {
4702             return apply(iteratee, thisArg, args);
4703           });
4704         });
4705       });
4706     }
4707
4708     /**
4709      * Creates the padding for `string` based on `length`. The `chars` string
4710      * is truncated if the number of characters exceeds `length`.
4711      *
4712      * @private
4713      * @param {number} length The padding length.
4714      * @param {string} [chars=' '] The string used as padding.
4715      * @returns {string} Returns the padding for `string`.
4716      */
4717     function createPadding(length, chars) {
4718       chars = chars === undefined ? ' ' : baseToString(chars);
4719
4720       var charsLength = chars.length;
4721       if (charsLength < 2) {
4722         return charsLength ? baseRepeat(chars, length) : chars;
4723       }
4724       var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
4725       return reHasComplexSymbol.test(chars)
4726         ? castSlice(stringToArray(result), 0, length).join('')
4727         : result.slice(0, length);
4728     }
4729
4730     /**
4731      * Creates a function that wraps `func` to invoke it with the `this` binding
4732      * of `thisArg` and `partials` prepended to the arguments it receives.
4733      *
4734      * @private
4735      * @param {Function} func The function to wrap.
4736      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
4737      *  for more details.
4738      * @param {*} thisArg The `this` binding of `func`.
4739      * @param {Array} partials The arguments to prepend to those provided to
4740      *  the new function.
4741      * @returns {Function} Returns the new wrapped function.
4742      */
4743     function createPartialWrapper(func, bitmask, thisArg, partials) {
4744       var isBind = bitmask & BIND_FLAG,
4745           Ctor = createCtorWrapper(func);
4746
4747       function wrapper() {
4748         var argsIndex = -1,
4749             argsLength = arguments.length,
4750             leftIndex = -1,
4751             leftLength = partials.length,
4752             args = Array(leftLength + argsLength),
4753             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4754
4755         while (++leftIndex < leftLength) {
4756           args[leftIndex] = partials[leftIndex];
4757         }
4758         while (argsLength--) {
4759           args[leftIndex++] = arguments[++argsIndex];
4760         }
4761         return apply(fn, isBind ? thisArg : this, args);
4762       }
4763       return wrapper;
4764     }
4765
4766     /**
4767      * Creates a `_.range` or `_.rangeRight` function.
4768      *
4769      * @private
4770      * @param {boolean} [fromRight] Specify iterating from right to left.
4771      * @returns {Function} Returns the new range function.
4772      */
4773     function createRange(fromRight) {
4774       return function(start, end, step) {
4775         if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
4776           end = step = undefined;
4777         }
4778         // Ensure the sign of `-0` is preserved.
4779         start = toNumber(start);
4780         start = start === start ? start : 0;
4781         if (end === undefined) {
4782           end = start;
4783           start = 0;
4784         } else {
4785           end = toNumber(end) || 0;
4786         }
4787         step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
4788         return baseRange(start, end, step, fromRight);
4789       };
4790     }
4791
4792     /**
4793      * Creates a function that performs a relational operation on two values.
4794      *
4795      * @private
4796      * @param {Function} operator The function to perform the operation.
4797      * @returns {Function} Returns the new relational operation function.
4798      */
4799     function createRelationalOperation(operator) {
4800       return function(value, other) {
4801         if (!(typeof value == 'string' && typeof other == 'string')) {
4802           value = toNumber(value);
4803           other = toNumber(other);
4804         }
4805         return operator(value, other);
4806       };
4807     }
4808
4809     /**
4810      * Creates a function that wraps `func` to continue currying.
4811      *
4812      * @private
4813      * @param {Function} func The function to wrap.
4814      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
4815      *  for more details.
4816      * @param {Function} wrapFunc The function to create the `func` wrapper.
4817      * @param {*} placeholder The placeholder value.
4818      * @param {*} [thisArg] The `this` binding of `func`.
4819      * @param {Array} [partials] The arguments to prepend to those provided to
4820      *  the new function.
4821      * @param {Array} [holders] The `partials` placeholder indexes.
4822      * @param {Array} [argPos] The argument positions of the new function.
4823      * @param {number} [ary] The arity cap of `func`.
4824      * @param {number} [arity] The arity of `func`.
4825      * @returns {Function} Returns the new wrapped function.
4826      */
4827     function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
4828       var isCurry = bitmask & CURRY_FLAG,
4829           newHolders = isCurry ? holders : undefined,
4830           newHoldersRight = isCurry ? undefined : holders,
4831           newPartials = isCurry ? partials : undefined,
4832           newPartialsRight = isCurry ? undefined : partials;
4833
4834       bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
4835       bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
4836
4837       if (!(bitmask & CURRY_BOUND_FLAG)) {
4838         bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
4839       }
4840       var newData = [
4841         func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
4842         newHoldersRight, argPos, ary, arity
4843       ];
4844
4845       var result = wrapFunc.apply(undefined, newData);
4846       if (isLaziable(func)) {
4847         setData(result, newData);
4848       }
4849       result.placeholder = placeholder;
4850       return result;
4851     }
4852
4853     /**
4854      * Creates a function like `_.round`.
4855      *
4856      * @private
4857      * @param {string} methodName The name of the `Math` method to use when rounding.
4858      * @returns {Function} Returns the new round function.
4859      */
4860     function createRound(methodName) {
4861       var func = Math[methodName];
4862       return function(number, precision) {
4863         number = toNumber(number);
4864         precision = toInteger(precision);
4865         if (precision) {
4866           // Shift with exponential notation to avoid floating-point issues.
4867           // See [MDN](https://mdn.io/round#Examples) for more details.
4868           var pair = (toString(number) + 'e').split('e'),
4869               value = func(pair[0] + 'e' + (+pair[1] + precision));
4870
4871           pair = (toString(value) + 'e').split('e');
4872           return +(pair[0] + 'e' + (+pair[1] - precision));
4873         }
4874         return func(number);
4875       };
4876     }
4877
4878     /**
4879      * Creates a set of `values`.
4880      *
4881      * @private
4882      * @param {Array} values The values to add to the set.
4883      * @returns {Object} Returns the new set.
4884      */
4885     var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
4886       return new Set(values);
4887     };
4888
4889     /**
4890      * Creates a function that either curries or invokes `func` with optional
4891      * `this` binding and partially applied arguments.
4892      *
4893      * @private
4894      * @param {Function|string} func The function or method name to wrap.
4895      * @param {number} bitmask The bitmask of wrapper flags.
4896      *  The bitmask may be composed of the following flags:
4897      *     1 - `_.bind`
4898      *     2 - `_.bindKey`
4899      *     4 - `_.curry` or `_.curryRight` of a bound function
4900      *     8 - `_.curry`
4901      *    16 - `_.curryRight`
4902      *    32 - `_.partial`
4903      *    64 - `_.partialRight`
4904      *   128 - `_.rearg`
4905      *   256 - `_.ary`
4906      * @param {*} [thisArg] The `this` binding of `func`.
4907      * @param {Array} [partials] The arguments to be partially applied.
4908      * @param {Array} [holders] The `partials` placeholder indexes.
4909      * @param {Array} [argPos] The argument positions of the new function.
4910      * @param {number} [ary] The arity cap of `func`.
4911      * @param {number} [arity] The arity of `func`.
4912      * @returns {Function} Returns the new wrapped function.
4913      */
4914     function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
4915       var isBindKey = bitmask & BIND_KEY_FLAG;
4916       if (!isBindKey && typeof func != 'function') {
4917         throw new TypeError(FUNC_ERROR_TEXT);
4918       }
4919       var length = partials ? partials.length : 0;
4920       if (!length) {
4921         bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
4922         partials = holders = undefined;
4923       }
4924       ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
4925       arity = arity === undefined ? arity : toInteger(arity);
4926       length -= holders ? holders.length : 0;
4927
4928       if (bitmask & PARTIAL_RIGHT_FLAG) {
4929         var partialsRight = partials,
4930             holdersRight = holders;
4931
4932         partials = holders = undefined;
4933       }
4934       var data = isBindKey ? undefined : getData(func);
4935
4936       var newData = [
4937         func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
4938         argPos, ary, arity
4939       ];
4940
4941       if (data) {
4942         mergeData(newData, data);
4943       }
4944       func = newData[0];
4945       bitmask = newData[1];
4946       thisArg = newData[2];
4947       partials = newData[3];
4948       holders = newData[4];
4949       arity = newData[9] = newData[9] == null
4950         ? (isBindKey ? 0 : func.length)
4951         : nativeMax(newData[9] - length, 0);
4952
4953       if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
4954         bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
4955       }
4956       if (!bitmask || bitmask == BIND_FLAG) {
4957         var result = createBaseWrapper(func, bitmask, thisArg);
4958       } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
4959         result = createCurryWrapper(func, bitmask, arity);
4960       } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
4961         result = createPartialWrapper(func, bitmask, thisArg, partials);
4962       } else {
4963         result = createHybridWrapper.apply(undefined, newData);
4964       }
4965       var setter = data ? baseSetData : setData;
4966       return setter(result, newData);
4967     }
4968
4969     /**
4970      * A specialized version of `baseIsEqualDeep` for arrays with support for
4971      * partial deep comparisons.
4972      *
4973      * @private
4974      * @param {Array} array The array to compare.
4975      * @param {Array} other The other array to compare.
4976      * @param {Function} equalFunc The function to determine equivalents of values.
4977      * @param {Function} customizer The function to customize comparisons.
4978      * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
4979      *  for more details.
4980      * @param {Object} stack Tracks traversed `array` and `other` objects.
4981      * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
4982      */
4983     function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
4984       var index = -1,
4985           isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4986           isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
4987           arrLength = array.length,
4988           othLength = other.length;
4989
4990       if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
4991         return false;
4992       }
4993       // Assume cyclic values are equal.
4994       var stacked = stack.get(array);
4995       if (stacked) {
4996         return stacked == other;
4997       }
4998       var result = true;
4999       stack.set(array, other);
5000
5001       // Ignore non-index properties.
5002       while (++index < arrLength) {
5003         var arrValue = array[index],
5004             othValue = other[index];
5005
5006         if (customizer) {
5007           var compared = isPartial
5008             ? customizer(othValue, arrValue, index, other, array, stack)
5009             : customizer(arrValue, othValue, index, array, other, stack);
5010         }
5011         if (compared !== undefined) {
5012           if (compared) {
5013             continue;
5014           }
5015           result = false;
5016           break;
5017         }
5018         // Recursively compare arrays (susceptible to call stack limits).
5019         if (isUnordered) {
5020           if (!arraySome(other, function(othValue) {
5021                 return arrValue === othValue ||
5022                   equalFunc(arrValue, othValue, customizer, bitmask, stack);
5023               })) {
5024             result = false;
5025             break;
5026           }
5027         } else if (!(
5028               arrValue === othValue ||
5029                 equalFunc(arrValue, othValue, customizer, bitmask, stack)
5030             )) {
5031           result = false;
5032           break;
5033         }
5034       }
5035       stack['delete'](array);
5036       return result;
5037     }
5038
5039     /**
5040      * A specialized version of `baseIsEqualDeep` for comparing objects of
5041      * the same `toStringTag`.
5042      *
5043      * **Note:** This function only supports comparing values with tags of
5044      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5045      *
5046      * @private
5047      * @param {Object} object The object to compare.
5048      * @param {Object} other The other object to compare.
5049      * @param {string} tag The `toStringTag` of the objects to compare.
5050      * @param {Function} equalFunc The function to determine equivalents of values.
5051      * @param {Function} customizer The function to customize comparisons.
5052      * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
5053      *  for more details.
5054      * @param {Object} stack Tracks traversed `object` and `other` objects.
5055      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5056      */
5057     function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) {
5058       switch (tag) {
5059         case dataViewTag:
5060           if ((object.byteLength != other.byteLength) ||
5061               (object.byteOffset != other.byteOffset)) {
5062             return false;
5063           }
5064           object = object.buffer;
5065           other = other.buffer;
5066
5067         case arrayBufferTag:
5068           if ((object.byteLength != other.byteLength) ||
5069               !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
5070             return false;
5071           }
5072           return true;
5073
5074         case boolTag:
5075         case dateTag:
5076           // Coerce dates and booleans to numbers, dates to milliseconds and
5077           // booleans to `1` or `0` treating invalid dates coerced to `NaN` as
5078           // not equal.
5079           return +object == +other;
5080
5081         case errorTag:
5082           return object.name == other.name && object.message == other.message;
5083
5084         case numberTag:
5085           // Treat `NaN` vs. `NaN` as equal.
5086           return (object != +object) ? other != +other : object == +other;
5087
5088         case regexpTag:
5089         case stringTag:
5090           // Coerce regexes to strings and treat strings, primitives and objects,
5091           // as equal. See http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype.tostring
5092           // for more details.
5093           return object == (other + '');
5094
5095         case mapTag:
5096           var convert = mapToArray;
5097
5098         case setTag:
5099           var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
5100           convert || (convert = setToArray);
5101
5102           if (object.size != other.size && !isPartial) {
5103             return false;
5104           }
5105           // Assume cyclic values are equal.
5106           var stacked = stack.get(object);
5107           if (stacked) {
5108             return stacked == other;
5109           }
5110           bitmask |= UNORDERED_COMPARE_FLAG;
5111           stack.set(object, other);
5112
5113           // Recursively compare objects (susceptible to call stack limits).
5114           return equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack);
5115
5116         case symbolTag:
5117           if (symbolValueOf) {
5118             return symbolValueOf.call(object) == symbolValueOf.call(other);
5119           }
5120       }
5121       return false;
5122     }
5123
5124     /**
5125      * A specialized version of `baseIsEqualDeep` for objects with support for
5126      * partial deep comparisons.
5127      *
5128      * @private
5129      * @param {Object} object The object to compare.
5130      * @param {Object} other The other object to compare.
5131      * @param {Function} equalFunc The function to determine equivalents of values.
5132      * @param {Function} customizer The function to customize comparisons.
5133      * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
5134      *  for more details.
5135      * @param {Object} stack Tracks traversed `object` and `other` objects.
5136      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5137      */
5138     function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
5139       var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
5140           objProps = keys(object),
5141           objLength = objProps.length,
5142           othProps = keys(other),
5143           othLength = othProps.length;
5144
5145       if (objLength != othLength && !isPartial) {
5146         return false;
5147       }
5148       var index = objLength;
5149       while (index--) {
5150         var key = objProps[index];
5151         if (!(isPartial ? key in other : baseHas(other, key))) {
5152           return false;
5153         }
5154       }
5155       // Assume cyclic values are equal.
5156       var stacked = stack.get(object);
5157       if (stacked) {
5158         return stacked == other;
5159       }
5160       var result = true;
5161       stack.set(object, other);
5162
5163       var skipCtor = isPartial;
5164       while (++index < objLength) {
5165         key = objProps[index];
5166         var objValue = object[key],
5167             othValue = other[key];
5168
5169         if (customizer) {
5170           var compared = isPartial
5171             ? customizer(othValue, objValue, key, other, object, stack)
5172             : customizer(objValue, othValue, key, object, other, stack);
5173         }
5174         // Recursively compare objects (susceptible to call stack limits).
5175         if (!(compared === undefined
5176               ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
5177               : compared
5178             )) {
5179           result = false;
5180           break;
5181         }
5182         skipCtor || (skipCtor = key == 'constructor');
5183       }
5184       if (result && !skipCtor) {
5185         var objCtor = object.constructor,
5186             othCtor = other.constructor;
5187
5188         // Non `Object` object instances with different constructors are not equal.
5189         if (objCtor != othCtor &&
5190             ('constructor' in object && 'constructor' in other) &&
5191             !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
5192               typeof othCtor == 'function' && othCtor instanceof othCtor)) {
5193           result = false;
5194         }
5195       }
5196       stack['delete'](object);
5197       return result;
5198     }
5199
5200     /**
5201      * Creates an array of own enumerable property names and symbols of `object`.
5202      *
5203      * @private
5204      * @param {Object} object The object to query.
5205      * @returns {Array} Returns the array of property names and symbols.
5206      */
5207     function getAllKeys(object) {
5208       return baseGetAllKeys(object, keys, getSymbols);
5209     }
5210
5211     /**
5212      * Creates an array of own and inherited enumerable property names and
5213      * symbols of `object`.
5214      *
5215      * @private
5216      * @param {Object} object The object to query.
5217      * @returns {Array} Returns the array of property names and symbols.
5218      */
5219     function getAllKeysIn(object) {
5220       return baseGetAllKeys(object, keysIn, getSymbolsIn);
5221     }
5222
5223     /**
5224      * Gets metadata for `func`.
5225      *
5226      * @private
5227      * @param {Function} func The function to query.
5228      * @returns {*} Returns the metadata for `func`.
5229      */
5230     var getData = !metaMap ? noop : function(func) {
5231       return metaMap.get(func);
5232     };
5233
5234     /**
5235      * Gets the name of `func`.
5236      *
5237      * @private
5238      * @param {Function} func The function to query.
5239      * @returns {string} Returns the function name.
5240      */
5241     function getFuncName(func) {
5242       var result = (func.name + ''),
5243           array = realNames[result],
5244           length = hasOwnProperty.call(realNames, result) ? array.length : 0;
5245
5246       while (length--) {
5247         var data = array[length],
5248             otherFunc = data.func;
5249         if (otherFunc == null || otherFunc == func) {
5250           return data.name;
5251         }
5252       }
5253       return result;
5254     }
5255
5256     /**
5257      * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
5258      * this function returns the custom method, otherwise it returns `baseIteratee`.
5259      * If arguments are provided, the chosen function is invoked with them and
5260      * its result is returned.
5261      *
5262      * @private
5263      * @param {*} [value] The value to convert to an iteratee.
5264      * @param {number} [arity] The arity of the created iteratee.
5265      * @returns {Function} Returns the chosen function or its result.
5266      */
5267     function getIteratee() {
5268       var result = lodash.iteratee || iteratee;
5269       result = result === iteratee ? baseIteratee : result;
5270       return arguments.length ? result(arguments[0], arguments[1]) : result;
5271     }
5272
5273     /**
5274      * Gets the "length" property value of `object`.
5275      *
5276      * **Note:** This function is used to avoid a
5277      * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects
5278      * Safari on at least iOS 8.1-8.3 ARM64.
5279      *
5280      * @private
5281      * @param {Object} object The object to query.
5282      * @returns {*} Returns the "length" value.
5283      */
5284     var getLength = baseProperty('length');
5285
5286     /**
5287      * Gets the property names, values, and compare flags of `object`.
5288      *
5289      * @private
5290      * @param {Object} object The object to query.
5291      * @returns {Array} Returns the match data of `object`.
5292      */
5293     function getMatchData(object) {
5294       var result = toPairs(object),
5295           length = result.length;
5296
5297       while (length--) {
5298         result[length][2] = isStrictComparable(result[length][1]);
5299       }
5300       return result;
5301     }
5302
5303     /**
5304      * Gets the native function at `key` of `object`.
5305      *
5306      * @private
5307      * @param {Object} object The object to query.
5308      * @param {string} key The key of the method to get.
5309      * @returns {*} Returns the function if it's native, else `undefined`.
5310      */
5311     function getNative(object, key) {
5312       var value = object[key];
5313       return isNative(value) ? value : undefined;
5314     }
5315
5316     /**
5317      * Gets the argument placeholder value for `func`.
5318      *
5319      * @private
5320      * @param {Function} func The function to inspect.
5321      * @returns {*} Returns the placeholder value.
5322      */
5323     function getPlaceholder(func) {
5324       var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
5325       return object.placeholder;
5326     }
5327
5328     /**
5329      * Gets the `[[Prototype]]` of `value`.
5330      *
5331      * @private
5332      * @param {*} value The value to query.
5333      * @returns {null|Object} Returns the `[[Prototype]]`.
5334      */
5335     function getPrototype(value) {
5336       return nativeGetPrototype(Object(value));
5337     }
5338
5339     /**
5340      * Creates an array of the own enumerable symbol properties of `object`.
5341      *
5342      * @private
5343      * @param {Object} object The object to query.
5344      * @returns {Array} Returns the array of symbols.
5345      */
5346     function getSymbols(object) {
5347       // Coerce `object` to an object to avoid non-object errors in V8.
5348       // See https://bugs.chromium.org/p/v8/issues/detail?id=3443 for more details.
5349       return getOwnPropertySymbols(Object(object));
5350     }
5351
5352     // Fallback for IE < 11.
5353     if (!getOwnPropertySymbols) {
5354       getSymbols = function() {
5355         return [];
5356       };
5357     }
5358
5359     /**
5360      * Creates an array of the own and inherited enumerable symbol properties
5361      * of `object`.
5362      *
5363      * @private
5364      * @param {Object} object The object to query.
5365      * @returns {Array} Returns the array of symbols.
5366      */
5367     var getSymbolsIn = !getOwnPropertySymbols ? getSymbols : function(object) {
5368       var result = [];
5369       while (object) {
5370         arrayPush(result, getSymbols(object));
5371         object = getPrototype(object);
5372       }
5373       return result;
5374     };
5375
5376     /**
5377      * Gets the `toStringTag` of `value`.
5378      *
5379      * @private
5380      * @param {*} value The value to query.
5381      * @returns {string} Returns the `toStringTag`.
5382      */
5383     function getTag(value) {
5384       return objectToString.call(value);
5385     }
5386
5387     // Fallback for data views, maps, sets, and weak maps in IE 11,
5388     // for data views in Edge, and promises in Node.js.
5389     if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
5390         (Map && getTag(new Map) != mapTag) ||
5391         (Promise && getTag(Promise.resolve()) != promiseTag) ||
5392         (Set && getTag(new Set) != setTag) ||
5393         (WeakMap && getTag(new WeakMap) != weakMapTag)) {
5394       getTag = function(value) {
5395         var result = objectToString.call(value),
5396             Ctor = result == objectTag ? value.constructor : undefined,
5397             ctorString = Ctor ? toSource(Ctor) : undefined;
5398
5399         if (ctorString) {
5400           switch (ctorString) {
5401             case dataViewCtorString: return dataViewTag;
5402             case mapCtorString: return mapTag;
5403             case promiseCtorString: return promiseTag;
5404             case setCtorString: return setTag;
5405             case weakMapCtorString: return weakMapTag;
5406           }
5407         }
5408         return result;
5409       };
5410     }
5411
5412     /**
5413      * Gets the view, applying any `transforms` to the `start` and `end` positions.
5414      *
5415      * @private
5416      * @param {number} start The start of the view.
5417      * @param {number} end The end of the view.
5418      * @param {Array} transforms The transformations to apply to the view.
5419      * @returns {Object} Returns an object containing the `start` and `end`
5420      *  positions of the view.
5421      */
5422     function getView(start, end, transforms) {
5423       var index = -1,
5424           length = transforms.length;
5425
5426       while (++index < length) {
5427         var data = transforms[index],
5428             size = data.size;
5429
5430         switch (data.type) {
5431           case 'drop':      start += size; break;
5432           case 'dropRight': end -= size; break;
5433           case 'take':      end = nativeMin(end, start + size); break;
5434           case 'takeRight': start = nativeMax(start, end - size); break;
5435         }
5436       }
5437       return { 'start': start, 'end': end };
5438     }
5439
5440     /**
5441      * Checks if `path` exists on `object`.
5442      *
5443      * @private
5444      * @param {Object} object The object to query.
5445      * @param {Array|string} path The path to check.
5446      * @param {Function} hasFunc The function to check properties.
5447      * @returns {boolean} Returns `true` if `path` exists, else `false`.
5448      */
5449     function hasPath(object, path, hasFunc) {
5450       path = isKey(path, object) ? [path] : castPath(path);
5451
5452       var result,
5453           index = -1,
5454           length = path.length;
5455
5456       while (++index < length) {
5457         var key = toKey(path[index]);
5458         if (!(result = object != null && hasFunc(object, key))) {
5459           break;
5460         }
5461         object = object[key];
5462       }
5463       if (result) {
5464         return result;
5465       }
5466       var length = object ? object.length : 0;
5467       return !!length && isLength(length) && isIndex(key, length) &&
5468         (isArray(object) || isString(object) || isArguments(object));
5469     }
5470
5471     /**
5472      * Initializes an array clone.
5473      *
5474      * @private
5475      * @param {Array} array The array to clone.
5476      * @returns {Array} Returns the initialized clone.
5477      */
5478     function initCloneArray(array) {
5479       var length = array.length,
5480           result = array.constructor(length);
5481
5482       // Add properties assigned by `RegExp#exec`.
5483       if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
5484         result.index = array.index;
5485         result.input = array.input;
5486       }
5487       return result;
5488     }
5489
5490     /**
5491      * Initializes an object clone.
5492      *
5493      * @private
5494      * @param {Object} object The object to clone.
5495      * @returns {Object} Returns the initialized clone.
5496      */
5497     function initCloneObject(object) {
5498       return (typeof object.constructor == 'function' && !isPrototype(object))
5499         ? baseCreate(getPrototype(object))
5500         : {};
5501     }
5502
5503     /**
5504      * Initializes an object clone based on its `toStringTag`.
5505      *
5506      * **Note:** This function only supports cloning values with tags of
5507      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5508      *
5509      * @private
5510      * @param {Object} object The object to clone.
5511      * @param {string} tag The `toStringTag` of the object to clone.
5512      * @param {Function} cloneFunc The function to clone values.
5513      * @param {boolean} [isDeep] Specify a deep clone.
5514      * @returns {Object} Returns the initialized clone.
5515      */
5516     function initCloneByTag(object, tag, cloneFunc, isDeep) {
5517       var Ctor = object.constructor;
5518       switch (tag) {
5519         case arrayBufferTag:
5520           return cloneArrayBuffer(object);
5521
5522         case boolTag:
5523         case dateTag:
5524           return new Ctor(+object);
5525
5526         case dataViewTag:
5527           return cloneDataView(object, isDeep);
5528
5529         case float32Tag: case float64Tag:
5530         case int8Tag: case int16Tag: case int32Tag:
5531         case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
5532           return cloneTypedArray(object, isDeep);
5533
5534         case mapTag:
5535           return cloneMap(object, isDeep, cloneFunc);
5536
5537         case numberTag:
5538         case stringTag:
5539           return new Ctor(object);
5540
5541         case regexpTag:
5542           return cloneRegExp(object);
5543
5544         case setTag:
5545           return cloneSet(object, isDeep, cloneFunc);
5546
5547         case symbolTag:
5548           return cloneSymbol(object);
5549       }
5550     }
5551
5552     /**
5553      * Creates an array of index keys for `object` values of arrays,
5554      * `arguments` objects, and strings, otherwise `null` is returned.
5555      *
5556      * @private
5557      * @param {Object} object The object to query.
5558      * @returns {Array|null} Returns index keys, else `null`.
5559      */
5560     function indexKeys(object) {
5561       var length = object ? object.length : undefined;
5562       if (isLength(length) &&
5563           (isArray(object) || isString(object) || isArguments(object))) {
5564         return baseTimes(length, String);
5565       }
5566       return null;
5567     }
5568
5569     /**
5570      * Checks if `value` is a flattenable `arguments` object or array.
5571      *
5572      * @private
5573      * @param {*} value The value to check.
5574      * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
5575      */
5576     function isFlattenable(value) {
5577       return isArrayLikeObject(value) && (isArray(value) || isArguments(value));
5578     }
5579
5580     /**
5581      * Checks if `value` is a flattenable array and not a `_.matchesProperty`
5582      * iteratee shorthand.
5583      *
5584      * @private
5585      * @param {*} value The value to check.
5586      * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
5587      */
5588     function isFlattenableIteratee(value) {
5589       return isArray(value) && !(value.length == 2 && !isFunction(value[0]));
5590     }
5591
5592     /**
5593      * Checks if `value` is a valid array-like index.
5594      *
5595      * @private
5596      * @param {*} value The value to check.
5597      * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
5598      * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
5599      */
5600     function isIndex(value, length) {
5601       length = length == null ? MAX_SAFE_INTEGER : length;
5602       return !!length &&
5603         (typeof value == 'number' || reIsUint.test(value)) &&
5604         (value > -1 && value % 1 == 0 && value < length);
5605     }
5606
5607     /**
5608      * Checks if the given arguments are from an iteratee call.
5609      *
5610      * @private
5611      * @param {*} value The potential iteratee value argument.
5612      * @param {*} index The potential iteratee index or key argument.
5613      * @param {*} object The potential iteratee object argument.
5614      * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
5615      *  else `false`.
5616      */
5617     function isIterateeCall(value, index, object) {
5618       if (!isObject(object)) {
5619         return false;
5620       }
5621       var type = typeof index;
5622       if (type == 'number'
5623             ? (isArrayLike(object) && isIndex(index, object.length))
5624             : (type == 'string' && index in object)
5625           ) {
5626         return eq(object[index], value);
5627       }
5628       return false;
5629     }
5630
5631     /**
5632      * Checks if `value` is a property name and not a property path.
5633      *
5634      * @private
5635      * @param {*} value The value to check.
5636      * @param {Object} [object] The object to query keys on.
5637      * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
5638      */
5639     function isKey(value, object) {
5640       if (isArray(value)) {
5641         return false;
5642       }
5643       var type = typeof value;
5644       if (type == 'number' || type == 'symbol' || type == 'boolean' ||
5645           value == null || isSymbol(value)) {
5646         return true;
5647       }
5648       return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
5649         (object != null && value in Object(object));
5650     }
5651
5652     /**
5653      * Checks if `value` is suitable for use as unique object key.
5654      *
5655      * @private
5656      * @param {*} value The value to check.
5657      * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
5658      */
5659     function isKeyable(value) {
5660       var type = typeof value;
5661       return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
5662         ? (value !== '__proto__')
5663         : (value === null);
5664     }
5665
5666     /**
5667      * Checks if `func` has a lazy counterpart.
5668      *
5669      * @private
5670      * @param {Function} func The function to check.
5671      * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
5672      *  else `false`.
5673      */
5674     function isLaziable(func) {
5675       var funcName = getFuncName(func),
5676           other = lodash[funcName];
5677
5678       if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
5679         return false;
5680       }
5681       if (func === other) {
5682         return true;
5683       }
5684       var data = getData(other);
5685       return !!data && func === data[0];
5686     }
5687
5688     /**
5689      * Checks if `value` is likely a prototype object.
5690      *
5691      * @private
5692      * @param {*} value The value to check.
5693      * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
5694      */
5695     function isPrototype(value) {
5696       var Ctor = value && value.constructor,
5697           proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
5698
5699       return value === proto;
5700     }
5701
5702     /**
5703      * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
5704      *
5705      * @private
5706      * @param {*} value The value to check.
5707      * @returns {boolean} Returns `true` if `value` if suitable for strict
5708      *  equality comparisons, else `false`.
5709      */
5710     function isStrictComparable(value) {
5711       return value === value && !isObject(value);
5712     }
5713
5714     /**
5715      * A specialized version of `matchesProperty` for source values suitable
5716      * for strict equality comparisons, i.e. `===`.
5717      *
5718      * @private
5719      * @param {string} key The key of the property to get.
5720      * @param {*} srcValue The value to match.
5721      * @returns {Function} Returns the new function.
5722      */
5723     function matchesStrictComparable(key, srcValue) {
5724       return function(object) {
5725         if (object == null) {
5726           return false;
5727         }
5728         return object[key] === srcValue &&
5729           (srcValue !== undefined || (key in Object(object)));
5730       };
5731     }
5732
5733     /**
5734      * Merges the function metadata of `source` into `data`.
5735      *
5736      * Merging metadata reduces the number of wrappers used to invoke a function.
5737      * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
5738      * may be applied regardless of execution order. Methods like `_.ary` and
5739      * `_.rearg` modify function arguments, making the order in which they are
5740      * executed important, preventing the merging of metadata. However, we make
5741      * an exception for a safe combined case where curried functions have `_.ary`
5742      * and or `_.rearg` applied.
5743      *
5744      * @private
5745      * @param {Array} data The destination metadata.
5746      * @param {Array} source The source metadata.
5747      * @returns {Array} Returns `data`.
5748      */
5749     function mergeData(data, source) {
5750       var bitmask = data[1],
5751           srcBitmask = source[1],
5752           newBitmask = bitmask | srcBitmask,
5753           isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
5754
5755       var isCombo =
5756         ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) ||
5757         ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
5758         ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
5759
5760       // Exit early if metadata can't be merged.
5761       if (!(isCommon || isCombo)) {
5762         return data;
5763       }
5764       // Use source `thisArg` if available.
5765       if (srcBitmask & BIND_FLAG) {
5766         data[2] = source[2];
5767         // Set when currying a bound function.
5768         newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG;
5769       }
5770       // Compose partial arguments.
5771       var value = source[3];
5772       if (value) {
5773         var partials = data[3];
5774         data[3] = partials ? composeArgs(partials, value, source[4]) : value;
5775         data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
5776       }
5777       // Compose partial right arguments.
5778       value = source[5];
5779       if (value) {
5780         partials = data[5];
5781         data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
5782         data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
5783       }
5784       // Use source `argPos` if available.
5785       value = source[7];
5786       if (value) {
5787         data[7] = value;
5788       }
5789       // Use source `ary` if it's smaller.
5790       if (srcBitmask & ARY_FLAG) {
5791         data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
5792       }
5793       // Use source `arity` if one is not provided.
5794       if (data[9] == null) {
5795         data[9] = source[9];
5796       }
5797       // Use source `func` and merge bitmasks.
5798       data[0] = source[0];
5799       data[1] = newBitmask;
5800
5801       return data;
5802     }
5803
5804     /**
5805      * Used by `_.defaultsDeep` to customize its `_.merge` use.
5806      *
5807      * @private
5808      * @param {*} objValue The destination value.
5809      * @param {*} srcValue The source value.
5810      * @param {string} key The key of the property to merge.
5811      * @param {Object} object The parent object of `objValue`.
5812      * @param {Object} source The parent object of `srcValue`.
5813      * @param {Object} [stack] Tracks traversed source values and their merged
5814      *  counterparts.
5815      * @returns {*} Returns the value to assign.
5816      */
5817     function mergeDefaults(objValue, srcValue, key, object, source, stack) {
5818       if (isObject(objValue) && isObject(srcValue)) {
5819         baseMerge(objValue, srcValue, undefined, mergeDefaults, stack.set(srcValue, objValue));
5820       }
5821       return objValue;
5822     }
5823
5824     /**
5825      * Gets the parent value at `path` of `object`.
5826      *
5827      * @private
5828      * @param {Object} object The object to query.
5829      * @param {Array} path The path to get the parent value of.
5830      * @returns {*} Returns the parent value.
5831      */
5832     function parent(object, path) {
5833       return path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
5834     }
5835
5836     /**
5837      * Reorder `array` according to the specified indexes where the element at
5838      * the first index is assigned as the first element, the element at
5839      * the second index is assigned as the second element, and so on.
5840      *
5841      * @private
5842      * @param {Array} array The array to reorder.
5843      * @param {Array} indexes The arranged array indexes.
5844      * @returns {Array} Returns `array`.
5845      */
5846     function reorder(array, indexes) {
5847       var arrLength = array.length,
5848           length = nativeMin(indexes.length, arrLength),
5849           oldArray = copyArray(array);
5850
5851       while (length--) {
5852         var index = indexes[length];
5853         array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
5854       }
5855       return array;
5856     }
5857
5858     /**
5859      * Sets metadata for `func`.
5860      *
5861      * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
5862      * period of time, it will trip its breaker and transition to an identity
5863      * function to avoid garbage collection pauses in V8. See
5864      * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
5865      * for more details.
5866      *
5867      * @private
5868      * @param {Function} func The function to associate metadata with.
5869      * @param {*} data The metadata.
5870      * @returns {Function} Returns `func`.
5871      */
5872     var setData = (function() {
5873       var count = 0,
5874           lastCalled = 0;
5875
5876       return function(key, value) {
5877         var stamp = now(),
5878             remaining = HOT_SPAN - (stamp - lastCalled);
5879
5880         lastCalled = stamp;
5881         if (remaining > 0) {
5882           if (++count >= HOT_COUNT) {
5883             return key;
5884           }
5885         } else {
5886           count = 0;
5887         }
5888         return baseSetData(key, value);
5889       };
5890     }());
5891
5892     /**
5893      * Converts `string` to a property path array.
5894      *
5895      * @private
5896      * @param {string} string The string to convert.
5897      * @returns {Array} Returns the property path array.
5898      */
5899     var stringToPath = memoize(function(string) {
5900       var result = [];
5901       toString(string).replace(rePropName, function(match, number, quote, string) {
5902         result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
5903       });
5904       return result;
5905     });
5906
5907     /**
5908      * Converts `value` to a string key if it's not a string or symbol.
5909      *
5910      * @private
5911      * @param {*} value The value to inspect.
5912      * @returns {string|symbol} Returns the key.
5913      */
5914     function toKey(value) {
5915       if (typeof value == 'string' || isSymbol(value)) {
5916         return value;
5917       }
5918       var result = (value + '');
5919       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
5920     }
5921
5922     /**
5923      * Converts `func` to its source code.
5924      *
5925      * @private
5926      * @param {Function} func The function to process.
5927      * @returns {string} Returns the source code.
5928      */
5929     function toSource(func) {
5930       if (func != null) {
5931         try {
5932           return funcToString.call(func);
5933         } catch (e) {}
5934         try {
5935           return (func + '');
5936         } catch (e) {}
5937       }
5938       return '';
5939     }
5940
5941     /**
5942      * Creates a clone of `wrapper`.
5943      *
5944      * @private
5945      * @param {Object} wrapper The wrapper to clone.
5946      * @returns {Object} Returns the cloned wrapper.
5947      */
5948     function wrapperClone(wrapper) {
5949       if (wrapper instanceof LazyWrapper) {
5950         return wrapper.clone();
5951       }
5952       var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
5953       result.__actions__ = copyArray(wrapper.__actions__);
5954       result.__index__  = wrapper.__index__;
5955       result.__values__ = wrapper.__values__;
5956       return result;
5957     }
5958
5959     /*------------------------------------------------------------------------*/
5960
5961     /**
5962      * Creates an array of elements split into groups the length of `size`.
5963      * If `array` can't be split evenly, the final chunk will be the remaining
5964      * elements.
5965      *
5966      * @static
5967      * @memberOf _
5968      * @since 3.0.0
5969      * @category Array
5970      * @param {Array} array The array to process.
5971      * @param {number} [size=1] The length of each chunk
5972      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
5973      * @returns {Array} Returns the new array containing chunks.
5974      * @example
5975      *
5976      * _.chunk(['a', 'b', 'c', 'd'], 2);
5977      * // => [['a', 'b'], ['c', 'd']]
5978      *
5979      * _.chunk(['a', 'b', 'c', 'd'], 3);
5980      * // => [['a', 'b', 'c'], ['d']]
5981      */
5982     function chunk(array, size, guard) {
5983       if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
5984         size = 1;
5985       } else {
5986         size = nativeMax(toInteger(size), 0);
5987       }
5988       var length = array ? array.length : 0;
5989       if (!length || size < 1) {
5990         return [];
5991       }
5992       var index = 0,
5993           resIndex = 0,
5994           result = Array(nativeCeil(length / size));
5995
5996       while (index < length) {
5997         result[resIndex++] = baseSlice(array, index, (index += size));
5998       }
5999       return result;
6000     }
6001
6002     /**
6003      * Creates an array with all falsey values removed. The values `false`, `null`,
6004      * `0`, `""`, `undefined`, and `NaN` are falsey.
6005      *
6006      * @static
6007      * @memberOf _
6008      * @since 0.1.0
6009      * @category Array
6010      * @param {Array} array The array to compact.
6011      * @returns {Array} Returns the new array of filtered values.
6012      * @example
6013      *
6014      * _.compact([0, 1, false, 2, '', 3]);
6015      * // => [1, 2, 3]
6016      */
6017     function compact(array) {
6018       var index = -1,
6019           length = array ? array.length : 0,
6020           resIndex = 0,
6021           result = [];
6022
6023       while (++index < length) {
6024         var value = array[index];
6025         if (value) {
6026           result[resIndex++] = value;
6027         }
6028       }
6029       return result;
6030     }
6031
6032     /**
6033      * Creates a new array concatenating `array` with any additional arrays
6034      * and/or values.
6035      *
6036      * @static
6037      * @memberOf _
6038      * @since 4.0.0
6039      * @category Array
6040      * @param {Array} array The array to concatenate.
6041      * @param {...*} [values] The values to concatenate.
6042      * @returns {Array} Returns the new concatenated array.
6043      * @example
6044      *
6045      * var array = [1];
6046      * var other = _.concat(array, 2, [3], [[4]]);
6047      *
6048      * console.log(other);
6049      * // => [1, 2, 3, [4]]
6050      *
6051      * console.log(array);
6052      * // => [1]
6053      */
6054     function concat() {
6055       var length = arguments.length,
6056           array = castArray(arguments[0]);
6057
6058       if (length < 2) {
6059         return length ? copyArray(array) : [];
6060       }
6061       var args = Array(length - 1);
6062       while (length--) {
6063         args[length - 1] = arguments[length];
6064       }
6065       return arrayConcat(array, baseFlatten(args, 1));
6066     }
6067
6068     /**
6069      * Creates an array of unique `array` values not included in the other given
6070      * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6071      * for equality comparisons. The order of result values is determined by the
6072      * order they occur in the first array.
6073      *
6074      * @static
6075      * @memberOf _
6076      * @since 0.1.0
6077      * @category Array
6078      * @param {Array} array The array to inspect.
6079      * @param {...Array} [values] The values to exclude.
6080      * @returns {Array} Returns the new array of filtered values.
6081      * @see _.without, _.xor
6082      * @example
6083      *
6084      * _.difference([3, 2, 1], [4, 2]);
6085      * // => [3, 1]
6086      */
6087     var difference = rest(function(array, values) {
6088       return isArrayLikeObject(array)
6089         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
6090         : [];
6091     });
6092
6093     /**
6094      * This method is like `_.difference` except that it accepts `iteratee` which
6095      * is invoked for each element of `array` and `values` to generate the criterion
6096      * by which they're compared. Result values are chosen from the first array.
6097      * The iteratee is invoked with one argument: (value).
6098      *
6099      * @static
6100      * @memberOf _
6101      * @since 4.0.0
6102      * @category Array
6103      * @param {Array} array The array to inspect.
6104      * @param {...Array} [values] The values to exclude.
6105      * @param {Array|Function|Object|string} [iteratee=_.identity]
6106      *  The iteratee invoked per element.
6107      * @returns {Array} Returns the new array of filtered values.
6108      * @example
6109      *
6110      * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
6111      * // => [3.1, 1.3]
6112      *
6113      * // The `_.property` iteratee shorthand.
6114      * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
6115      * // => [{ 'x': 2 }]
6116      */
6117     var differenceBy = rest(function(array, values) {
6118       var iteratee = last(values);
6119       if (isArrayLikeObject(iteratee)) {
6120         iteratee = undefined;
6121       }
6122       return isArrayLikeObject(array)
6123         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee))
6124         : [];
6125     });
6126
6127     /**
6128      * This method is like `_.difference` except that it accepts `comparator`
6129      * which is invoked to compare elements of `array` to `values`. Result values
6130      * are chosen from the first array. The comparator is invoked with two arguments:
6131      * (arrVal, othVal).
6132      *
6133      * @static
6134      * @memberOf _
6135      * @since 4.0.0
6136      * @category Array
6137      * @param {Array} array The array to inspect.
6138      * @param {...Array} [values] The values to exclude.
6139      * @param {Function} [comparator] The comparator invoked per element.
6140      * @returns {Array} Returns the new array of filtered values.
6141      * @example
6142      *
6143      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6144      *
6145      * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
6146      * // => [{ 'x': 2, 'y': 1 }]
6147      */
6148     var differenceWith = rest(function(array, values) {
6149       var comparator = last(values);
6150       if (isArrayLikeObject(comparator)) {
6151         comparator = undefined;
6152       }
6153       return isArrayLikeObject(array)
6154         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
6155         : [];
6156     });
6157
6158     /**
6159      * Creates a slice of `array` with `n` elements dropped from the beginning.
6160      *
6161      * @static
6162      * @memberOf _
6163      * @since 0.5.0
6164      * @category Array
6165      * @param {Array} array The array to query.
6166      * @param {number} [n=1] The number of elements to drop.
6167      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
6168      * @returns {Array} Returns the slice of `array`.
6169      * @example
6170      *
6171      * _.drop([1, 2, 3]);
6172      * // => [2, 3]
6173      *
6174      * _.drop([1, 2, 3], 2);
6175      * // => [3]
6176      *
6177      * _.drop([1, 2, 3], 5);
6178      * // => []
6179      *
6180      * _.drop([1, 2, 3], 0);
6181      * // => [1, 2, 3]
6182      */
6183     function drop(array, n, guard) {
6184       var length = array ? array.length : 0;
6185       if (!length) {
6186         return [];
6187       }
6188       n = (guard || n === undefined) ? 1 : toInteger(n);
6189       return baseSlice(array, n < 0 ? 0 : n, length);
6190     }
6191
6192     /**
6193      * Creates a slice of `array` with `n` elements dropped from the end.
6194      *
6195      * @static
6196      * @memberOf _
6197      * @since 3.0.0
6198      * @category Array
6199      * @param {Array} array The array to query.
6200      * @param {number} [n=1] The number of elements to drop.
6201      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
6202      * @returns {Array} Returns the slice of `array`.
6203      * @example
6204      *
6205      * _.dropRight([1, 2, 3]);
6206      * // => [1, 2]
6207      *
6208      * _.dropRight([1, 2, 3], 2);
6209      * // => [1]
6210      *
6211      * _.dropRight([1, 2, 3], 5);
6212      * // => []
6213      *
6214      * _.dropRight([1, 2, 3], 0);
6215      * // => [1, 2, 3]
6216      */
6217     function dropRight(array, n, guard) {
6218       var length = array ? array.length : 0;
6219       if (!length) {
6220         return [];
6221       }
6222       n = (guard || n === undefined) ? 1 : toInteger(n);
6223       n = length - n;
6224       return baseSlice(array, 0, n < 0 ? 0 : n);
6225     }
6226
6227     /**
6228      * Creates a slice of `array` excluding elements dropped from the end.
6229      * Elements are dropped until `predicate` returns falsey. The predicate is
6230      * invoked with three arguments: (value, index, array).
6231      *
6232      * @static
6233      * @memberOf _
6234      * @since 3.0.0
6235      * @category Array
6236      * @param {Array} array The array to query.
6237      * @param {Array|Function|Object|string} [predicate=_.identity]
6238      *  The function invoked per iteration.
6239      * @returns {Array} Returns the slice of `array`.
6240      * @example
6241      *
6242      * var users = [
6243      *   { 'user': 'barney',  'active': true },
6244      *   { 'user': 'fred',    'active': false },
6245      *   { 'user': 'pebbles', 'active': false }
6246      * ];
6247      *
6248      * _.dropRightWhile(users, function(o) { return !o.active; });
6249      * // => objects for ['barney']
6250      *
6251      * // The `_.matches` iteratee shorthand.
6252      * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
6253      * // => objects for ['barney', 'fred']
6254      *
6255      * // The `_.matchesProperty` iteratee shorthand.
6256      * _.dropRightWhile(users, ['active', false]);
6257      * // => objects for ['barney']
6258      *
6259      * // The `_.property` iteratee shorthand.
6260      * _.dropRightWhile(users, 'active');
6261      * // => objects for ['barney', 'fred', 'pebbles']
6262      */
6263     function dropRightWhile(array, predicate) {
6264       return (array && array.length)
6265         ? baseWhile(array, getIteratee(predicate, 3), true, true)
6266         : [];
6267     }
6268
6269     /**
6270      * Creates a slice of `array` excluding elements dropped from the beginning.
6271      * Elements are dropped until `predicate` returns falsey. The predicate is
6272      * invoked with three arguments: (value, index, array).
6273      *
6274      * @static
6275      * @memberOf _
6276      * @since 3.0.0
6277      * @category Array
6278      * @param {Array} array The array to query.
6279      * @param {Array|Function|Object|string} [predicate=_.identity]
6280      *  The function invoked per iteration.
6281      * @returns {Array} Returns the slice of `array`.
6282      * @example
6283      *
6284      * var users = [
6285      *   { 'user': 'barney',  'active': false },
6286      *   { 'user': 'fred',    'active': false },
6287      *   { 'user': 'pebbles', 'active': true }
6288      * ];
6289      *
6290      * _.dropWhile(users, function(o) { return !o.active; });
6291      * // => objects for ['pebbles']
6292      *
6293      * // The `_.matches` iteratee shorthand.
6294      * _.dropWhile(users, { 'user': 'barney', 'active': false });
6295      * // => objects for ['fred', 'pebbles']
6296      *
6297      * // The `_.matchesProperty` iteratee shorthand.
6298      * _.dropWhile(users, ['active', false]);
6299      * // => objects for ['pebbles']
6300      *
6301      * // The `_.property` iteratee shorthand.
6302      * _.dropWhile(users, 'active');
6303      * // => objects for ['barney', 'fred', 'pebbles']
6304      */
6305     function dropWhile(array, predicate) {
6306       return (array && array.length)
6307         ? baseWhile(array, getIteratee(predicate, 3), true)
6308         : [];
6309     }
6310
6311     /**
6312      * Fills elements of `array` with `value` from `start` up to, but not
6313      * including, `end`.
6314      *
6315      * **Note:** This method mutates `array`.
6316      *
6317      * @static
6318      * @memberOf _
6319      * @since 3.2.0
6320      * @category Array
6321      * @param {Array} array The array to fill.
6322      * @param {*} value The value to fill `array` with.
6323      * @param {number} [start=0] The start position.
6324      * @param {number} [end=array.length] The end position.
6325      * @returns {Array} Returns `array`.
6326      * @example
6327      *
6328      * var array = [1, 2, 3];
6329      *
6330      * _.fill(array, 'a');
6331      * console.log(array);
6332      * // => ['a', 'a', 'a']
6333      *
6334      * _.fill(Array(3), 2);
6335      * // => [2, 2, 2]
6336      *
6337      * _.fill([4, 6, 8, 10], '*', 1, 3);
6338      * // => [4, '*', '*', 10]
6339      */
6340     function fill(array, value, start, end) {
6341       var length = array ? array.length : 0;
6342       if (!length) {
6343         return [];
6344       }
6345       if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
6346         start = 0;
6347         end = length;
6348       }
6349       return baseFill(array, value, start, end);
6350     }
6351
6352     /**
6353      * This method is like `_.find` except that it returns the index of the first
6354      * element `predicate` returns truthy for instead of the element itself.
6355      *
6356      * @static
6357      * @memberOf _
6358      * @since 1.1.0
6359      * @category Array
6360      * @param {Array} array The array to search.
6361      * @param {Array|Function|Object|string} [predicate=_.identity]
6362      *  The function invoked per iteration.
6363      * @returns {number} Returns the index of the found element, else `-1`.
6364      * @example
6365      *
6366      * var users = [
6367      *   { 'user': 'barney',  'active': false },
6368      *   { 'user': 'fred',    'active': false },
6369      *   { 'user': 'pebbles', 'active': true }
6370      * ];
6371      *
6372      * _.findIndex(users, function(o) { return o.user == 'barney'; });
6373      * // => 0
6374      *
6375      * // The `_.matches` iteratee shorthand.
6376      * _.findIndex(users, { 'user': 'fred', 'active': false });
6377      * // => 1
6378      *
6379      * // The `_.matchesProperty` iteratee shorthand.
6380      * _.findIndex(users, ['active', false]);
6381      * // => 0
6382      *
6383      * // The `_.property` iteratee shorthand.
6384      * _.findIndex(users, 'active');
6385      * // => 2
6386      */
6387     function findIndex(array, predicate) {
6388       return (array && array.length)
6389         ? baseFindIndex(array, getIteratee(predicate, 3))
6390         : -1;
6391     }
6392
6393     /**
6394      * This method is like `_.findIndex` except that it iterates over elements
6395      * of `collection` from right to left.
6396      *
6397      * @static
6398      * @memberOf _
6399      * @since 2.0.0
6400      * @category Array
6401      * @param {Array} array The array to search.
6402      * @param {Array|Function|Object|string} [predicate=_.identity]
6403      *  The function invoked per iteration.
6404      * @returns {number} Returns the index of the found element, else `-1`.
6405      * @example
6406      *
6407      * var users = [
6408      *   { 'user': 'barney',  'active': true },
6409      *   { 'user': 'fred',    'active': false },
6410      *   { 'user': 'pebbles', 'active': false }
6411      * ];
6412      *
6413      * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
6414      * // => 2
6415      *
6416      * // The `_.matches` iteratee shorthand.
6417      * _.findLastIndex(users, { 'user': 'barney', 'active': true });
6418      * // => 0
6419      *
6420      * // The `_.matchesProperty` iteratee shorthand.
6421      * _.findLastIndex(users, ['active', false]);
6422      * // => 2
6423      *
6424      * // The `_.property` iteratee shorthand.
6425      * _.findLastIndex(users, 'active');
6426      * // => 0
6427      */
6428     function findLastIndex(array, predicate) {
6429       return (array && array.length)
6430         ? baseFindIndex(array, getIteratee(predicate, 3), true)
6431         : -1;
6432     }
6433
6434     /**
6435      * Flattens `array` a single level deep.
6436      *
6437      * @static
6438      * @memberOf _
6439      * @since 0.1.0
6440      * @category Array
6441      * @param {Array} array The array to flatten.
6442      * @returns {Array} Returns the new flattened array.
6443      * @example
6444      *
6445      * _.flatten([1, [2, [3, [4]], 5]]);
6446      * // => [1, 2, [3, [4]], 5]
6447      */
6448     function flatten(array) {
6449       var length = array ? array.length : 0;
6450       return length ? baseFlatten(array, 1) : [];
6451     }
6452
6453     /**
6454      * Recursively flattens `array`.
6455      *
6456      * @static
6457      * @memberOf _
6458      * @since 3.0.0
6459      * @category Array
6460      * @param {Array} array The array to flatten.
6461      * @returns {Array} Returns the new flattened array.
6462      * @example
6463      *
6464      * _.flattenDeep([1, [2, [3, [4]], 5]]);
6465      * // => [1, 2, 3, 4, 5]
6466      */
6467     function flattenDeep(array) {
6468       var length = array ? array.length : 0;
6469       return length ? baseFlatten(array, INFINITY) : [];
6470     }
6471
6472     /**
6473      * Recursively flatten `array` up to `depth` times.
6474      *
6475      * @static
6476      * @memberOf _
6477      * @since 4.4.0
6478      * @category Array
6479      * @param {Array} array The array to flatten.
6480      * @param {number} [depth=1] The maximum recursion depth.
6481      * @returns {Array} Returns the new flattened array.
6482      * @example
6483      *
6484      * var array = [1, [2, [3, [4]], 5]];
6485      *
6486      * _.flattenDepth(array, 1);
6487      * // => [1, 2, [3, [4]], 5]
6488      *
6489      * _.flattenDepth(array, 2);
6490      * // => [1, 2, 3, [4], 5]
6491      */
6492     function flattenDepth(array, depth) {
6493       var length = array ? array.length : 0;
6494       if (!length) {
6495         return [];
6496       }
6497       depth = depth === undefined ? 1 : toInteger(depth);
6498       return baseFlatten(array, depth);
6499     }
6500
6501     /**
6502      * The inverse of `_.toPairs`; this method returns an object composed
6503      * from key-value `pairs`.
6504      *
6505      * @static
6506      * @memberOf _
6507      * @since 4.0.0
6508      * @category Array
6509      * @param {Array} pairs The key-value pairs.
6510      * @returns {Object} Returns the new object.
6511      * @example
6512      *
6513      * _.fromPairs([['fred', 30], ['barney', 40]]);
6514      * // => { 'fred': 30, 'barney': 40 }
6515      */
6516     function fromPairs(pairs) {
6517       var index = -1,
6518           length = pairs ? pairs.length : 0,
6519           result = {};
6520
6521       while (++index < length) {
6522         var pair = pairs[index];
6523         result[pair[0]] = pair[1];
6524       }
6525       return result;
6526     }
6527
6528     /**
6529      * Gets the first element of `array`.
6530      *
6531      * @static
6532      * @memberOf _
6533      * @since 0.1.0
6534      * @alias first
6535      * @category Array
6536      * @param {Array} array The array to query.
6537      * @returns {*} Returns the first element of `array`.
6538      * @example
6539      *
6540      * _.head([1, 2, 3]);
6541      * // => 1
6542      *
6543      * _.head([]);
6544      * // => undefined
6545      */
6546     function head(array) {
6547       return (array && array.length) ? array[0] : undefined;
6548     }
6549
6550     /**
6551      * Gets the index at which the first occurrence of `value` is found in `array`
6552      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6553      * for equality comparisons. If `fromIndex` is negative, it's used as the
6554      * offset from the end of `array`.
6555      *
6556      * @static
6557      * @memberOf _
6558      * @since 0.1.0
6559      * @category Array
6560      * @param {Array} array The array to search.
6561      * @param {*} value The value to search for.
6562      * @param {number} [fromIndex=0] The index to search from.
6563      * @returns {number} Returns the index of the matched value, else `-1`.
6564      * @example
6565      *
6566      * _.indexOf([1, 2, 1, 2], 2);
6567      * // => 1
6568      *
6569      * // Search from the `fromIndex`.
6570      * _.indexOf([1, 2, 1, 2], 2, 2);
6571      * // => 3
6572      */
6573     function indexOf(array, value, fromIndex) {
6574       var length = array ? array.length : 0;
6575       if (!length) {
6576         return -1;
6577       }
6578       fromIndex = toInteger(fromIndex);
6579       if (fromIndex < 0) {
6580         fromIndex = nativeMax(length + fromIndex, 0);
6581       }
6582       return baseIndexOf(array, value, fromIndex);
6583     }
6584
6585     /**
6586      * Gets all but the last element of `array`.
6587      *
6588      * @static
6589      * @memberOf _
6590      * @since 0.1.0
6591      * @category Array
6592      * @param {Array} array The array to query.
6593      * @returns {Array} Returns the slice of `array`.
6594      * @example
6595      *
6596      * _.initial([1, 2, 3]);
6597      * // => [1, 2]
6598      */
6599     function initial(array) {
6600       return dropRight(array, 1);
6601     }
6602
6603     /**
6604      * Creates an array of unique values that are included in all given arrays
6605      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6606      * for equality comparisons. The order of result values is determined by the
6607      * order they occur in the first array.
6608      *
6609      * @static
6610      * @memberOf _
6611      * @since 0.1.0
6612      * @category Array
6613      * @param {...Array} [arrays] The arrays to inspect.
6614      * @returns {Array} Returns the new array of intersecting values.
6615      * @example
6616      *
6617      * _.intersection([2, 1], [4, 2], [1, 2]);
6618      * // => [2]
6619      */
6620     var intersection = rest(function(arrays) {
6621       var mapped = arrayMap(arrays, castArrayLikeObject);
6622       return (mapped.length && mapped[0] === arrays[0])
6623         ? baseIntersection(mapped)
6624         : [];
6625     });
6626
6627     /**
6628      * This method is like `_.intersection` except that it accepts `iteratee`
6629      * which is invoked for each element of each `arrays` to generate the criterion
6630      * by which they're compared. Result values are chosen from the first array.
6631      * The iteratee is invoked with one argument: (value).
6632      *
6633      * @static
6634      * @memberOf _
6635      * @since 4.0.0
6636      * @category Array
6637      * @param {...Array} [arrays] The arrays to inspect.
6638      * @param {Array|Function|Object|string} [iteratee=_.identity]
6639      *  The iteratee invoked per element.
6640      * @returns {Array} Returns the new array of intersecting values.
6641      * @example
6642      *
6643      * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6644      * // => [2.1]
6645      *
6646      * // The `_.property` iteratee shorthand.
6647      * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6648      * // => [{ 'x': 1 }]
6649      */
6650     var intersectionBy = rest(function(arrays) {
6651       var iteratee = last(arrays),
6652           mapped = arrayMap(arrays, castArrayLikeObject);
6653
6654       if (iteratee === last(mapped)) {
6655         iteratee = undefined;
6656       } else {
6657         mapped.pop();
6658       }
6659       return (mapped.length && mapped[0] === arrays[0])
6660         ? baseIntersection(mapped, getIteratee(iteratee))
6661         : [];
6662     });
6663
6664     /**
6665      * This method is like `_.intersection` except that it accepts `comparator`
6666      * which is invoked to compare elements of `arrays`. Result values are chosen
6667      * from the first array. The comparator is invoked with two arguments:
6668      * (arrVal, othVal).
6669      *
6670      * @static
6671      * @memberOf _
6672      * @since 4.0.0
6673      * @category Array
6674      * @param {...Array} [arrays] The arrays to inspect.
6675      * @param {Function} [comparator] The comparator invoked per element.
6676      * @returns {Array} Returns the new array of intersecting values.
6677      * @example
6678      *
6679      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6680      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6681      *
6682      * _.intersectionWith(objects, others, _.isEqual);
6683      * // => [{ 'x': 1, 'y': 2 }]
6684      */
6685     var intersectionWith = rest(function(arrays) {
6686       var comparator = last(arrays),
6687           mapped = arrayMap(arrays, castArrayLikeObject);
6688
6689       if (comparator === last(mapped)) {
6690         comparator = undefined;
6691       } else {
6692         mapped.pop();
6693       }
6694       return (mapped.length && mapped[0] === arrays[0])
6695         ? baseIntersection(mapped, undefined, comparator)
6696         : [];
6697     });
6698
6699     /**
6700      * Converts all elements in `array` into a string separated by `separator`.
6701      *
6702      * @static
6703      * @memberOf _
6704      * @since 4.0.0
6705      * @category Array
6706      * @param {Array} array The array to convert.
6707      * @param {string} [separator=','] The element separator.
6708      * @returns {string} Returns the joined string.
6709      * @example
6710      *
6711      * _.join(['a', 'b', 'c'], '~');
6712      * // => 'a~b~c'
6713      */
6714     function join(array, separator) {
6715       return array ? nativeJoin.call(array, separator) : '';
6716     }
6717
6718     /**
6719      * Gets the last element of `array`.
6720      *
6721      * @static
6722      * @memberOf _
6723      * @since 0.1.0
6724      * @category Array
6725      * @param {Array} array The array to query.
6726      * @returns {*} Returns the last element of `array`.
6727      * @example
6728      *
6729      * _.last([1, 2, 3]);
6730      * // => 3
6731      */
6732     function last(array) {
6733       var length = array ? array.length : 0;
6734       return length ? array[length - 1] : undefined;
6735     }
6736
6737     /**
6738      * This method is like `_.indexOf` except that it iterates over elements of
6739      * `array` from right to left.
6740      *
6741      * @static
6742      * @memberOf _
6743      * @since 0.1.0
6744      * @category Array
6745      * @param {Array} array The array to search.
6746      * @param {*} value The value to search for.
6747      * @param {number} [fromIndex=array.length-1] The index to search from.
6748      * @returns {number} Returns the index of the matched value, else `-1`.
6749      * @example
6750      *
6751      * _.lastIndexOf([1, 2, 1, 2], 2);
6752      * // => 3
6753      *
6754      * // Search from the `fromIndex`.
6755      * _.lastIndexOf([1, 2, 1, 2], 2, 2);
6756      * // => 1
6757      */
6758     function lastIndexOf(array, value, fromIndex) {
6759       var length = array ? array.length : 0;
6760       if (!length) {
6761         return -1;
6762       }
6763       var index = length;
6764       if (fromIndex !== undefined) {
6765         index = toInteger(fromIndex);
6766         index = (
6767           index < 0
6768             ? nativeMax(length + index, 0)
6769             : nativeMin(index, length - 1)
6770         ) + 1;
6771       }
6772       if (value !== value) {
6773         return indexOfNaN(array, index, true);
6774       }
6775       while (index--) {
6776         if (array[index] === value) {
6777           return index;
6778         }
6779       }
6780       return -1;
6781     }
6782
6783     /**
6784      * Gets the nth element of `array`. If `n` is negative, the nth element
6785      * from the end is returned.
6786      *
6787      * @static
6788      * @memberOf _
6789      * @since 4.11.0
6790      * @category Array
6791      * @param {Array} array The array to query.
6792      * @param {number} [n=0] The index of the element to return.
6793      * @returns {*} Returns the nth element of `array`.
6794      * @example
6795      *
6796      * var array = ['a', 'b', 'c', 'd'];
6797      *
6798      * _.nth(array, 1);
6799      * // => 'b'
6800      *
6801      * _.nth(array, -2);
6802      * // => 'c';
6803      */
6804     function nth(array, n) {
6805       return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
6806     }
6807
6808     /**
6809      * Removes all given values from `array` using
6810      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6811      * for equality comparisons.
6812      *
6813      * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
6814      * to remove elements from an array by predicate.
6815      *
6816      * @static
6817      * @memberOf _
6818      * @since 2.0.0
6819      * @category Array
6820      * @param {Array} array The array to modify.
6821      * @param {...*} [values] The values to remove.
6822      * @returns {Array} Returns `array`.
6823      * @example
6824      *
6825      * var array = [1, 2, 3, 1, 2, 3];
6826      *
6827      * _.pull(array, 2, 3);
6828      * console.log(array);
6829      * // => [1, 1]
6830      */
6831     var pull = rest(pullAll);
6832
6833     /**
6834      * This method is like `_.pull` except that it accepts an array of values to remove.
6835      *
6836      * **Note:** Unlike `_.difference`, this method mutates `array`.
6837      *
6838      * @static
6839      * @memberOf _
6840      * @since 4.0.0
6841      * @category Array
6842      * @param {Array} array The array to modify.
6843      * @param {Array} values The values to remove.
6844      * @returns {Array} Returns `array`.
6845      * @example
6846      *
6847      * var array = [1, 2, 3, 1, 2, 3];
6848      *
6849      * _.pullAll(array, [2, 3]);
6850      * console.log(array);
6851      * // => [1, 1]
6852      */
6853     function pullAll(array, values) {
6854       return (array && array.length && values && values.length)
6855         ? basePullAll(array, values)
6856         : array;
6857     }
6858
6859     /**
6860      * This method is like `_.pullAll` except that it accepts `iteratee` which is
6861      * invoked for each element of `array` and `values` to generate the criterion
6862      * by which they're compared. The iteratee is invoked with one argument: (value).
6863      *
6864      * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
6865      *
6866      * @static
6867      * @memberOf _
6868      * @since 4.0.0
6869      * @category Array
6870      * @param {Array} array The array to modify.
6871      * @param {Array} values The values to remove.
6872      * @param {Array|Function|Object|string} [iteratee=_.identity]
6873      *  The iteratee invoked per element.
6874      * @returns {Array} Returns `array`.
6875      * @example
6876      *
6877      * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
6878      *
6879      * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
6880      * console.log(array);
6881      * // => [{ 'x': 2 }]
6882      */
6883     function pullAllBy(array, values, iteratee) {
6884       return (array && array.length && values && values.length)
6885         ? basePullAll(array, values, getIteratee(iteratee))
6886         : array;
6887     }
6888
6889     /**
6890      * This method is like `_.pullAll` except that it accepts `comparator` which
6891      * is invoked to compare elements of `array` to `values`. The comparator is
6892      * invoked with two arguments: (arrVal, othVal).
6893      *
6894      * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
6895      *
6896      * @static
6897      * @memberOf _
6898      * @since 4.6.0
6899      * @category Array
6900      * @param {Array} array The array to modify.
6901      * @param {Array} values The values to remove.
6902      * @param {Function} [comparator] The comparator invoked per element.
6903      * @returns {Array} Returns `array`.
6904      * @example
6905      *
6906      * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
6907      *
6908      * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
6909      * console.log(array);
6910      * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
6911      */
6912     function pullAllWith(array, values, comparator) {
6913       return (array && array.length && values && values.length)
6914         ? basePullAll(array, values, undefined, comparator)
6915         : array;
6916     }
6917
6918     /**
6919      * Removes elements from `array` corresponding to `indexes` and returns an
6920      * array of removed elements.
6921      *
6922      * **Note:** Unlike `_.at`, this method mutates `array`.
6923      *
6924      * @static
6925      * @memberOf _
6926      * @since 3.0.0
6927      * @category Array
6928      * @param {Array} array The array to modify.
6929      * @param {...(number|number[])} [indexes] The indexes of elements to remove.
6930      * @returns {Array} Returns the new array of removed elements.
6931      * @example
6932      *
6933      * var array = [5, 10, 15, 20];
6934      * var evens = _.pullAt(array, 1, 3);
6935      *
6936      * console.log(array);
6937      * // => [5, 15]
6938      *
6939      * console.log(evens);
6940      * // => [10, 20]
6941      */
6942     var pullAt = rest(function(array, indexes) {
6943       indexes = baseFlatten(indexes, 1);
6944
6945       var length = array ? array.length : 0,
6946           result = baseAt(array, indexes);
6947
6948       basePullAt(array, arrayMap(indexes, function(index) {
6949         return isIndex(index, length) ? +index : index;
6950       }).sort(compareAscending));
6951
6952       return result;
6953     });
6954
6955     /**
6956      * Removes all elements from `array` that `predicate` returns truthy for
6957      * and returns an array of the removed elements. The predicate is invoked
6958      * with three arguments: (value, index, array).
6959      *
6960      * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
6961      * to pull elements from an array by value.
6962      *
6963      * @static
6964      * @memberOf _
6965      * @since 2.0.0
6966      * @category Array
6967      * @param {Array} array The array to modify.
6968      * @param {Array|Function|Object|string} [predicate=_.identity]
6969      *  The function invoked per iteration.
6970      * @returns {Array} Returns the new array of removed elements.
6971      * @example
6972      *
6973      * var array = [1, 2, 3, 4];
6974      * var evens = _.remove(array, function(n) {
6975      *   return n % 2 == 0;
6976      * });
6977      *
6978      * console.log(array);
6979      * // => [1, 3]
6980      *
6981      * console.log(evens);
6982      * // => [2, 4]
6983      */
6984     function remove(array, predicate) {
6985       var result = [];
6986       if (!(array && array.length)) {
6987         return result;
6988       }
6989       var index = -1,
6990           indexes = [],
6991           length = array.length;
6992
6993       predicate = getIteratee(predicate, 3);
6994       while (++index < length) {
6995         var value = array[index];
6996         if (predicate(value, index, array)) {
6997           result.push(value);
6998           indexes.push(index);
6999         }
7000       }
7001       basePullAt(array, indexes);
7002       return result;
7003     }
7004
7005     /**
7006      * Reverses `array` so that the first element becomes the last, the second
7007      * element becomes the second to last, and so on.
7008      *
7009      * **Note:** This method mutates `array` and is based on
7010      * [`Array#reverse`](https://mdn.io/Array/reverse).
7011      *
7012      * @static
7013      * @memberOf _
7014      * @since 4.0.0
7015      * @category Array
7016      * @param {Array} array The array to modify.
7017      * @returns {Array} Returns `array`.
7018      * @example
7019      *
7020      * var array = [1, 2, 3];
7021      *
7022      * _.reverse(array);
7023      * // => [3, 2, 1]
7024      *
7025      * console.log(array);
7026      * // => [3, 2, 1]
7027      */
7028     function reverse(array) {
7029       return array ? nativeReverse.call(array) : array;
7030     }
7031
7032     /**
7033      * Creates a slice of `array` from `start` up to, but not including, `end`.
7034      *
7035      * **Note:** This method is used instead of
7036      * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
7037      * returned.
7038      *
7039      * @static
7040      * @memberOf _
7041      * @since 3.0.0
7042      * @category Array
7043      * @param {Array} array The array to slice.
7044      * @param {number} [start=0] The start position.
7045      * @param {number} [end=array.length] The end position.
7046      * @returns {Array} Returns the slice of `array`.
7047      */
7048     function slice(array, start, end) {
7049       var length = array ? array.length : 0;
7050       if (!length) {
7051         return [];
7052       }
7053       if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
7054         start = 0;
7055         end = length;
7056       }
7057       else {
7058         start = start == null ? 0 : toInteger(start);
7059         end = end === undefined ? length : toInteger(end);
7060       }
7061       return baseSlice(array, start, end);
7062     }
7063
7064     /**
7065      * Uses a binary search to determine the lowest index at which `value`
7066      * should be inserted into `array` in order to maintain its sort order.
7067      *
7068      * @static
7069      * @memberOf _
7070      * @since 0.1.0
7071      * @category Array
7072      * @param {Array} array The sorted array to inspect.
7073      * @param {*} value The value to evaluate.
7074      * @returns {number} Returns the index at which `value` should be inserted
7075      *  into `array`.
7076      * @example
7077      *
7078      * _.sortedIndex([30, 50], 40);
7079      * // => 1
7080      *
7081      * _.sortedIndex([4, 5], 4);
7082      * // => 0
7083      */
7084     function sortedIndex(array, value) {
7085       return baseSortedIndex(array, value);
7086     }
7087
7088     /**
7089      * This method is like `_.sortedIndex` except that it accepts `iteratee`
7090      * which is invoked for `value` and each element of `array` to compute their
7091      * sort ranking. The iteratee is invoked with one argument: (value).
7092      *
7093      * @static
7094      * @memberOf _
7095      * @since 4.0.0
7096      * @category Array
7097      * @param {Array} array The sorted array to inspect.
7098      * @param {*} value The value to evaluate.
7099      * @param {Array|Function|Object|string} [iteratee=_.identity]
7100      *  The iteratee invoked per element.
7101      * @returns {number} Returns the index at which `value` should be inserted
7102      *  into `array`.
7103      * @example
7104      *
7105      * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
7106      *
7107      * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
7108      * // => 1
7109      *
7110      * // The `_.property` iteratee shorthand.
7111      * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
7112      * // => 0
7113      */
7114     function sortedIndexBy(array, value, iteratee) {
7115       return baseSortedIndexBy(array, value, getIteratee(iteratee));
7116     }
7117
7118     /**
7119      * This method is like `_.indexOf` except that it performs a binary
7120      * search on a sorted `array`.
7121      *
7122      * @static
7123      * @memberOf _
7124      * @since 4.0.0
7125      * @category Array
7126      * @param {Array} array The array to search.
7127      * @param {*} value The value to search for.
7128      * @returns {number} Returns the index of the matched value, else `-1`.
7129      * @example
7130      *
7131      * _.sortedIndexOf([1, 1, 2, 2], 2);
7132      * // => 2
7133      */
7134     function sortedIndexOf(array, value) {
7135       var length = array ? array.length : 0;
7136       if (length) {
7137         var index = baseSortedIndex(array, value);
7138         if (index < length && eq(array[index], value)) {
7139           return index;
7140         }
7141       }
7142       return -1;
7143     }
7144
7145     /**
7146      * This method is like `_.sortedIndex` except that it returns the highest
7147      * index at which `value` should be inserted into `array` in order to
7148      * maintain its sort order.
7149      *
7150      * @static
7151      * @memberOf _
7152      * @since 3.0.0
7153      * @category Array
7154      * @param {Array} array The sorted array to inspect.
7155      * @param {*} value The value to evaluate.
7156      * @returns {number} Returns the index at which `value` should be inserted
7157      *  into `array`.
7158      * @example
7159      *
7160      * _.sortedLastIndex([4, 5], 4);
7161      * // => 1
7162      */
7163     function sortedLastIndex(array, value) {
7164       return baseSortedIndex(array, value, true);
7165     }
7166
7167     /**
7168      * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
7169      * which is invoked for `value` and each element of `array` to compute their
7170      * sort ranking. The iteratee is invoked with one argument: (value).
7171      *
7172      * @static
7173      * @memberOf _
7174      * @since 4.0.0
7175      * @category Array
7176      * @param {Array} array The sorted array to inspect.
7177      * @param {*} value The value to evaluate.
7178      * @param {Array|Function|Object|string} [iteratee=_.identity]
7179      *  The iteratee invoked per element.
7180      * @returns {number} Returns the index at which `value` should be inserted
7181      *  into `array`.
7182      * @example
7183      *
7184      * // The `_.property` iteratee shorthand.
7185      * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
7186      * // => 1
7187      */
7188     function sortedLastIndexBy(array, value, iteratee) {
7189       return baseSortedIndexBy(array, value, getIteratee(iteratee), true);
7190     }
7191
7192     /**
7193      * This method is like `_.lastIndexOf` except that it performs a binary
7194      * search on a sorted `array`.
7195      *
7196      * @static
7197      * @memberOf _
7198      * @since 4.0.0
7199      * @category Array
7200      * @param {Array} array The array to search.
7201      * @param {*} value The value to search for.
7202      * @returns {number} Returns the index of the matched value, else `-1`.
7203      * @example
7204      *
7205      * _.sortedLastIndexOf([1, 1, 2, 2], 2);
7206      * // => 3
7207      */
7208     function sortedLastIndexOf(array, value) {
7209       var length = array ? array.length : 0;
7210       if (length) {
7211         var index = baseSortedIndex(array, value, true) - 1;
7212         if (eq(array[index], value)) {
7213           return index;
7214         }
7215       }
7216       return -1;
7217     }
7218
7219     /**
7220      * This method is like `_.uniq` except that it's designed and optimized
7221      * for sorted arrays.
7222      *
7223      * @static
7224      * @memberOf _
7225      * @since 4.0.0
7226      * @category Array
7227      * @param {Array} array The array to inspect.
7228      * @returns {Array} Returns the new duplicate free array.
7229      * @example
7230      *
7231      * _.sortedUniq([1, 1, 2]);
7232      * // => [1, 2]
7233      */
7234     function sortedUniq(array) {
7235       return (array && array.length)
7236         ? baseSortedUniq(array)
7237         : [];
7238     }
7239
7240     /**
7241      * This method is like `_.uniqBy` except that it's designed and optimized
7242      * for sorted arrays.
7243      *
7244      * @static
7245      * @memberOf _
7246      * @since 4.0.0
7247      * @category Array
7248      * @param {Array} array The array to inspect.
7249      * @param {Function} [iteratee] The iteratee invoked per element.
7250      * @returns {Array} Returns the new duplicate free array.
7251      * @example
7252      *
7253      * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
7254      * // => [1.1, 2.3]
7255      */
7256     function sortedUniqBy(array, iteratee) {
7257       return (array && array.length)
7258         ? baseSortedUniq(array, getIteratee(iteratee))
7259         : [];
7260     }
7261
7262     /**
7263      * Gets all but the first element of `array`.
7264      *
7265      * @static
7266      * @memberOf _
7267      * @since 4.0.0
7268      * @category Array
7269      * @param {Array} array The array to query.
7270      * @returns {Array} Returns the slice of `array`.
7271      * @example
7272      *
7273      * _.tail([1, 2, 3]);
7274      * // => [2, 3]
7275      */
7276     function tail(array) {
7277       return drop(array, 1);
7278     }
7279
7280     /**
7281      * Creates a slice of `array` with `n` elements taken from the beginning.
7282      *
7283      * @static
7284      * @memberOf _
7285      * @since 0.1.0
7286      * @category Array
7287      * @param {Array} array The array to query.
7288      * @param {number} [n=1] The number of elements to take.
7289      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7290      * @returns {Array} Returns the slice of `array`.
7291      * @example
7292      *
7293      * _.take([1, 2, 3]);
7294      * // => [1]
7295      *
7296      * _.take([1, 2, 3], 2);
7297      * // => [1, 2]
7298      *
7299      * _.take([1, 2, 3], 5);
7300      * // => [1, 2, 3]
7301      *
7302      * _.take([1, 2, 3], 0);
7303      * // => []
7304      */
7305     function take(array, n, guard) {
7306       if (!(array && array.length)) {
7307         return [];
7308       }
7309       n = (guard || n === undefined) ? 1 : toInteger(n);
7310       return baseSlice(array, 0, n < 0 ? 0 : n);
7311     }
7312
7313     /**
7314      * Creates a slice of `array` with `n` elements taken from the end.
7315      *
7316      * @static
7317      * @memberOf _
7318      * @since 3.0.0
7319      * @category Array
7320      * @param {Array} array The array to query.
7321      * @param {number} [n=1] The number of elements to take.
7322      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7323      * @returns {Array} Returns the slice of `array`.
7324      * @example
7325      *
7326      * _.takeRight([1, 2, 3]);
7327      * // => [3]
7328      *
7329      * _.takeRight([1, 2, 3], 2);
7330      * // => [2, 3]
7331      *
7332      * _.takeRight([1, 2, 3], 5);
7333      * // => [1, 2, 3]
7334      *
7335      * _.takeRight([1, 2, 3], 0);
7336      * // => []
7337      */
7338     function takeRight(array, n, guard) {
7339       var length = array ? array.length : 0;
7340       if (!length) {
7341         return [];
7342       }
7343       n = (guard || n === undefined) ? 1 : toInteger(n);
7344       n = length - n;
7345       return baseSlice(array, n < 0 ? 0 : n, length);
7346     }
7347
7348     /**
7349      * Creates a slice of `array` with elements taken from the end. Elements are
7350      * taken until `predicate` returns falsey. The predicate is invoked with
7351      * three arguments: (value, index, array).
7352      *
7353      * @static
7354      * @memberOf _
7355      * @since 3.0.0
7356      * @category Array
7357      * @param {Array} array The array to query.
7358      * @param {Array|Function|Object|string} [predicate=_.identity]
7359      *  The function invoked per iteration.
7360      * @returns {Array} Returns the slice of `array`.
7361      * @example
7362      *
7363      * var users = [
7364      *   { 'user': 'barney',  'active': true },
7365      *   { 'user': 'fred',    'active': false },
7366      *   { 'user': 'pebbles', 'active': false }
7367      * ];
7368      *
7369      * _.takeRightWhile(users, function(o) { return !o.active; });
7370      * // => objects for ['fred', 'pebbles']
7371      *
7372      * // The `_.matches` iteratee shorthand.
7373      * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
7374      * // => objects for ['pebbles']
7375      *
7376      * // The `_.matchesProperty` iteratee shorthand.
7377      * _.takeRightWhile(users, ['active', false]);
7378      * // => objects for ['fred', 'pebbles']
7379      *
7380      * // The `_.property` iteratee shorthand.
7381      * _.takeRightWhile(users, 'active');
7382      * // => []
7383      */
7384     function takeRightWhile(array, predicate) {
7385       return (array && array.length)
7386         ? baseWhile(array, getIteratee(predicate, 3), false, true)
7387         : [];
7388     }
7389
7390     /**
7391      * Creates a slice of `array` with elements taken from the beginning. Elements
7392      * are taken until `predicate` returns falsey. The predicate is invoked with
7393      * three arguments: (value, index, array).
7394      *
7395      * @static
7396      * @memberOf _
7397      * @since 3.0.0
7398      * @category Array
7399      * @param {Array} array The array to query.
7400      * @param {Array|Function|Object|string} [predicate=_.identity]
7401      *  The function invoked per iteration.
7402      * @returns {Array} Returns the slice of `array`.
7403      * @example
7404      *
7405      * var users = [
7406      *   { 'user': 'barney',  'active': false },
7407      *   { 'user': 'fred',    'active': false},
7408      *   { 'user': 'pebbles', 'active': true }
7409      * ];
7410      *
7411      * _.takeWhile(users, function(o) { return !o.active; });
7412      * // => objects for ['barney', 'fred']
7413      *
7414      * // The `_.matches` iteratee shorthand.
7415      * _.takeWhile(users, { 'user': 'barney', 'active': false });
7416      * // => objects for ['barney']
7417      *
7418      * // The `_.matchesProperty` iteratee shorthand.
7419      * _.takeWhile(users, ['active', false]);
7420      * // => objects for ['barney', 'fred']
7421      *
7422      * // The `_.property` iteratee shorthand.
7423      * _.takeWhile(users, 'active');
7424      * // => []
7425      */
7426     function takeWhile(array, predicate) {
7427       return (array && array.length)
7428         ? baseWhile(array, getIteratee(predicate, 3))
7429         : [];
7430     }
7431
7432     /**
7433      * Creates an array of unique values, in order, from all given arrays using
7434      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7435      * for equality comparisons.
7436      *
7437      * @static
7438      * @memberOf _
7439      * @since 0.1.0
7440      * @category Array
7441      * @param {...Array} [arrays] The arrays to inspect.
7442      * @returns {Array} Returns the new array of combined values.
7443      * @example
7444      *
7445      * _.union([2, 1], [4, 2], [1, 2]);
7446      * // => [2, 1, 4]
7447      */
7448     var union = rest(function(arrays) {
7449       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
7450     });
7451
7452     /**
7453      * This method is like `_.union` except that it accepts `iteratee` which is
7454      * invoked for each element of each `arrays` to generate the criterion by
7455      * which uniqueness is computed. The iteratee is invoked with one argument:
7456      * (value).
7457      *
7458      * @static
7459      * @memberOf _
7460      * @since 4.0.0
7461      * @category Array
7462      * @param {...Array} [arrays] The arrays to inspect.
7463      * @param {Array|Function|Object|string} [iteratee=_.identity]
7464      *  The iteratee invoked per element.
7465      * @returns {Array} Returns the new array of combined values.
7466      * @example
7467      *
7468      * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
7469      * // => [2.1, 1.2, 4.3]
7470      *
7471      * // The `_.property` iteratee shorthand.
7472      * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7473      * // => [{ 'x': 1 }, { 'x': 2 }]
7474      */
7475     var unionBy = rest(function(arrays) {
7476       var iteratee = last(arrays);
7477       if (isArrayLikeObject(iteratee)) {
7478         iteratee = undefined;
7479       }
7480       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee));
7481     });
7482
7483     /**
7484      * This method is like `_.union` except that it accepts `comparator` which
7485      * is invoked to compare elements of `arrays`. The comparator is invoked
7486      * with two arguments: (arrVal, othVal).
7487      *
7488      * @static
7489      * @memberOf _
7490      * @since 4.0.0
7491      * @category Array
7492      * @param {...Array} [arrays] The arrays to inspect.
7493      * @param {Function} [comparator] The comparator invoked per element.
7494      * @returns {Array} Returns the new array of combined values.
7495      * @example
7496      *
7497      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7498      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7499      *
7500      * _.unionWith(objects, others, _.isEqual);
7501      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
7502      */
7503     var unionWith = rest(function(arrays) {
7504       var comparator = last(arrays);
7505       if (isArrayLikeObject(comparator)) {
7506         comparator = undefined;
7507       }
7508       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
7509     });
7510
7511     /**
7512      * Creates a duplicate-free version of an array, using
7513      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7514      * for equality comparisons, in which only the first occurrence of each
7515      * element is kept.
7516      *
7517      * @static
7518      * @memberOf _
7519      * @since 0.1.0
7520      * @category Array
7521      * @param {Array} array The array to inspect.
7522      * @returns {Array} Returns the new duplicate free array.
7523      * @example
7524      *
7525      * _.uniq([2, 1, 2]);
7526      * // => [2, 1]
7527      */
7528     function uniq(array) {
7529       return (array && array.length)
7530         ? baseUniq(array)
7531         : [];
7532     }
7533
7534     /**
7535      * This method is like `_.uniq` except that it accepts `iteratee` which is
7536      * invoked for each element in `array` to generate the criterion by which
7537      * uniqueness is computed. The iteratee is invoked with one argument: (value).
7538      *
7539      * @static
7540      * @memberOf _
7541      * @since 4.0.0
7542      * @category Array
7543      * @param {Array} array The array to inspect.
7544      * @param {Array|Function|Object|string} [iteratee=_.identity]
7545      *  The iteratee invoked per element.
7546      * @returns {Array} Returns the new duplicate free array.
7547      * @example
7548      *
7549      * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
7550      * // => [2.1, 1.2]
7551      *
7552      * // The `_.property` iteratee shorthand.
7553      * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
7554      * // => [{ 'x': 1 }, { 'x': 2 }]
7555      */
7556     function uniqBy(array, iteratee) {
7557       return (array && array.length)
7558         ? baseUniq(array, getIteratee(iteratee))
7559         : [];
7560     }
7561
7562     /**
7563      * This method is like `_.uniq` except that it accepts `comparator` which
7564      * is invoked to compare elements of `array`. The comparator is invoked with
7565      * two arguments: (arrVal, othVal).
7566      *
7567      * @static
7568      * @memberOf _
7569      * @since 4.0.0
7570      * @category Array
7571      * @param {Array} array The array to inspect.
7572      * @param {Function} [comparator] The comparator invoked per element.
7573      * @returns {Array} Returns the new duplicate free array.
7574      * @example
7575      *
7576      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }];
7577      *
7578      * _.uniqWith(objects, _.isEqual);
7579      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
7580      */
7581     function uniqWith(array, comparator) {
7582       return (array && array.length)
7583         ? baseUniq(array, undefined, comparator)
7584         : [];
7585     }
7586
7587     /**
7588      * This method is like `_.zip` except that it accepts an array of grouped
7589      * elements and creates an array regrouping the elements to their pre-zip
7590      * configuration.
7591      *
7592      * @static
7593      * @memberOf _
7594      * @since 1.2.0
7595      * @category Array
7596      * @param {Array} array The array of grouped elements to process.
7597      * @returns {Array} Returns the new array of regrouped elements.
7598      * @example
7599      *
7600      * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
7601      * // => [['fred', 30, true], ['barney', 40, false]]
7602      *
7603      * _.unzip(zipped);
7604      * // => [['fred', 'barney'], [30, 40], [true, false]]
7605      */
7606     function unzip(array) {
7607       if (!(array && array.length)) {
7608         return [];
7609       }
7610       var length = 0;
7611       array = arrayFilter(array, function(group) {
7612         if (isArrayLikeObject(group)) {
7613           length = nativeMax(group.length, length);
7614           return true;
7615         }
7616       });
7617       return baseTimes(length, function(index) {
7618         return arrayMap(array, baseProperty(index));
7619       });
7620     }
7621
7622     /**
7623      * This method is like `_.unzip` except that it accepts `iteratee` to specify
7624      * how regrouped values should be combined. The iteratee is invoked with the
7625      * elements of each group: (...group).
7626      *
7627      * @static
7628      * @memberOf _
7629      * @since 3.8.0
7630      * @category Array
7631      * @param {Array} array The array of grouped elements to process.
7632      * @param {Function} [iteratee=_.identity] The function to combine
7633      *  regrouped values.
7634      * @returns {Array} Returns the new array of regrouped elements.
7635      * @example
7636      *
7637      * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
7638      * // => [[1, 10, 100], [2, 20, 200]]
7639      *
7640      * _.unzipWith(zipped, _.add);
7641      * // => [3, 30, 300]
7642      */
7643     function unzipWith(array, iteratee) {
7644       if (!(array && array.length)) {
7645         return [];
7646       }
7647       var result = unzip(array);
7648       if (iteratee == null) {
7649         return result;
7650       }
7651       return arrayMap(result, function(group) {
7652         return apply(iteratee, undefined, group);
7653       });
7654     }
7655
7656     /**
7657      * Creates an array excluding all given values using
7658      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7659      * for equality comparisons.
7660      *
7661      * @static
7662      * @memberOf _
7663      * @since 0.1.0
7664      * @category Array
7665      * @param {Array} array The array to filter.
7666      * @param {...*} [values] The values to exclude.
7667      * @returns {Array} Returns the new array of filtered values.
7668      * @see _.difference, _.xor
7669      * @example
7670      *
7671      * _.without([1, 2, 1, 3], 1, 2);
7672      * // => [3]
7673      */
7674     var without = rest(function(array, values) {
7675       return isArrayLikeObject(array)
7676         ? baseDifference(array, values)
7677         : [];
7678     });
7679
7680     /**
7681      * Creates an array of unique values that is the
7682      * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
7683      * of the given arrays. The order of result values is determined by the order
7684      * they occur in the arrays.
7685      *
7686      * @static
7687      * @memberOf _
7688      * @since 2.4.0
7689      * @category Array
7690      * @param {...Array} [arrays] The arrays to inspect.
7691      * @returns {Array} Returns the new array of values.
7692      * @see _.difference, _.without
7693      * @example
7694      *
7695      * _.xor([2, 1], [4, 2]);
7696      * // => [1, 4]
7697      */
7698     var xor = rest(function(arrays) {
7699       return baseXor(arrayFilter(arrays, isArrayLikeObject));
7700     });
7701
7702     /**
7703      * This method is like `_.xor` except that it accepts `iteratee` which is
7704      * invoked for each element of each `arrays` to generate the criterion by
7705      * which by which they're compared. The iteratee is invoked with one argument:
7706      * (value).
7707      *
7708      * @static
7709      * @memberOf _
7710      * @since 4.0.0
7711      * @category Array
7712      * @param {...Array} [arrays] The arrays to inspect.
7713      * @param {Array|Function|Object|string} [iteratee=_.identity]
7714      *  The iteratee invoked per element.
7715      * @returns {Array} Returns the new array of values.
7716      * @example
7717      *
7718      * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
7719      * // => [1.2, 4.3]
7720      *
7721      * // The `_.property` iteratee shorthand.
7722      * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7723      * // => [{ 'x': 2 }]
7724      */
7725     var xorBy = rest(function(arrays) {
7726       var iteratee = last(arrays);
7727       if (isArrayLikeObject(iteratee)) {
7728         iteratee = undefined;
7729       }
7730       return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
7731     });
7732
7733     /**
7734      * This method is like `_.xor` except that it accepts `comparator` which is
7735      * invoked to compare elements of `arrays`. The comparator is invoked with
7736      * two arguments: (arrVal, othVal).
7737      *
7738      * @static
7739      * @memberOf _
7740      * @since 4.0.0
7741      * @category Array
7742      * @param {...Array} [arrays] The arrays to inspect.
7743      * @param {Function} [comparator] The comparator invoked per element.
7744      * @returns {Array} Returns the new array of values.
7745      * @example
7746      *
7747      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7748      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7749      *
7750      * _.xorWith(objects, others, _.isEqual);
7751      * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
7752      */
7753     var xorWith = rest(function(arrays) {
7754       var comparator = last(arrays);
7755       if (isArrayLikeObject(comparator)) {
7756         comparator = undefined;
7757       }
7758       return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
7759     });
7760
7761     /**
7762      * Creates an array of grouped elements, the first of which contains the
7763      * first elements of the given arrays, the second of which contains the
7764      * second elements of the given arrays, and so on.
7765      *
7766      * @static
7767      * @memberOf _
7768      * @since 0.1.0
7769      * @category Array
7770      * @param {...Array} [arrays] The arrays to process.
7771      * @returns {Array} Returns the new array of grouped elements.
7772      * @example
7773      *
7774      * _.zip(['fred', 'barney'], [30, 40], [true, false]);
7775      * // => [['fred', 30, true], ['barney', 40, false]]
7776      */
7777     var zip = rest(unzip);
7778
7779     /**
7780      * This method is like `_.fromPairs` except that it accepts two arrays,
7781      * one of property identifiers and one of corresponding values.
7782      *
7783      * @static
7784      * @memberOf _
7785      * @since 0.4.0
7786      * @category Array
7787      * @param {Array} [props=[]] The property identifiers.
7788      * @param {Array} [values=[]] The property values.
7789      * @returns {Object} Returns the new object.
7790      * @example
7791      *
7792      * _.zipObject(['a', 'b'], [1, 2]);
7793      * // => { 'a': 1, 'b': 2 }
7794      */
7795     function zipObject(props, values) {
7796       return baseZipObject(props || [], values || [], assignValue);
7797     }
7798
7799     /**
7800      * This method is like `_.zipObject` except that it supports property paths.
7801      *
7802      * @static
7803      * @memberOf _
7804      * @since 4.1.0
7805      * @category Array
7806      * @param {Array} [props=[]] The property identifiers.
7807      * @param {Array} [values=[]] The property values.
7808      * @returns {Object} Returns the new object.
7809      * @example
7810      *
7811      * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
7812      * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
7813      */
7814     function zipObjectDeep(props, values) {
7815       return baseZipObject(props || [], values || [], baseSet);
7816     }
7817
7818     /**
7819      * This method is like `_.zip` except that it accepts `iteratee` to specify
7820      * how grouped values should be combined. The iteratee is invoked with the
7821      * elements of each group: (...group).
7822      *
7823      * @static
7824      * @memberOf _
7825      * @since 3.8.0
7826      * @category Array
7827      * @param {...Array} [arrays] The arrays to process.
7828      * @param {Function} [iteratee=_.identity] The function to combine grouped values.
7829      * @returns {Array} Returns the new array of grouped elements.
7830      * @example
7831      *
7832      * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
7833      *   return a + b + c;
7834      * });
7835      * // => [111, 222]
7836      */
7837     var zipWith = rest(function(arrays) {
7838       var length = arrays.length,
7839           iteratee = length > 1 ? arrays[length - 1] : undefined;
7840
7841       iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
7842       return unzipWith(arrays, iteratee);
7843     });
7844
7845     /*------------------------------------------------------------------------*/
7846
7847     /**
7848      * Creates a `lodash` wrapper instance that wraps `value` with explicit method
7849      * chain sequences enabled. The result of such sequences must be unwrapped
7850      * with `_#value`.
7851      *
7852      * @static
7853      * @memberOf _
7854      * @since 1.3.0
7855      * @category Seq
7856      * @param {*} value The value to wrap.
7857      * @returns {Object} Returns the new `lodash` wrapper instance.
7858      * @example
7859      *
7860      * var users = [
7861      *   { 'user': 'barney',  'age': 36 },
7862      *   { 'user': 'fred',    'age': 40 },
7863      *   { 'user': 'pebbles', 'age': 1 }
7864      * ];
7865      *
7866      * var youngest = _
7867      *   .chain(users)
7868      *   .sortBy('age')
7869      *   .map(function(o) {
7870      *     return o.user + ' is ' + o.age;
7871      *   })
7872      *   .head()
7873      *   .value();
7874      * // => 'pebbles is 1'
7875      */
7876     function chain(value) {
7877       var result = lodash(value);
7878       result.__chain__ = true;
7879       return result;
7880     }
7881
7882     /**
7883      * This method invokes `interceptor` and returns `value`. The interceptor
7884      * is invoked with one argument; (value). The purpose of this method is to
7885      * "tap into" a method chain sequence in order to modify intermediate results.
7886      *
7887      * @static
7888      * @memberOf _
7889      * @since 0.1.0
7890      * @category Seq
7891      * @param {*} value The value to provide to `interceptor`.
7892      * @param {Function} interceptor The function to invoke.
7893      * @returns {*} Returns `value`.
7894      * @example
7895      *
7896      * _([1, 2, 3])
7897      *  .tap(function(array) {
7898      *    // Mutate input array.
7899      *    array.pop();
7900      *  })
7901      *  .reverse()
7902      *  .value();
7903      * // => [2, 1]
7904      */
7905     function tap(value, interceptor) {
7906       interceptor(value);
7907       return value;
7908     }
7909
7910     /**
7911      * This method is like `_.tap` except that it returns the result of `interceptor`.
7912      * The purpose of this method is to "pass thru" values replacing intermediate
7913      * results in a method chain sequence.
7914      *
7915      * @static
7916      * @memberOf _
7917      * @since 3.0.0
7918      * @category Seq
7919      * @param {*} value The value to provide to `interceptor`.
7920      * @param {Function} interceptor The function to invoke.
7921      * @returns {*} Returns the result of `interceptor`.
7922      * @example
7923      *
7924      * _('  abc  ')
7925      *  .chain()
7926      *  .trim()
7927      *  .thru(function(value) {
7928      *    return [value];
7929      *  })
7930      *  .value();
7931      * // => ['abc']
7932      */
7933     function thru(value, interceptor) {
7934       return interceptor(value);
7935     }
7936
7937     /**
7938      * This method is the wrapper version of `_.at`.
7939      *
7940      * @name at
7941      * @memberOf _
7942      * @since 1.0.0
7943      * @category Seq
7944      * @param {...(string|string[])} [paths] The property paths of elements to pick.
7945      * @returns {Object} Returns the new `lodash` wrapper instance.
7946      * @example
7947      *
7948      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
7949      *
7950      * _(object).at(['a[0].b.c', 'a[1]']).value();
7951      * // => [3, 4]
7952      *
7953      * _(['a', 'b', 'c']).at(0, 2).value();
7954      * // => ['a', 'c']
7955      */
7956     var wrapperAt = rest(function(paths) {
7957       paths = baseFlatten(paths, 1);
7958       var length = paths.length,
7959           start = length ? paths[0] : 0,
7960           value = this.__wrapped__,
7961           interceptor = function(object) { return baseAt(object, paths); };
7962
7963       if (length > 1 || this.__actions__.length ||
7964           !(value instanceof LazyWrapper) || !isIndex(start)) {
7965         return this.thru(interceptor);
7966       }
7967       value = value.slice(start, +start + (length ? 1 : 0));
7968       value.__actions__.push({
7969         'func': thru,
7970         'args': [interceptor],
7971         'thisArg': undefined
7972       });
7973       return new LodashWrapper(value, this.__chain__).thru(function(array) {
7974         if (length && !array.length) {
7975           array.push(undefined);
7976         }
7977         return array;
7978       });
7979     });
7980
7981     /**
7982      * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
7983      *
7984      * @name chain
7985      * @memberOf _
7986      * @since 0.1.0
7987      * @category Seq
7988      * @returns {Object} Returns the new `lodash` wrapper instance.
7989      * @example
7990      *
7991      * var users = [
7992      *   { 'user': 'barney', 'age': 36 },
7993      *   { 'user': 'fred',   'age': 40 }
7994      * ];
7995      *
7996      * // A sequence without explicit chaining.
7997      * _(users).head();
7998      * // => { 'user': 'barney', 'age': 36 }
7999      *
8000      * // A sequence with explicit chaining.
8001      * _(users)
8002      *   .chain()
8003      *   .head()
8004      *   .pick('user')
8005      *   .value();
8006      * // => { 'user': 'barney' }
8007      */
8008     function wrapperChain() {
8009       return chain(this);
8010     }
8011
8012     /**
8013      * Executes the chain sequence and returns the wrapped result.
8014      *
8015      * @name commit
8016      * @memberOf _
8017      * @since 3.2.0
8018      * @category Seq
8019      * @returns {Object} Returns the new `lodash` wrapper instance.
8020      * @example
8021      *
8022      * var array = [1, 2];
8023      * var wrapped = _(array).push(3);
8024      *
8025      * console.log(array);
8026      * // => [1, 2]
8027      *
8028      * wrapped = wrapped.commit();
8029      * console.log(array);
8030      * // => [1, 2, 3]
8031      *
8032      * wrapped.last();
8033      * // => 3
8034      *
8035      * console.log(array);
8036      * // => [1, 2, 3]
8037      */
8038     function wrapperCommit() {
8039       return new LodashWrapper(this.value(), this.__chain__);
8040     }
8041
8042     /**
8043      * Gets the next value on a wrapped object following the
8044      * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
8045      *
8046      * @name next
8047      * @memberOf _
8048      * @since 4.0.0
8049      * @category Seq
8050      * @returns {Object} Returns the next iterator value.
8051      * @example
8052      *
8053      * var wrapped = _([1, 2]);
8054      *
8055      * wrapped.next();
8056      * // => { 'done': false, 'value': 1 }
8057      *
8058      * wrapped.next();
8059      * // => { 'done': false, 'value': 2 }
8060      *
8061      * wrapped.next();
8062      * // => { 'done': true, 'value': undefined }
8063      */
8064     function wrapperNext() {
8065       if (this.__values__ === undefined) {
8066         this.__values__ = toArray(this.value());
8067       }
8068       var done = this.__index__ >= this.__values__.length,
8069           value = done ? undefined : this.__values__[this.__index__++];
8070
8071       return { 'done': done, 'value': value };
8072     }
8073
8074     /**
8075      * Enables the wrapper to be iterable.
8076      *
8077      * @name Symbol.iterator
8078      * @memberOf _
8079      * @since 4.0.0
8080      * @category Seq
8081      * @returns {Object} Returns the wrapper object.
8082      * @example
8083      *
8084      * var wrapped = _([1, 2]);
8085      *
8086      * wrapped[Symbol.iterator]() === wrapped;
8087      * // => true
8088      *
8089      * Array.from(wrapped);
8090      * // => [1, 2]
8091      */
8092     function wrapperToIterator() {
8093       return this;
8094     }
8095
8096     /**
8097      * Creates a clone of the chain sequence planting `value` as the wrapped value.
8098      *
8099      * @name plant
8100      * @memberOf _
8101      * @since 3.2.0
8102      * @category Seq
8103      * @param {*} value The value to plant.
8104      * @returns {Object} Returns the new `lodash` wrapper instance.
8105      * @example
8106      *
8107      * function square(n) {
8108      *   return n * n;
8109      * }
8110      *
8111      * var wrapped = _([1, 2]).map(square);
8112      * var other = wrapped.plant([3, 4]);
8113      *
8114      * other.value();
8115      * // => [9, 16]
8116      *
8117      * wrapped.value();
8118      * // => [1, 4]
8119      */
8120     function wrapperPlant(value) {
8121       var result,
8122           parent = this;
8123
8124       while (parent instanceof baseLodash) {
8125         var clone = wrapperClone(parent);
8126         clone.__index__ = 0;
8127         clone.__values__ = undefined;
8128         if (result) {
8129           previous.__wrapped__ = clone;
8130         } else {
8131           result = clone;
8132         }
8133         var previous = clone;
8134         parent = parent.__wrapped__;
8135       }
8136       previous.__wrapped__ = value;
8137       return result;
8138     }
8139
8140     /**
8141      * This method is the wrapper version of `_.reverse`.
8142      *
8143      * **Note:** This method mutates the wrapped array.
8144      *
8145      * @name reverse
8146      * @memberOf _
8147      * @since 0.1.0
8148      * @category Seq
8149      * @returns {Object} Returns the new `lodash` wrapper instance.
8150      * @example
8151      *
8152      * var array = [1, 2, 3];
8153      *
8154      * _(array).reverse().value()
8155      * // => [3, 2, 1]
8156      *
8157      * console.log(array);
8158      * // => [3, 2, 1]
8159      */
8160     function wrapperReverse() {
8161       var value = this.__wrapped__;
8162       if (value instanceof LazyWrapper) {
8163         var wrapped = value;
8164         if (this.__actions__.length) {
8165           wrapped = new LazyWrapper(this);
8166         }
8167         wrapped = wrapped.reverse();
8168         wrapped.__actions__.push({
8169           'func': thru,
8170           'args': [reverse],
8171           'thisArg': undefined
8172         });
8173         return new LodashWrapper(wrapped, this.__chain__);
8174       }
8175       return this.thru(reverse);
8176     }
8177
8178     /**
8179      * Executes the chain sequence to resolve the unwrapped value.
8180      *
8181      * @name value
8182      * @memberOf _
8183      * @since 0.1.0
8184      * @alias toJSON, valueOf
8185      * @category Seq
8186      * @returns {*} Returns the resolved unwrapped value.
8187      * @example
8188      *
8189      * _([1, 2, 3]).value();
8190      * // => [1, 2, 3]
8191      */
8192     function wrapperValue() {
8193       return baseWrapperValue(this.__wrapped__, this.__actions__);
8194     }
8195
8196     /*------------------------------------------------------------------------*/
8197
8198     /**
8199      * Creates an object composed of keys generated from the results of running
8200      * each element of `collection` thru `iteratee`. The corresponding value of
8201      * each key is the number of times the key was returned by `iteratee`. The
8202      * iteratee is invoked with one argument: (value).
8203      *
8204      * @static
8205      * @memberOf _
8206      * @since 0.5.0
8207      * @category Collection
8208      * @param {Array|Object} collection The collection to iterate over.
8209      * @param {Array|Function|Object|string} [iteratee=_.identity]
8210      *  The iteratee to transform keys.
8211      * @returns {Object} Returns the composed aggregate object.
8212      * @example
8213      *
8214      * _.countBy([6.1, 4.2, 6.3], Math.floor);
8215      * // => { '4': 1, '6': 2 }
8216      *
8217      * _.countBy(['one', 'two', 'three'], 'length');
8218      * // => { '3': 2, '5': 1 }
8219      */
8220     var countBy = createAggregator(function(result, value, key) {
8221       hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
8222     });
8223
8224     /**
8225      * Checks if `predicate` returns truthy for **all** elements of `collection`.
8226      * Iteration is stopped once `predicate` returns falsey. The predicate is
8227      * invoked with three arguments: (value, index|key, collection).
8228      *
8229      * @static
8230      * @memberOf _
8231      * @since 0.1.0
8232      * @category Collection
8233      * @param {Array|Object} collection The collection to iterate over.
8234      * @param {Array|Function|Object|string} [predicate=_.identity]
8235      *  The function invoked per iteration.
8236      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8237      * @returns {boolean} Returns `true` if all elements pass the predicate check,
8238      *  else `false`.
8239      * @example
8240      *
8241      * _.every([true, 1, null, 'yes'], Boolean);
8242      * // => false
8243      *
8244      * var users = [
8245      *   { 'user': 'barney', 'age': 36, 'active': false },
8246      *   { 'user': 'fred',   'age': 40, 'active': false }
8247      * ];
8248      *
8249      * // The `_.matches` iteratee shorthand.
8250      * _.every(users, { 'user': 'barney', 'active': false });
8251      * // => false
8252      *
8253      * // The `_.matchesProperty` iteratee shorthand.
8254      * _.every(users, ['active', false]);
8255      * // => true
8256      *
8257      * // The `_.property` iteratee shorthand.
8258      * _.every(users, 'active');
8259      * // => false
8260      */
8261     function every(collection, predicate, guard) {
8262       var func = isArray(collection) ? arrayEvery : baseEvery;
8263       if (guard && isIterateeCall(collection, predicate, guard)) {
8264         predicate = undefined;
8265       }
8266       return func(collection, getIteratee(predicate, 3));
8267     }
8268
8269     /**
8270      * Iterates over elements of `collection`, returning an array of all elements
8271      * `predicate` returns truthy for. The predicate is invoked with three
8272      * arguments: (value, index|key, collection).
8273      *
8274      * @static
8275      * @memberOf _
8276      * @since 0.1.0
8277      * @category Collection
8278      * @param {Array|Object} collection The collection to iterate over.
8279      * @param {Array|Function|Object|string} [predicate=_.identity]
8280      *  The function invoked per iteration.
8281      * @returns {Array} Returns the new filtered array.
8282      * @see _.reject
8283      * @example
8284      *
8285      * var users = [
8286      *   { 'user': 'barney', 'age': 36, 'active': true },
8287      *   { 'user': 'fred',   'age': 40, 'active': false }
8288      * ];
8289      *
8290      * _.filter(users, function(o) { return !o.active; });
8291      * // => objects for ['fred']
8292      *
8293      * // The `_.matches` iteratee shorthand.
8294      * _.filter(users, { 'age': 36, 'active': true });
8295      * // => objects for ['barney']
8296      *
8297      * // The `_.matchesProperty` iteratee shorthand.
8298      * _.filter(users, ['active', false]);
8299      * // => objects for ['fred']
8300      *
8301      * // The `_.property` iteratee shorthand.
8302      * _.filter(users, 'active');
8303      * // => objects for ['barney']
8304      */
8305     function filter(collection, predicate) {
8306       var func = isArray(collection) ? arrayFilter : baseFilter;
8307       return func(collection, getIteratee(predicate, 3));
8308     }
8309
8310     /**
8311      * Iterates over elements of `collection`, returning the first element
8312      * `predicate` returns truthy for. The predicate is invoked with three
8313      * arguments: (value, index|key, collection).
8314      *
8315      * @static
8316      * @memberOf _
8317      * @since 0.1.0
8318      * @category Collection
8319      * @param {Array|Object} collection The collection to search.
8320      * @param {Array|Function|Object|string} [predicate=_.identity]
8321      *  The function invoked per iteration.
8322      * @returns {*} Returns the matched element, else `undefined`.
8323      * @example
8324      *
8325      * var users = [
8326      *   { 'user': 'barney',  'age': 36, 'active': true },
8327      *   { 'user': 'fred',    'age': 40, 'active': false },
8328      *   { 'user': 'pebbles', 'age': 1,  'active': true }
8329      * ];
8330      *
8331      * _.find(users, function(o) { return o.age < 40; });
8332      * // => object for 'barney'
8333      *
8334      * // The `_.matches` iteratee shorthand.
8335      * _.find(users, { 'age': 1, 'active': true });
8336      * // => object for 'pebbles'
8337      *
8338      * // The `_.matchesProperty` iteratee shorthand.
8339      * _.find(users, ['active', false]);
8340      * // => object for 'fred'
8341      *
8342      * // The `_.property` iteratee shorthand.
8343      * _.find(users, 'active');
8344      * // => object for 'barney'
8345      */
8346     function find(collection, predicate) {
8347       predicate = getIteratee(predicate, 3);
8348       if (isArray(collection)) {
8349         var index = baseFindIndex(collection, predicate);
8350         return index > -1 ? collection[index] : undefined;
8351       }
8352       return baseFind(collection, predicate, baseEach);
8353     }
8354
8355     /**
8356      * This method is like `_.find` except that it iterates over elements of
8357      * `collection` from right to left.
8358      *
8359      * @static
8360      * @memberOf _
8361      * @since 2.0.0
8362      * @category Collection
8363      * @param {Array|Object} collection The collection to search.
8364      * @param {Array|Function|Object|string} [predicate=_.identity]
8365      *  The function invoked per iteration.
8366      * @returns {*} Returns the matched element, else `undefined`.
8367      * @example
8368      *
8369      * _.findLast([1, 2, 3, 4], function(n) {
8370      *   return n % 2 == 1;
8371      * });
8372      * // => 3
8373      */
8374     function findLast(collection, predicate) {
8375       predicate = getIteratee(predicate, 3);
8376       if (isArray(collection)) {
8377         var index = baseFindIndex(collection, predicate, true);
8378         return index > -1 ? collection[index] : undefined;
8379       }
8380       return baseFind(collection, predicate, baseEachRight);
8381     }
8382
8383     /**
8384      * Creates a flattened array of values by running each element in `collection`
8385      * thru `iteratee` and flattening the mapped results. The iteratee is invoked
8386      * with three arguments: (value, index|key, collection).
8387      *
8388      * @static
8389      * @memberOf _
8390      * @since 4.0.0
8391      * @category Collection
8392      * @param {Array|Object} collection The collection to iterate over.
8393      * @param {Array|Function|Object|string} [iteratee=_.identity]
8394      *  The function invoked per iteration.
8395      * @returns {Array} Returns the new flattened array.
8396      * @example
8397      *
8398      * function duplicate(n) {
8399      *   return [n, n];
8400      * }
8401      *
8402      * _.flatMap([1, 2], duplicate);
8403      * // => [1, 1, 2, 2]
8404      */
8405     function flatMap(collection, iteratee) {
8406       return baseFlatten(map(collection, iteratee), 1);
8407     }
8408
8409     /**
8410      * This method is like `_.flatMap` except that it recursively flattens the
8411      * mapped results.
8412      *
8413      * @static
8414      * @memberOf _
8415      * @since 4.7.0
8416      * @category Collection
8417      * @param {Array|Object} collection The collection to iterate over.
8418      * @param {Array|Function|Object|string} [iteratee=_.identity]
8419      *  The function invoked per iteration.
8420      * @returns {Array} Returns the new flattened array.
8421      * @example
8422      *
8423      * function duplicate(n) {
8424      *   return [[[n, n]]];
8425      * }
8426      *
8427      * _.flatMapDeep([1, 2], duplicate);
8428      * // => [1, 1, 2, 2]
8429      */
8430     function flatMapDeep(collection, iteratee) {
8431       return baseFlatten(map(collection, iteratee), INFINITY);
8432     }
8433
8434     /**
8435      * This method is like `_.flatMap` except that it recursively flattens the
8436      * mapped results up to `depth` times.
8437      *
8438      * @static
8439      * @memberOf _
8440      * @since 4.7.0
8441      * @category Collection
8442      * @param {Array|Object} collection The collection to iterate over.
8443      * @param {Array|Function|Object|string} [iteratee=_.identity]
8444      *  The function invoked per iteration.
8445      * @param {number} [depth=1] The maximum recursion depth.
8446      * @returns {Array} Returns the new flattened array.
8447      * @example
8448      *
8449      * function duplicate(n) {
8450      *   return [[[n, n]]];
8451      * }
8452      *
8453      * _.flatMapDepth([1, 2], duplicate, 2);
8454      * // => [[1, 1], [2, 2]]
8455      */
8456     function flatMapDepth(collection, iteratee, depth) {
8457       depth = depth === undefined ? 1 : toInteger(depth);
8458       return baseFlatten(map(collection, iteratee), depth);
8459     }
8460
8461     /**
8462      * Iterates over elements of `collection` and invokes `iteratee` for each element.
8463      * The iteratee is invoked with three arguments: (value, index|key, collection).
8464      * Iteratee functions may exit iteration early by explicitly returning `false`.
8465      *
8466      * **Note:** As with other "Collections" methods, objects with a "length"
8467      * property are iterated like arrays. To avoid this behavior use `_.forIn`
8468      * or `_.forOwn` for object iteration.
8469      *
8470      * @static
8471      * @memberOf _
8472      * @since 0.1.0
8473      * @alias each
8474      * @category Collection
8475      * @param {Array|Object} collection The collection to iterate over.
8476      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
8477      * @returns {Array|Object} Returns `collection`.
8478      * @see _.forEachRight
8479      * @example
8480      *
8481      * _([1, 2]).forEach(function(value) {
8482      *   console.log(value);
8483      * });
8484      * // => Logs `1` then `2`.
8485      *
8486      * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
8487      *   console.log(key);
8488      * });
8489      * // => Logs 'a' then 'b' (iteration order is not guaranteed).
8490      */
8491     function forEach(collection, iteratee) {
8492       return (typeof iteratee == 'function' && isArray(collection))
8493         ? arrayEach(collection, iteratee)
8494         : baseEach(collection, getIteratee(iteratee));
8495     }
8496
8497     /**
8498      * This method is like `_.forEach` except that it iterates over elements of
8499      * `collection` from right to left.
8500      *
8501      * @static
8502      * @memberOf _
8503      * @since 2.0.0
8504      * @alias eachRight
8505      * @category Collection
8506      * @param {Array|Object} collection The collection to iterate over.
8507      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
8508      * @returns {Array|Object} Returns `collection`.
8509      * @see _.forEach
8510      * @example
8511      *
8512      * _.forEachRight([1, 2], function(value) {
8513      *   console.log(value);
8514      * });
8515      * // => Logs `2` then `1`.
8516      */
8517     function forEachRight(collection, iteratee) {
8518       return (typeof iteratee == 'function' && isArray(collection))
8519         ? arrayEachRight(collection, iteratee)
8520         : baseEachRight(collection, getIteratee(iteratee));
8521     }
8522
8523     /**
8524      * Creates an object composed of keys generated from the results of running
8525      * each element of `collection` thru `iteratee`. The order of grouped values
8526      * is determined by the order they occur in `collection`. The corresponding
8527      * value of each key is an array of elements responsible for generating the
8528      * key. The iteratee is invoked with one argument: (value).
8529      *
8530      * @static
8531      * @memberOf _
8532      * @since 0.1.0
8533      * @category Collection
8534      * @param {Array|Object} collection The collection to iterate over.
8535      * @param {Array|Function|Object|string} [iteratee=_.identity]
8536      *  The iteratee to transform keys.
8537      * @returns {Object} Returns the composed aggregate object.
8538      * @example
8539      *
8540      * _.groupBy([6.1, 4.2, 6.3], Math.floor);
8541      * // => { '4': [4.2], '6': [6.1, 6.3] }
8542      *
8543      * // The `_.property` iteratee shorthand.
8544      * _.groupBy(['one', 'two', 'three'], 'length');
8545      * // => { '3': ['one', 'two'], '5': ['three'] }
8546      */
8547     var groupBy = createAggregator(function(result, value, key) {
8548       if (hasOwnProperty.call(result, key)) {
8549         result[key].push(value);
8550       } else {
8551         result[key] = [value];
8552       }
8553     });
8554
8555     /**
8556      * Checks if `value` is in `collection`. If `collection` is a string, it's
8557      * checked for a substring of `value`, otherwise
8558      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
8559      * is used for equality comparisons. If `fromIndex` is negative, it's used as
8560      * the offset from the end of `collection`.
8561      *
8562      * @static
8563      * @memberOf _
8564      * @since 0.1.0
8565      * @category Collection
8566      * @param {Array|Object|string} collection The collection to search.
8567      * @param {*} value The value to search for.
8568      * @param {number} [fromIndex=0] The index to search from.
8569      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
8570      * @returns {boolean} Returns `true` if `value` is found, else `false`.
8571      * @example
8572      *
8573      * _.includes([1, 2, 3], 1);
8574      * // => true
8575      *
8576      * _.includes([1, 2, 3], 1, 2);
8577      * // => false
8578      *
8579      * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
8580      * // => true
8581      *
8582      * _.includes('pebbles', 'eb');
8583      * // => true
8584      */
8585     function includes(collection, value, fromIndex, guard) {
8586       collection = isArrayLike(collection) ? collection : values(collection);
8587       fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
8588
8589       var length = collection.length;
8590       if (fromIndex < 0) {
8591         fromIndex = nativeMax(length + fromIndex, 0);
8592       }
8593       return isString(collection)
8594         ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
8595         : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
8596     }
8597
8598     /**
8599      * Invokes the method at `path` of each element in `collection`, returning
8600      * an array of the results of each invoked method. Any additional arguments
8601      * are provided to each invoked method. If `methodName` is a function, it's
8602      * invoked for and `this` bound to, each element in `collection`.
8603      *
8604      * @static
8605      * @memberOf _
8606      * @since 4.0.0
8607      * @category Collection
8608      * @param {Array|Object} collection The collection to iterate over.
8609      * @param {Array|Function|string} path The path of the method to invoke or
8610      *  the function invoked per iteration.
8611      * @param {...*} [args] The arguments to invoke each method with.
8612      * @returns {Array} Returns the array of results.
8613      * @example
8614      *
8615      * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
8616      * // => [[1, 5, 7], [1, 2, 3]]
8617      *
8618      * _.invokeMap([123, 456], String.prototype.split, '');
8619      * // => [['1', '2', '3'], ['4', '5', '6']]
8620      */
8621     var invokeMap = rest(function(collection, path, args) {
8622       var index = -1,
8623           isFunc = typeof path == 'function',
8624           isProp = isKey(path),
8625           result = isArrayLike(collection) ? Array(collection.length) : [];
8626
8627       baseEach(collection, function(value) {
8628         var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
8629         result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
8630       });
8631       return result;
8632     });
8633
8634     /**
8635      * Creates an object composed of keys generated from the results of running
8636      * each element of `collection` thru `iteratee`. The corresponding value of
8637      * each key is the last element responsible for generating the key. The
8638      * iteratee is invoked with one argument: (value).
8639      *
8640      * @static
8641      * @memberOf _
8642      * @since 4.0.0
8643      * @category Collection
8644      * @param {Array|Object} collection The collection to iterate over.
8645      * @param {Array|Function|Object|string} [iteratee=_.identity]
8646      *  The iteratee to transform keys.
8647      * @returns {Object} Returns the composed aggregate object.
8648      * @example
8649      *
8650      * var array = [
8651      *   { 'dir': 'left', 'code': 97 },
8652      *   { 'dir': 'right', 'code': 100 }
8653      * ];
8654      *
8655      * _.keyBy(array, function(o) {
8656      *   return String.fromCharCode(o.code);
8657      * });
8658      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
8659      *
8660      * _.keyBy(array, 'dir');
8661      * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
8662      */
8663     var keyBy = createAggregator(function(result, value, key) {
8664       result[key] = value;
8665     });
8666
8667     /**
8668      * Creates an array of values by running each element in `collection` thru
8669      * `iteratee`. The iteratee is invoked with three arguments:
8670      * (value, index|key, collection).
8671      *
8672      * Many lodash methods are guarded to work as iteratees for methods like
8673      * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
8674      *
8675      * The guarded methods are:
8676      * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
8677      * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
8678      * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
8679      * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
8680      *
8681      * @static
8682      * @memberOf _
8683      * @since 0.1.0
8684      * @category Collection
8685      * @param {Array|Object} collection The collection to iterate over.
8686      * @param {Array|Function|Object|string} [iteratee=_.identity]
8687      *  The function invoked per iteration.
8688      * @returns {Array} Returns the new mapped array.
8689      * @example
8690      *
8691      * function square(n) {
8692      *   return n * n;
8693      * }
8694      *
8695      * _.map([4, 8], square);
8696      * // => [16, 64]
8697      *
8698      * _.map({ 'a': 4, 'b': 8 }, square);
8699      * // => [16, 64] (iteration order is not guaranteed)
8700      *
8701      * var users = [
8702      *   { 'user': 'barney' },
8703      *   { 'user': 'fred' }
8704      * ];
8705      *
8706      * // The `_.property` iteratee shorthand.
8707      * _.map(users, 'user');
8708      * // => ['barney', 'fred']
8709      */
8710     function map(collection, iteratee) {
8711       var func = isArray(collection) ? arrayMap : baseMap;
8712       return func(collection, getIteratee(iteratee, 3));
8713     }
8714
8715     /**
8716      * This method is like `_.sortBy` except that it allows specifying the sort
8717      * orders of the iteratees to sort by. If `orders` is unspecified, all values
8718      * are sorted in ascending order. Otherwise, specify an order of "desc" for
8719      * descending or "asc" for ascending sort order of corresponding values.
8720      *
8721      * @static
8722      * @memberOf _
8723      * @since 4.0.0
8724      * @category Collection
8725      * @param {Array|Object} collection The collection to iterate over.
8726      * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
8727      *  The iteratees to sort by.
8728      * @param {string[]} [orders] The sort orders of `iteratees`.
8729      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
8730      * @returns {Array} Returns the new sorted array.
8731      * @example
8732      *
8733      * var users = [
8734      *   { 'user': 'fred',   'age': 48 },
8735      *   { 'user': 'barney', 'age': 34 },
8736      *   { 'user': 'fred',   'age': 40 },
8737      *   { 'user': 'barney', 'age': 36 }
8738      * ];
8739      *
8740      * // Sort by `user` in ascending order and by `age` in descending order.
8741      * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
8742      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
8743      */
8744     function orderBy(collection, iteratees, orders, guard) {
8745       if (collection == null) {
8746         return [];
8747       }
8748       if (!isArray(iteratees)) {
8749         iteratees = iteratees == null ? [] : [iteratees];
8750       }
8751       orders = guard ? undefined : orders;
8752       if (!isArray(orders)) {
8753         orders = orders == null ? [] : [orders];
8754       }
8755       return baseOrderBy(collection, iteratees, orders);
8756     }
8757
8758     /**
8759      * Creates an array of elements split into two groups, the first of which
8760      * contains elements `predicate` returns truthy for, the second of which
8761      * contains elements `predicate` returns falsey for. The predicate is
8762      * invoked with one argument: (value).
8763      *
8764      * @static
8765      * @memberOf _
8766      * @since 3.0.0
8767      * @category Collection
8768      * @param {Array|Object} collection The collection to iterate over.
8769      * @param {Array|Function|Object|string} [predicate=_.identity]
8770      *  The function invoked per iteration.
8771      * @returns {Array} Returns the array of grouped elements.
8772      * @example
8773      *
8774      * var users = [
8775      *   { 'user': 'barney',  'age': 36, 'active': false },
8776      *   { 'user': 'fred',    'age': 40, 'active': true },
8777      *   { 'user': 'pebbles', 'age': 1,  'active': false }
8778      * ];
8779      *
8780      * _.partition(users, function(o) { return o.active; });
8781      * // => objects for [['fred'], ['barney', 'pebbles']]
8782      *
8783      * // The `_.matches` iteratee shorthand.
8784      * _.partition(users, { 'age': 1, 'active': false });
8785      * // => objects for [['pebbles'], ['barney', 'fred']]
8786      *
8787      * // The `_.matchesProperty` iteratee shorthand.
8788      * _.partition(users, ['active', false]);
8789      * // => objects for [['barney', 'pebbles'], ['fred']]
8790      *
8791      * // The `_.property` iteratee shorthand.
8792      * _.partition(users, 'active');
8793      * // => objects for [['fred'], ['barney', 'pebbles']]
8794      */
8795     var partition = createAggregator(function(result, value, key) {
8796       result[key ? 0 : 1].push(value);
8797     }, function() { return [[], []]; });
8798
8799     /**
8800      * Reduces `collection` to a value which is the accumulated result of running
8801      * each element in `collection` thru `iteratee`, where each successive
8802      * invocation is supplied the return value of the previous. If `accumulator`
8803      * is not given, the first element of `collection` is used as the initial
8804      * value. The iteratee is invoked with four arguments:
8805      * (accumulator, value, index|key, collection).
8806      *
8807      * Many lodash methods are guarded to work as iteratees for methods like
8808      * `_.reduce`, `_.reduceRight`, and `_.transform`.
8809      *
8810      * The guarded methods are:
8811      * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
8812      * and `sortBy`
8813      *
8814      * @static
8815      * @memberOf _
8816      * @since 0.1.0
8817      * @category Collection
8818      * @param {Array|Object} collection The collection to iterate over.
8819      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
8820      * @param {*} [accumulator] The initial value.
8821      * @returns {*} Returns the accumulated value.
8822      * @see _.reduceRight
8823      * @example
8824      *
8825      * _.reduce([1, 2], function(sum, n) {
8826      *   return sum + n;
8827      * }, 0);
8828      * // => 3
8829      *
8830      * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
8831      *   (result[value] || (result[value] = [])).push(key);
8832      *   return result;
8833      * }, {});
8834      * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
8835      */
8836     function reduce(collection, iteratee, accumulator) {
8837       var func = isArray(collection) ? arrayReduce : baseReduce,
8838           initAccum = arguments.length < 3;
8839
8840       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
8841     }
8842
8843     /**
8844      * This method is like `_.reduce` except that it iterates over elements of
8845      * `collection` from right to left.
8846      *
8847      * @static
8848      * @memberOf _
8849      * @since 0.1.0
8850      * @category Collection
8851      * @param {Array|Object} collection The collection to iterate over.
8852      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
8853      * @param {*} [accumulator] The initial value.
8854      * @returns {*} Returns the accumulated value.
8855      * @see _.reduce
8856      * @example
8857      *
8858      * var array = [[0, 1], [2, 3], [4, 5]];
8859      *
8860      * _.reduceRight(array, function(flattened, other) {
8861      *   return flattened.concat(other);
8862      * }, []);
8863      * // => [4, 5, 2, 3, 0, 1]
8864      */
8865     function reduceRight(collection, iteratee, accumulator) {
8866       var func = isArray(collection) ? arrayReduceRight : baseReduce,
8867           initAccum = arguments.length < 3;
8868
8869       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
8870     }
8871
8872     /**
8873      * The opposite of `_.filter`; this method returns the elements of `collection`
8874      * that `predicate` does **not** return truthy for.
8875      *
8876      * @static
8877      * @memberOf _
8878      * @since 0.1.0
8879      * @category Collection
8880      * @param {Array|Object} collection The collection to iterate over.
8881      * @param {Array|Function|Object|string} [predicate=_.identity]
8882      *  The function invoked per iteration.
8883      * @returns {Array} Returns the new filtered array.
8884      * @see _.filter
8885      * @example
8886      *
8887      * var users = [
8888      *   { 'user': 'barney', 'age': 36, 'active': false },
8889      *   { 'user': 'fred',   'age': 40, 'active': true }
8890      * ];
8891      *
8892      * _.reject(users, function(o) { return !o.active; });
8893      * // => objects for ['fred']
8894      *
8895      * // The `_.matches` iteratee shorthand.
8896      * _.reject(users, { 'age': 40, 'active': true });
8897      * // => objects for ['barney']
8898      *
8899      * // The `_.matchesProperty` iteratee shorthand.
8900      * _.reject(users, ['active', false]);
8901      * // => objects for ['fred']
8902      *
8903      * // The `_.property` iteratee shorthand.
8904      * _.reject(users, 'active');
8905      * // => objects for ['barney']
8906      */
8907     function reject(collection, predicate) {
8908       var func = isArray(collection) ? arrayFilter : baseFilter;
8909       predicate = getIteratee(predicate, 3);
8910       return func(collection, function(value, index, collection) {
8911         return !predicate(value, index, collection);
8912       });
8913     }
8914
8915     /**
8916      * Gets a random element from `collection`.
8917      *
8918      * @static
8919      * @memberOf _
8920      * @since 2.0.0
8921      * @category Collection
8922      * @param {Array|Object} collection The collection to sample.
8923      * @returns {*} Returns the random element.
8924      * @example
8925      *
8926      * _.sample([1, 2, 3, 4]);
8927      * // => 2
8928      */
8929     function sample(collection) {
8930       var array = isArrayLike(collection) ? collection : values(collection),
8931           length = array.length;
8932
8933       return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
8934     }
8935
8936     /**
8937      * Gets `n` random elements at unique keys from `collection` up to the
8938      * size of `collection`.
8939      *
8940      * @static
8941      * @memberOf _
8942      * @since 4.0.0
8943      * @category Collection
8944      * @param {Array|Object} collection The collection to sample.
8945      * @param {number} [n=1] The number of elements to sample.
8946      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8947      * @returns {Array} Returns the random elements.
8948      * @example
8949      *
8950      * _.sampleSize([1, 2, 3], 2);
8951      * // => [3, 1]
8952      *
8953      * _.sampleSize([1, 2, 3], 4);
8954      * // => [2, 3, 1]
8955      */
8956     function sampleSize(collection, n, guard) {
8957       var index = -1,
8958           result = toArray(collection),
8959           length = result.length,
8960           lastIndex = length - 1;
8961
8962       if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
8963         n = 1;
8964       } else {
8965         n = baseClamp(toInteger(n), 0, length);
8966       }
8967       while (++index < n) {
8968         var rand = baseRandom(index, lastIndex),
8969             value = result[rand];
8970
8971         result[rand] = result[index];
8972         result[index] = value;
8973       }
8974       result.length = n;
8975       return result;
8976     }
8977
8978     /**
8979      * Creates an array of shuffled values, using a version of the
8980      * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
8981      *
8982      * @static
8983      * @memberOf _
8984      * @since 0.1.0
8985      * @category Collection
8986      * @param {Array|Object} collection The collection to shuffle.
8987      * @returns {Array} Returns the new shuffled array.
8988      * @example
8989      *
8990      * _.shuffle([1, 2, 3, 4]);
8991      * // => [4, 1, 3, 2]
8992      */
8993     function shuffle(collection) {
8994       return sampleSize(collection, MAX_ARRAY_LENGTH);
8995     }
8996
8997     /**
8998      * Gets the size of `collection` by returning its length for array-like
8999      * values or the number of own enumerable string keyed properties for objects.
9000      *
9001      * @static
9002      * @memberOf _
9003      * @since 0.1.0
9004      * @category Collection
9005      * @param {Array|Object} collection The collection to inspect.
9006      * @returns {number} Returns the collection size.
9007      * @example
9008      *
9009      * _.size([1, 2, 3]);
9010      * // => 3
9011      *
9012      * _.size({ 'a': 1, 'b': 2 });
9013      * // => 2
9014      *
9015      * _.size('pebbles');
9016      * // => 7
9017      */
9018     function size(collection) {
9019       if (collection == null) {
9020         return 0;
9021       }
9022       if (isArrayLike(collection)) {
9023         var result = collection.length;
9024         return (result && isString(collection)) ? stringSize(collection) : result;
9025       }
9026       if (isObjectLike(collection)) {
9027         var tag = getTag(collection);
9028         if (tag == mapTag || tag == setTag) {
9029           return collection.size;
9030         }
9031       }
9032       return keys(collection).length;
9033     }
9034
9035     /**
9036      * Checks if `predicate` returns truthy for **any** element of `collection`.
9037      * Iteration is stopped once `predicate` returns truthy. The predicate is
9038      * invoked with three arguments: (value, index|key, collection).
9039      *
9040      * @static
9041      * @memberOf _
9042      * @since 0.1.0
9043      * @category Collection
9044      * @param {Array|Object} collection The collection to iterate over.
9045      * @param {Array|Function|Object|string} [predicate=_.identity]
9046      *  The function invoked per iteration.
9047      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9048      * @returns {boolean} Returns `true` if any element passes the predicate check,
9049      *  else `false`.
9050      * @example
9051      *
9052      * _.some([null, 0, 'yes', false], Boolean);
9053      * // => true
9054      *
9055      * var users = [
9056      *   { 'user': 'barney', 'active': true },
9057      *   { 'user': 'fred',   'active': false }
9058      * ];
9059      *
9060      * // The `_.matches` iteratee shorthand.
9061      * _.some(users, { 'user': 'barney', 'active': false });
9062      * // => false
9063      *
9064      * // The `_.matchesProperty` iteratee shorthand.
9065      * _.some(users, ['active', false]);
9066      * // => true
9067      *
9068      * // The `_.property` iteratee shorthand.
9069      * _.some(users, 'active');
9070      * // => true
9071      */
9072     function some(collection, predicate, guard) {
9073       var func = isArray(collection) ? arraySome : baseSome;
9074       if (guard && isIterateeCall(collection, predicate, guard)) {
9075         predicate = undefined;
9076       }
9077       return func(collection, getIteratee(predicate, 3));
9078     }
9079
9080     /**
9081      * Creates an array of elements, sorted in ascending order by the results of
9082      * running each element in a collection thru each iteratee. This method
9083      * performs a stable sort, that is, it preserves the original sort order of
9084      * equal elements. The iteratees are invoked with one argument: (value).
9085      *
9086      * @static
9087      * @memberOf _
9088      * @since 0.1.0
9089      * @category Collection
9090      * @param {Array|Object} collection The collection to iterate over.
9091      * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
9092      *  [iteratees=[_.identity]] The iteratees to sort by.
9093      * @returns {Array} Returns the new sorted array.
9094      * @example
9095      *
9096      * var users = [
9097      *   { 'user': 'fred',   'age': 48 },
9098      *   { 'user': 'barney', 'age': 36 },
9099      *   { 'user': 'fred',   'age': 40 },
9100      *   { 'user': 'barney', 'age': 34 }
9101      * ];
9102      *
9103      * _.sortBy(users, function(o) { return o.user; });
9104      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9105      *
9106      * _.sortBy(users, ['user', 'age']);
9107      * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
9108      *
9109      * _.sortBy(users, 'user', function(o) {
9110      *   return Math.floor(o.age / 10);
9111      * });
9112      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9113      */
9114     var sortBy = rest(function(collection, iteratees) {
9115       if (collection == null) {
9116         return [];
9117       }
9118       var length = iteratees.length;
9119       if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
9120         iteratees = [];
9121       } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
9122         iteratees = [iteratees[0]];
9123       }
9124       iteratees = (iteratees.length == 1 && isArray(iteratees[0]))
9125         ? iteratees[0]
9126         : baseFlatten(iteratees, 1, isFlattenableIteratee);
9127
9128       return baseOrderBy(collection, iteratees, []);
9129     });
9130
9131     /*------------------------------------------------------------------------*/
9132
9133     /**
9134      * Gets the timestamp of the number of milliseconds that have elapsed since
9135      * the Unix epoch (1 January 1970 00:00:00 UTC).
9136      *
9137      * @static
9138      * @memberOf _
9139      * @since 2.4.0
9140      * @type {Function}
9141      * @category Date
9142      * @returns {number} Returns the timestamp.
9143      * @example
9144      *
9145      * _.defer(function(stamp) {
9146      *   console.log(_.now() - stamp);
9147      * }, _.now());
9148      * // => Logs the number of milliseconds it took for the deferred function to be invoked.
9149      */
9150     var now = Date.now;
9151
9152     /*------------------------------------------------------------------------*/
9153
9154     /**
9155      * The opposite of `_.before`; this method creates a function that invokes
9156      * `func` once it's called `n` or more times.
9157      *
9158      * @static
9159      * @memberOf _
9160      * @since 0.1.0
9161      * @category Function
9162      * @param {number} n The number of calls before `func` is invoked.
9163      * @param {Function} func The function to restrict.
9164      * @returns {Function} Returns the new restricted function.
9165      * @example
9166      *
9167      * var saves = ['profile', 'settings'];
9168      *
9169      * var done = _.after(saves.length, function() {
9170      *   console.log('done saving!');
9171      * });
9172      *
9173      * _.forEach(saves, function(type) {
9174      *   asyncSave({ 'type': type, 'complete': done });
9175      * });
9176      * // => Logs 'done saving!' after the two async saves have completed.
9177      */
9178     function after(n, func) {
9179       if (typeof func != 'function') {
9180         throw new TypeError(FUNC_ERROR_TEXT);
9181       }
9182       n = toInteger(n);
9183       return function() {
9184         if (--n < 1) {
9185           return func.apply(this, arguments);
9186         }
9187       };
9188     }
9189
9190     /**
9191      * Creates a function that invokes `func`, with up to `n` arguments,
9192      * ignoring any additional arguments.
9193      *
9194      * @static
9195      * @memberOf _
9196      * @since 3.0.0
9197      * @category Function
9198      * @param {Function} func The function to cap arguments for.
9199      * @param {number} [n=func.length] The arity cap.
9200      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9201      * @returns {Function} Returns the new function.
9202      * @example
9203      *
9204      * _.map(['6', '8', '10'], _.ary(parseInt, 1));
9205      * // => [6, 8, 10]
9206      */
9207     function ary(func, n, guard) {
9208       n = guard ? undefined : n;
9209       n = (func && n == null) ? func.length : n;
9210       return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
9211     }
9212
9213     /**
9214      * Creates a function that invokes `func`, with the `this` binding and arguments
9215      * of the created function, while it's called less than `n` times. Subsequent
9216      * calls to the created function return the result of the last `func` invocation.
9217      *
9218      * @static
9219      * @memberOf _
9220      * @since 3.0.0
9221      * @category Function
9222      * @param {number} n The number of calls at which `func` is no longer invoked.
9223      * @param {Function} func The function to restrict.
9224      * @returns {Function} Returns the new restricted function.
9225      * @example
9226      *
9227      * jQuery(element).on('click', _.before(5, addContactToList));
9228      * // => allows adding up to 4 contacts to the list
9229      */
9230     function before(n, func) {
9231       var result;
9232       if (typeof func != 'function') {
9233         throw new TypeError(FUNC_ERROR_TEXT);
9234       }
9235       n = toInteger(n);
9236       return function() {
9237         if (--n > 0) {
9238           result = func.apply(this, arguments);
9239         }
9240         if (n <= 1) {
9241           func = undefined;
9242         }
9243         return result;
9244       };
9245     }
9246
9247     /**
9248      * Creates a function that invokes `func` with the `this` binding of `thisArg`
9249      * and `partials` prepended to the arguments it receives.
9250      *
9251      * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
9252      * may be used as a placeholder for partially applied arguments.
9253      *
9254      * **Note:** Unlike native `Function#bind` this method doesn't set the "length"
9255      * property of bound functions.
9256      *
9257      * @static
9258      * @memberOf _
9259      * @since 0.1.0
9260      * @category Function
9261      * @param {Function} func The function to bind.
9262      * @param {*} thisArg The `this` binding of `func`.
9263      * @param {...*} [partials] The arguments to be partially applied.
9264      * @returns {Function} Returns the new bound function.
9265      * @example
9266      *
9267      * var greet = function(greeting, punctuation) {
9268      *   return greeting + ' ' + this.user + punctuation;
9269      * };
9270      *
9271      * var object = { 'user': 'fred' };
9272      *
9273      * var bound = _.bind(greet, object, 'hi');
9274      * bound('!');
9275      * // => 'hi fred!'
9276      *
9277      * // Bound with placeholders.
9278      * var bound = _.bind(greet, object, _, '!');
9279      * bound('hi');
9280      * // => 'hi fred!'
9281      */
9282     var bind = rest(function(func, thisArg, partials) {
9283       var bitmask = BIND_FLAG;
9284       if (partials.length) {
9285         var holders = replaceHolders(partials, getPlaceholder(bind));
9286         bitmask |= PARTIAL_FLAG;
9287       }
9288       return createWrapper(func, bitmask, thisArg, partials, holders);
9289     });
9290
9291     /**
9292      * Creates a function that invokes the method at `object[key]` with `partials`
9293      * prepended to the arguments it receives.
9294      *
9295      * This method differs from `_.bind` by allowing bound functions to reference
9296      * methods that may be redefined or don't yet exist. See
9297      * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
9298      * for more details.
9299      *
9300      * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
9301      * builds, may be used as a placeholder for partially applied arguments.
9302      *
9303      * @static
9304      * @memberOf _
9305      * @since 0.10.0
9306      * @category Function
9307      * @param {Object} object The object to invoke the method on.
9308      * @param {string} key The key of the method.
9309      * @param {...*} [partials] The arguments to be partially applied.
9310      * @returns {Function} Returns the new bound function.
9311      * @example
9312      *
9313      * var object = {
9314      *   'user': 'fred',
9315      *   'greet': function(greeting, punctuation) {
9316      *     return greeting + ' ' + this.user + punctuation;
9317      *   }
9318      * };
9319      *
9320      * var bound = _.bindKey(object, 'greet', 'hi');
9321      * bound('!');
9322      * // => 'hi fred!'
9323      *
9324      * object.greet = function(greeting, punctuation) {
9325      *   return greeting + 'ya ' + this.user + punctuation;
9326      * };
9327      *
9328      * bound('!');
9329      * // => 'hiya fred!'
9330      *
9331      * // Bound with placeholders.
9332      * var bound = _.bindKey(object, 'greet', _, '!');
9333      * bound('hi');
9334      * // => 'hiya fred!'
9335      */
9336     var bindKey = rest(function(object, key, partials) {
9337       var bitmask = BIND_FLAG | BIND_KEY_FLAG;
9338       if (partials.length) {
9339         var holders = replaceHolders(partials, getPlaceholder(bindKey));
9340         bitmask |= PARTIAL_FLAG;
9341       }
9342       return createWrapper(key, bitmask, object, partials, holders);
9343     });
9344
9345     /**
9346      * Creates a function that accepts arguments of `func` and either invokes
9347      * `func` returning its result, if at least `arity` number of arguments have
9348      * been provided, or returns a function that accepts the remaining `func`
9349      * arguments, and so on. The arity of `func` may be specified if `func.length`
9350      * is not sufficient.
9351      *
9352      * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
9353      * may be used as a placeholder for provided arguments.
9354      *
9355      * **Note:** This method doesn't set the "length" property of curried functions.
9356      *
9357      * @static
9358      * @memberOf _
9359      * @since 2.0.0
9360      * @category Function
9361      * @param {Function} func The function to curry.
9362      * @param {number} [arity=func.length] The arity of `func`.
9363      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9364      * @returns {Function} Returns the new curried function.
9365      * @example
9366      *
9367      * var abc = function(a, b, c) {
9368      *   return [a, b, c];
9369      * };
9370      *
9371      * var curried = _.curry(abc);
9372      *
9373      * curried(1)(2)(3);
9374      * // => [1, 2, 3]
9375      *
9376      * curried(1, 2)(3);
9377      * // => [1, 2, 3]
9378      *
9379      * curried(1, 2, 3);
9380      * // => [1, 2, 3]
9381      *
9382      * // Curried with placeholders.
9383      * curried(1)(_, 3)(2);
9384      * // => [1, 2, 3]
9385      */
9386     function curry(func, arity, guard) {
9387       arity = guard ? undefined : arity;
9388       var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
9389       result.placeholder = curry.placeholder;
9390       return result;
9391     }
9392
9393     /**
9394      * This method is like `_.curry` except that arguments are applied to `func`
9395      * in the manner of `_.partialRight` instead of `_.partial`.
9396      *
9397      * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
9398      * builds, may be used as a placeholder for provided arguments.
9399      *
9400      * **Note:** This method doesn't set the "length" property of curried functions.
9401      *
9402      * @static
9403      * @memberOf _
9404      * @since 3.0.0
9405      * @category Function
9406      * @param {Function} func The function to curry.
9407      * @param {number} [arity=func.length] The arity of `func`.
9408      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9409      * @returns {Function} Returns the new curried function.
9410      * @example
9411      *
9412      * var abc = function(a, b, c) {
9413      *   return [a, b, c];
9414      * };
9415      *
9416      * var curried = _.curryRight(abc);
9417      *
9418      * curried(3)(2)(1);
9419      * // => [1, 2, 3]
9420      *
9421      * curried(2, 3)(1);
9422      * // => [1, 2, 3]
9423      *
9424      * curried(1, 2, 3);
9425      * // => [1, 2, 3]
9426      *
9427      * // Curried with placeholders.
9428      * curried(3)(1, _)(2);
9429      * // => [1, 2, 3]
9430      */
9431     function curryRight(func, arity, guard) {
9432       arity = guard ? undefined : arity;
9433       var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
9434       result.placeholder = curryRight.placeholder;
9435       return result;
9436     }
9437
9438     /**
9439      * Creates a debounced function that delays invoking `func` until after `wait`
9440      * milliseconds have elapsed since the last time the debounced function was
9441      * invoked. The debounced function comes with a `cancel` method to cancel
9442      * delayed `func` invocations and a `flush` method to immediately invoke them.
9443      * Provide an options object to indicate whether `func` should be invoked on
9444      * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
9445      * with the last arguments provided to the debounced function. Subsequent calls
9446      * to the debounced function return the result of the last `func` invocation.
9447      *
9448      * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
9449      * on the trailing edge of the timeout only if the debounced function is
9450      * invoked more than once during the `wait` timeout.
9451      *
9452      * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
9453      * for details over the differences between `_.debounce` and `_.throttle`.
9454      *
9455      * @static
9456      * @memberOf _
9457      * @since 0.1.0
9458      * @category Function
9459      * @param {Function} func The function to debounce.
9460      * @param {number} [wait=0] The number of milliseconds to delay.
9461      * @param {Object} [options={}] The options object.
9462      * @param {boolean} [options.leading=false]
9463      *  Specify invoking on the leading edge of the timeout.
9464      * @param {number} [options.maxWait]
9465      *  The maximum time `func` is allowed to be delayed before it's invoked.
9466      * @param {boolean} [options.trailing=true]
9467      *  Specify invoking on the trailing edge of the timeout.
9468      * @returns {Function} Returns the new debounced function.
9469      * @example
9470      *
9471      * // Avoid costly calculations while the window size is in flux.
9472      * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
9473      *
9474      * // Invoke `sendMail` when clicked, debouncing subsequent calls.
9475      * jQuery(element).on('click', _.debounce(sendMail, 300, {
9476      *   'leading': true,
9477      *   'trailing': false
9478      * }));
9479      *
9480      * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
9481      * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
9482      * var source = new EventSource('/stream');
9483      * jQuery(source).on('message', debounced);
9484      *
9485      * // Cancel the trailing debounced invocation.
9486      * jQuery(window).on('popstate', debounced.cancel);
9487      */
9488     function debounce(func, wait, options) {
9489       var lastArgs,
9490           lastThis,
9491           maxWait,
9492           result,
9493           timerId,
9494           lastCallTime = 0,
9495           lastInvokeTime = 0,
9496           leading = false,
9497           maxing = false,
9498           trailing = true;
9499
9500       if (typeof func != 'function') {
9501         throw new TypeError(FUNC_ERROR_TEXT);
9502       }
9503       wait = toNumber(wait) || 0;
9504       if (isObject(options)) {
9505         leading = !!options.leading;
9506         maxing = 'maxWait' in options;
9507         maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
9508         trailing = 'trailing' in options ? !!options.trailing : trailing;
9509       }
9510
9511       function invokeFunc(time) {
9512         var args = lastArgs,
9513             thisArg = lastThis;
9514
9515         lastArgs = lastThis = undefined;
9516         lastInvokeTime = time;
9517         result = func.apply(thisArg, args);
9518         return result;
9519       }
9520
9521       function leadingEdge(time) {
9522         // Reset any `maxWait` timer.
9523         lastInvokeTime = time;
9524         // Start the timer for the trailing edge.
9525         timerId = setTimeout(timerExpired, wait);
9526         // Invoke the leading edge.
9527         return leading ? invokeFunc(time) : result;
9528       }
9529
9530       function remainingWait(time) {
9531         var timeSinceLastCall = time - lastCallTime,
9532             timeSinceLastInvoke = time - lastInvokeTime,
9533             result = wait - timeSinceLastCall;
9534
9535         return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
9536       }
9537
9538       function shouldInvoke(time) {
9539         var timeSinceLastCall = time - lastCallTime,
9540             timeSinceLastInvoke = time - lastInvokeTime;
9541
9542         // Either this is the first call, activity has stopped and we're at the
9543         // trailing edge, the system time has gone backwards and we're treating
9544         // it as the trailing edge, or we've hit the `maxWait` limit.
9545         return (!lastCallTime || (timeSinceLastCall >= wait) ||
9546           (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
9547       }
9548
9549       function timerExpired() {
9550         var time = now();
9551         if (shouldInvoke(time)) {
9552           return trailingEdge(time);
9553         }
9554         // Restart the timer.
9555         timerId = setTimeout(timerExpired, remainingWait(time));
9556       }
9557
9558       function trailingEdge(time) {
9559         clearTimeout(timerId);
9560         timerId = undefined;
9561
9562         // Only invoke if we have `lastArgs` which means `func` has been
9563         // debounced at least once.
9564         if (trailing && lastArgs) {
9565           return invokeFunc(time);
9566         }
9567         lastArgs = lastThis = undefined;
9568         return result;
9569       }
9570
9571       function cancel() {
9572         if (timerId !== undefined) {
9573           clearTimeout(timerId);
9574         }
9575         lastCallTime = lastInvokeTime = 0;
9576         lastArgs = lastThis = timerId = undefined;
9577       }
9578
9579       function flush() {
9580         return timerId === undefined ? result : trailingEdge(now());
9581       }
9582
9583       function debounced() {
9584         var time = now(),
9585             isInvoking = shouldInvoke(time);
9586
9587         lastArgs = arguments;
9588         lastThis = this;
9589         lastCallTime = time;
9590
9591         if (isInvoking) {
9592           if (timerId === undefined) {
9593             return leadingEdge(lastCallTime);
9594           }
9595           if (maxing) {
9596             // Handle invocations in a tight loop.
9597             clearTimeout(timerId);
9598             timerId = setTimeout(timerExpired, wait);
9599             return invokeFunc(lastCallTime);
9600           }
9601         }
9602         if (timerId === undefined) {
9603           timerId = setTimeout(timerExpired, wait);
9604         }
9605         return result;
9606       }
9607       debounced.cancel = cancel;
9608       debounced.flush = flush;
9609       return debounced;
9610     }
9611
9612     /**
9613      * Defers invoking the `func` until the current call stack has cleared. Any
9614      * additional arguments are provided to `func` when it's invoked.
9615      *
9616      * @static
9617      * @memberOf _
9618      * @since 0.1.0
9619      * @category Function
9620      * @param {Function} func The function to defer.
9621      * @param {...*} [args] The arguments to invoke `func` with.
9622      * @returns {number} Returns the timer id.
9623      * @example
9624      *
9625      * _.defer(function(text) {
9626      *   console.log(text);
9627      * }, 'deferred');
9628      * // => Logs 'deferred' after one or more milliseconds.
9629      */
9630     var defer = rest(function(func, args) {
9631       return baseDelay(func, 1, args);
9632     });
9633
9634     /**
9635      * Invokes `func` after `wait` milliseconds. Any additional arguments are
9636      * provided to `func` when it's invoked.
9637      *
9638      * @static
9639      * @memberOf _
9640      * @since 0.1.0
9641      * @category Function
9642      * @param {Function} func The function to delay.
9643      * @param {number} wait The number of milliseconds to delay invocation.
9644      * @param {...*} [args] The arguments to invoke `func` with.
9645      * @returns {number} Returns the timer id.
9646      * @example
9647      *
9648      * _.delay(function(text) {
9649      *   console.log(text);
9650      * }, 1000, 'later');
9651      * // => Logs 'later' after one second.
9652      */
9653     var delay = rest(function(func, wait, args) {
9654       return baseDelay(func, toNumber(wait) || 0, args);
9655     });
9656
9657     /**
9658      * Creates a function that invokes `func` with arguments reversed.
9659      *
9660      * @static
9661      * @memberOf _
9662      * @since 4.0.0
9663      * @category Function
9664      * @param {Function} func The function to flip arguments for.
9665      * @returns {Function} Returns the new function.
9666      * @example
9667      *
9668      * var flipped = _.flip(function() {
9669      *   return _.toArray(arguments);
9670      * });
9671      *
9672      * flipped('a', 'b', 'c', 'd');
9673      * // => ['d', 'c', 'b', 'a']
9674      */
9675     function flip(func) {
9676       return createWrapper(func, FLIP_FLAG);
9677     }
9678
9679     /**
9680      * Creates a function that memoizes the result of `func`. If `resolver` is
9681      * provided, it determines the cache key for storing the result based on the
9682      * arguments provided to the memoized function. By default, the first argument
9683      * provided to the memoized function is used as the map cache key. The `func`
9684      * is invoked with the `this` binding of the memoized function.
9685      *
9686      * **Note:** The cache is exposed as the `cache` property on the memoized
9687      * function. Its creation may be customized by replacing the `_.memoize.Cache`
9688      * constructor with one whose instances implement the
9689      * [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
9690      * method interface of `delete`, `get`, `has`, and `set`.
9691      *
9692      * @static
9693      * @memberOf _
9694      * @since 0.1.0
9695      * @category Function
9696      * @param {Function} func The function to have its output memoized.
9697      * @param {Function} [resolver] The function to resolve the cache key.
9698      * @returns {Function} Returns the new memoizing function.
9699      * @example
9700      *
9701      * var object = { 'a': 1, 'b': 2 };
9702      * var other = { 'c': 3, 'd': 4 };
9703      *
9704      * var values = _.memoize(_.values);
9705      * values(object);
9706      * // => [1, 2]
9707      *
9708      * values(other);
9709      * // => [3, 4]
9710      *
9711      * object.a = 2;
9712      * values(object);
9713      * // => [1, 2]
9714      *
9715      * // Modify the result cache.
9716      * values.cache.set(object, ['a', 'b']);
9717      * values(object);
9718      * // => ['a', 'b']
9719      *
9720      * // Replace `_.memoize.Cache`.
9721      * _.memoize.Cache = WeakMap;
9722      */
9723     function memoize(func, resolver) {
9724       if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
9725         throw new TypeError(FUNC_ERROR_TEXT);
9726       }
9727       var memoized = function() {
9728         var args = arguments,
9729             key = resolver ? resolver.apply(this, args) : args[0],
9730             cache = memoized.cache;
9731
9732         if (cache.has(key)) {
9733           return cache.get(key);
9734         }
9735         var result = func.apply(this, args);
9736         memoized.cache = cache.set(key, result);
9737         return result;
9738       };
9739       memoized.cache = new (memoize.Cache || MapCache);
9740       return memoized;
9741     }
9742
9743     // Assign cache to `_.memoize`.
9744     memoize.Cache = MapCache;
9745
9746     /**
9747      * Creates a function that negates the result of the predicate `func`. The
9748      * `func` predicate is invoked with the `this` binding and arguments of the
9749      * created function.
9750      *
9751      * @static
9752      * @memberOf _
9753      * @since 3.0.0
9754      * @category Function
9755      * @param {Function} predicate The predicate to negate.
9756      * @returns {Function} Returns the new function.
9757      * @example
9758      *
9759      * function isEven(n) {
9760      *   return n % 2 == 0;
9761      * }
9762      *
9763      * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
9764      * // => [1, 3, 5]
9765      */
9766     function negate(predicate) {
9767       if (typeof predicate != 'function') {
9768         throw new TypeError(FUNC_ERROR_TEXT);
9769       }
9770       return function() {
9771         return !predicate.apply(this, arguments);
9772       };
9773     }
9774
9775     /**
9776      * Creates a function that is restricted to invoking `func` once. Repeat calls
9777      * to the function return the value of the first invocation. The `func` is
9778      * invoked with the `this` binding and arguments of the created function.
9779      *
9780      * @static
9781      * @memberOf _
9782      * @since 0.1.0
9783      * @category Function
9784      * @param {Function} func The function to restrict.
9785      * @returns {Function} Returns the new restricted function.
9786      * @example
9787      *
9788      * var initialize = _.once(createApplication);
9789      * initialize();
9790      * initialize();
9791      * // `initialize` invokes `createApplication` once
9792      */
9793     function once(func) {
9794       return before(2, func);
9795     }
9796
9797     /**
9798      * Creates a function that invokes `func` with arguments transformed by
9799      * corresponding `transforms`.
9800      *
9801      * @static
9802      * @since 4.0.0
9803      * @memberOf _
9804      * @category Function
9805      * @param {Function} func The function to wrap.
9806      * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
9807      *  [transforms[_.identity]] The functions to transform.
9808      * @returns {Function} Returns the new function.
9809      * @example
9810      *
9811      * function doubled(n) {
9812      *   return n * 2;
9813      * }
9814      *
9815      * function square(n) {
9816      *   return n * n;
9817      * }
9818      *
9819      * var func = _.overArgs(function(x, y) {
9820      *   return [x, y];
9821      * }, square, doubled);
9822      *
9823      * func(9, 3);
9824      * // => [81, 6]
9825      *
9826      * func(10, 5);
9827      * // => [100, 10]
9828      */
9829     var overArgs = rest(function(func, transforms) {
9830       transforms = (transforms.length == 1 && isArray(transforms[0]))
9831         ? arrayMap(transforms[0], baseUnary(getIteratee()))
9832         : arrayMap(baseFlatten(transforms, 1, isFlattenableIteratee), baseUnary(getIteratee()));
9833
9834       var funcsLength = transforms.length;
9835       return rest(function(args) {
9836         var index = -1,
9837             length = nativeMin(args.length, funcsLength);
9838
9839         while (++index < length) {
9840           args[index] = transforms[index].call(this, args[index]);
9841         }
9842         return apply(func, this, args);
9843       });
9844     });
9845
9846     /**
9847      * Creates a function that invokes `func` with `partials` prepended to the
9848      * arguments it receives. This method is like `_.bind` except it does **not**
9849      * alter the `this` binding.
9850      *
9851      * The `_.partial.placeholder` value, which defaults to `_` in monolithic
9852      * builds, may be used as a placeholder for partially applied arguments.
9853      *
9854      * **Note:** This method doesn't set the "length" property of partially
9855      * applied functions.
9856      *
9857      * @static
9858      * @memberOf _
9859      * @since 0.2.0
9860      * @category Function
9861      * @param {Function} func The function to partially apply arguments to.
9862      * @param {...*} [partials] The arguments to be partially applied.
9863      * @returns {Function} Returns the new partially applied function.
9864      * @example
9865      *
9866      * var greet = function(greeting, name) {
9867      *   return greeting + ' ' + name;
9868      * };
9869      *
9870      * var sayHelloTo = _.partial(greet, 'hello');
9871      * sayHelloTo('fred');
9872      * // => 'hello fred'
9873      *
9874      * // Partially applied with placeholders.
9875      * var greetFred = _.partial(greet, _, 'fred');
9876      * greetFred('hi');
9877      * // => 'hi fred'
9878      */
9879     var partial = rest(function(func, partials) {
9880       var holders = replaceHolders(partials, getPlaceholder(partial));
9881       return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
9882     });
9883
9884     /**
9885      * This method is like `_.partial` except that partially applied arguments
9886      * are appended to the arguments it receives.
9887      *
9888      * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
9889      * builds, may be used as a placeholder for partially applied arguments.
9890      *
9891      * **Note:** This method doesn't set the "length" property of partially
9892      * applied functions.
9893      *
9894      * @static
9895      * @memberOf _
9896      * @since 1.0.0
9897      * @category Function
9898      * @param {Function} func The function to partially apply arguments to.
9899      * @param {...*} [partials] The arguments to be partially applied.
9900      * @returns {Function} Returns the new partially applied function.
9901      * @example
9902      *
9903      * var greet = function(greeting, name) {
9904      *   return greeting + ' ' + name;
9905      * };
9906      *
9907      * var greetFred = _.partialRight(greet, 'fred');
9908      * greetFred('hi');
9909      * // => 'hi fred'
9910      *
9911      * // Partially applied with placeholders.
9912      * var sayHelloTo = _.partialRight(greet, 'hello', _);
9913      * sayHelloTo('fred');
9914      * // => 'hello fred'
9915      */
9916     var partialRight = rest(function(func, partials) {
9917       var holders = replaceHolders(partials, getPlaceholder(partialRight));
9918       return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
9919     });
9920
9921     /**
9922      * Creates a function that invokes `func` with arguments arranged according
9923      * to the specified `indexes` where the argument value at the first index is
9924      * provided as the first argument, the argument value at the second index is
9925      * provided as the second argument, and so on.
9926      *
9927      * @static
9928      * @memberOf _
9929      * @since 3.0.0
9930      * @category Function
9931      * @param {Function} func The function to rearrange arguments for.
9932      * @param {...(number|number[])} indexes The arranged argument indexes.
9933      * @returns {Function} Returns the new function.
9934      * @example
9935      *
9936      * var rearged = _.rearg(function(a, b, c) {
9937      *   return [a, b, c];
9938      * }, 2, 0, 1);
9939      *
9940      * rearged('b', 'c', 'a')
9941      * // => ['a', 'b', 'c']
9942      */
9943     var rearg = rest(function(func, indexes) {
9944       return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1));
9945     });
9946
9947     /**
9948      * Creates a function that invokes `func` with the `this` binding of the
9949      * created function and arguments from `start` and beyond provided as
9950      * an array.
9951      *
9952      * **Note:** This method is based on the
9953      * [rest parameter](https://mdn.io/rest_parameters).
9954      *
9955      * @static
9956      * @memberOf _
9957      * @since 4.0.0
9958      * @category Function
9959      * @param {Function} func The function to apply a rest parameter to.
9960      * @param {number} [start=func.length-1] The start position of the rest parameter.
9961      * @returns {Function} Returns the new function.
9962      * @example
9963      *
9964      * var say = _.rest(function(what, names) {
9965      *   return what + ' ' + _.initial(names).join(', ') +
9966      *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
9967      * });
9968      *
9969      * say('hello', 'fred', 'barney', 'pebbles');
9970      * // => 'hello fred, barney, & pebbles'
9971      */
9972     function rest(func, start) {
9973       if (typeof func != 'function') {
9974         throw new TypeError(FUNC_ERROR_TEXT);
9975       }
9976       start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
9977       return function() {
9978         var args = arguments,
9979             index = -1,
9980             length = nativeMax(args.length - start, 0),
9981             array = Array(length);
9982
9983         while (++index < length) {
9984           array[index] = args[start + index];
9985         }
9986         switch (start) {
9987           case 0: return func.call(this, array);
9988           case 1: return func.call(this, args[0], array);
9989           case 2: return func.call(this, args[0], args[1], array);
9990         }
9991         var otherArgs = Array(start + 1);
9992         index = -1;
9993         while (++index < start) {
9994           otherArgs[index] = args[index];
9995         }
9996         otherArgs[start] = array;
9997         return apply(func, this, otherArgs);
9998       };
9999     }
10000
10001     /**
10002      * Creates a function that invokes `func` with the `this` binding of the
10003      * create function and an array of arguments much like
10004      * [`Function#apply`](http://www.ecma-international.org/ecma-262/6.0/#sec-function.prototype.apply).
10005      *
10006      * **Note:** This method is based on the
10007      * [spread operator](https://mdn.io/spread_operator).
10008      *
10009      * @static
10010      * @memberOf _
10011      * @since 3.2.0
10012      * @category Function
10013      * @param {Function} func The function to spread arguments over.
10014      * @param {number} [start=0] The start position of the spread.
10015      * @returns {Function} Returns the new function.
10016      * @example
10017      *
10018      * var say = _.spread(function(who, what) {
10019      *   return who + ' says ' + what;
10020      * });
10021      *
10022      * say(['fred', 'hello']);
10023      * // => 'fred says hello'
10024      *
10025      * var numbers = Promise.all([
10026      *   Promise.resolve(40),
10027      *   Promise.resolve(36)
10028      * ]);
10029      *
10030      * numbers.then(_.spread(function(x, y) {
10031      *   return x + y;
10032      * }));
10033      * // => a Promise of 76
10034      */
10035     function spread(func, start) {
10036       if (typeof func != 'function') {
10037         throw new TypeError(FUNC_ERROR_TEXT);
10038       }
10039       start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
10040       return rest(function(args) {
10041         var array = args[start],
10042             otherArgs = castSlice(args, 0, start);
10043
10044         if (array) {
10045           arrayPush(otherArgs, array);
10046         }
10047         return apply(func, this, otherArgs);
10048       });
10049     }
10050
10051     /**
10052      * Creates a throttled function that only invokes `func` at most once per
10053      * every `wait` milliseconds. The throttled function comes with a `cancel`
10054      * method to cancel delayed `func` invocations and a `flush` method to
10055      * immediately invoke them. Provide an options object to indicate whether
10056      * `func` should be invoked on the leading and/or trailing edge of the `wait`
10057      * timeout. The `func` is invoked with the last arguments provided to the
10058      * throttled function. Subsequent calls to the throttled function return the
10059      * result of the last `func` invocation.
10060      *
10061      * **Note:** If `leading` and `trailing` options are `true`, `func` is
10062      * invoked on the trailing edge of the timeout only if the throttled function
10063      * is invoked more than once during the `wait` timeout.
10064      *
10065      * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10066      * for details over the differences between `_.throttle` and `_.debounce`.
10067      *
10068      * @static
10069      * @memberOf _
10070      * @since 0.1.0
10071      * @category Function
10072      * @param {Function} func The function to throttle.
10073      * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
10074      * @param {Object} [options={}] The options object.
10075      * @param {boolean} [options.leading=true]
10076      *  Specify invoking on the leading edge of the timeout.
10077      * @param {boolean} [options.trailing=true]
10078      *  Specify invoking on the trailing edge of the timeout.
10079      * @returns {Function} Returns the new throttled function.
10080      * @example
10081      *
10082      * // Avoid excessively updating the position while scrolling.
10083      * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
10084      *
10085      * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
10086      * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
10087      * jQuery(element).on('click', throttled);
10088      *
10089      * // Cancel the trailing throttled invocation.
10090      * jQuery(window).on('popstate', throttled.cancel);
10091      */
10092     function throttle(func, wait, options) {
10093       var leading = true,
10094           trailing = true;
10095
10096       if (typeof func != 'function') {
10097         throw new TypeError(FUNC_ERROR_TEXT);
10098       }
10099       if (isObject(options)) {
10100         leading = 'leading' in options ? !!options.leading : leading;
10101         trailing = 'trailing' in options ? !!options.trailing : trailing;
10102       }
10103       return debounce(func, wait, {
10104         'leading': leading,
10105         'maxWait': wait,
10106         'trailing': trailing
10107       });
10108     }
10109
10110     /**
10111      * Creates a function that accepts up to one argument, ignoring any
10112      * additional arguments.
10113      *
10114      * @static
10115      * @memberOf _
10116      * @since 4.0.0
10117      * @category Function
10118      * @param {Function} func The function to cap arguments for.
10119      * @returns {Function} Returns the new function.
10120      * @example
10121      *
10122      * _.map(['6', '8', '10'], _.unary(parseInt));
10123      * // => [6, 8, 10]
10124      */
10125     function unary(func) {
10126       return ary(func, 1);
10127     }
10128
10129     /**
10130      * Creates a function that provides `value` to the wrapper function as its
10131      * first argument. Any additional arguments provided to the function are
10132      * appended to those provided to the wrapper function. The wrapper is invoked
10133      * with the `this` binding of the created function.
10134      *
10135      * @static
10136      * @memberOf _
10137      * @since 0.1.0
10138      * @category Function
10139      * @param {*} value The value to wrap.
10140      * @param {Function} [wrapper=identity] The wrapper function.
10141      * @returns {Function} Returns the new function.
10142      * @example
10143      *
10144      * var p = _.wrap(_.escape, function(func, text) {
10145      *   return '<p>' + func(text) + '</p>';
10146      * });
10147      *
10148      * p('fred, barney, & pebbles');
10149      * // => '<p>fred, barney, &amp; pebbles</p>'
10150      */
10151     function wrap(value, wrapper) {
10152       wrapper = wrapper == null ? identity : wrapper;
10153       return partial(wrapper, value);
10154     }
10155
10156     /*------------------------------------------------------------------------*/
10157
10158     /**
10159      * Casts `value` as an array if it's not one.
10160      *
10161      * @static
10162      * @memberOf _
10163      * @since 4.4.0
10164      * @category Lang
10165      * @param {*} value The value to inspect.
10166      * @returns {Array} Returns the cast array.
10167      * @example
10168      *
10169      * _.castArray(1);
10170      * // => [1]
10171      *
10172      * _.castArray({ 'a': 1 });
10173      * // => [{ 'a': 1 }]
10174      *
10175      * _.castArray('abc');
10176      * // => ['abc']
10177      *
10178      * _.castArray(null);
10179      * // => [null]
10180      *
10181      * _.castArray(undefined);
10182      * // => [undefined]
10183      *
10184      * _.castArray();
10185      * // => []
10186      *
10187      * var array = [1, 2, 3];
10188      * console.log(_.castArray(array) === array);
10189      * // => true
10190      */
10191     function castArray() {
10192       if (!arguments.length) {
10193         return [];
10194       }
10195       var value = arguments[0];
10196       return isArray(value) ? value : [value];
10197     }
10198
10199     /**
10200      * Creates a shallow clone of `value`.
10201      *
10202      * **Note:** This method is loosely based on the
10203      * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
10204      * and supports cloning arrays, array buffers, booleans, date objects, maps,
10205      * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
10206      * arrays. The own enumerable properties of `arguments` objects are cloned
10207      * as plain objects. An empty object is returned for uncloneable values such
10208      * as error objects, functions, DOM nodes, and WeakMaps.
10209      *
10210      * @static
10211      * @memberOf _
10212      * @since 0.1.0
10213      * @category Lang
10214      * @param {*} value The value to clone.
10215      * @returns {*} Returns the cloned value.
10216      * @see _.cloneDeep
10217      * @example
10218      *
10219      * var objects = [{ 'a': 1 }, { 'b': 2 }];
10220      *
10221      * var shallow = _.clone(objects);
10222      * console.log(shallow[0] === objects[0]);
10223      * // => true
10224      */
10225     function clone(value) {
10226       return baseClone(value, false, true);
10227     }
10228
10229     /**
10230      * This method is like `_.clone` except that it accepts `customizer` which
10231      * is invoked to produce the cloned value. If `customizer` returns `undefined`,
10232      * cloning is handled by the method instead. The `customizer` is invoked with
10233      * up to four arguments; (value [, index|key, object, stack]).
10234      *
10235      * @static
10236      * @memberOf _
10237      * @since 4.0.0
10238      * @category Lang
10239      * @param {*} value The value to clone.
10240      * @param {Function} [customizer] The function to customize cloning.
10241      * @returns {*} Returns the cloned value.
10242      * @see _.cloneDeepWith
10243      * @example
10244      *
10245      * function customizer(value) {
10246      *   if (_.isElement(value)) {
10247      *     return value.cloneNode(false);
10248      *   }
10249      * }
10250      *
10251      * var el = _.cloneWith(document.body, customizer);
10252      *
10253      * console.log(el === document.body);
10254      * // => false
10255      * console.log(el.nodeName);
10256      * // => 'BODY'
10257      * console.log(el.childNodes.length);
10258      * // => 0
10259      */
10260     function cloneWith(value, customizer) {
10261       return baseClone(value, false, true, customizer);
10262     }
10263
10264     /**
10265      * This method is like `_.clone` except that it recursively clones `value`.
10266      *
10267      * @static
10268      * @memberOf _
10269      * @since 1.0.0
10270      * @category Lang
10271      * @param {*} value The value to recursively clone.
10272      * @returns {*} Returns the deep cloned value.
10273      * @see _.clone
10274      * @example
10275      *
10276      * var objects = [{ 'a': 1 }, { 'b': 2 }];
10277      *
10278      * var deep = _.cloneDeep(objects);
10279      * console.log(deep[0] === objects[0]);
10280      * // => false
10281      */
10282     function cloneDeep(value) {
10283       return baseClone(value, true, true);
10284     }
10285
10286     /**
10287      * This method is like `_.cloneWith` except that it recursively clones `value`.
10288      *
10289      * @static
10290      * @memberOf _
10291      * @since 4.0.0
10292      * @category Lang
10293      * @param {*} value The value to recursively clone.
10294      * @param {Function} [customizer] The function to customize cloning.
10295      * @returns {*} Returns the deep cloned value.
10296      * @see _.cloneWith
10297      * @example
10298      *
10299      * function customizer(value) {
10300      *   if (_.isElement(value)) {
10301      *     return value.cloneNode(true);
10302      *   }
10303      * }
10304      *
10305      * var el = _.cloneDeepWith(document.body, customizer);
10306      *
10307      * console.log(el === document.body);
10308      * // => false
10309      * console.log(el.nodeName);
10310      * // => 'BODY'
10311      * console.log(el.childNodes.length);
10312      * // => 20
10313      */
10314     function cloneDeepWith(value, customizer) {
10315       return baseClone(value, true, true, customizer);
10316     }
10317
10318     /**
10319      * Performs a
10320      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
10321      * comparison between two values to determine if they are equivalent.
10322      *
10323      * @static
10324      * @memberOf _
10325      * @since 4.0.0
10326      * @category Lang
10327      * @param {*} value The value to compare.
10328      * @param {*} other The other value to compare.
10329      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
10330      * @example
10331      *
10332      * var object = { 'user': 'fred' };
10333      * var other = { 'user': 'fred' };
10334      *
10335      * _.eq(object, object);
10336      * // => true
10337      *
10338      * _.eq(object, other);
10339      * // => false
10340      *
10341      * _.eq('a', 'a');
10342      * // => true
10343      *
10344      * _.eq('a', Object('a'));
10345      * // => false
10346      *
10347      * _.eq(NaN, NaN);
10348      * // => true
10349      */
10350     function eq(value, other) {
10351       return value === other || (value !== value && other !== other);
10352     }
10353
10354     /**
10355      * Checks if `value` is greater than `other`.
10356      *
10357      * @static
10358      * @memberOf _
10359      * @since 3.9.0
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 greater than `other`,
10364      *  else `false`.
10365      * @see _.lt
10366      * @example
10367      *
10368      * _.gt(3, 1);
10369      * // => true
10370      *
10371      * _.gt(3, 3);
10372      * // => false
10373      *
10374      * _.gt(1, 3);
10375      * // => false
10376      */
10377     var gt = createRelationalOperation(baseGt);
10378
10379     /**
10380      * Checks if `value` is greater than or equal to `other`.
10381      *
10382      * @static
10383      * @memberOf _
10384      * @since 3.9.0
10385      * @category Lang
10386      * @param {*} value The value to compare.
10387      * @param {*} other The other value to compare.
10388      * @returns {boolean} Returns `true` if `value` is greater than or equal to
10389      *  `other`, else `false`.
10390      * @see _.lte
10391      * @example
10392      *
10393      * _.gte(3, 1);
10394      * // => true
10395      *
10396      * _.gte(3, 3);
10397      * // => true
10398      *
10399      * _.gte(1, 3);
10400      * // => false
10401      */
10402     var gte = createRelationalOperation(function(value, other) {
10403       return value >= other;
10404     });
10405
10406     /**
10407      * Checks if `value` is likely an `arguments` object.
10408      *
10409      * @static
10410      * @memberOf _
10411      * @since 0.1.0
10412      * @category Lang
10413      * @param {*} value The value to check.
10414      * @returns {boolean} Returns `true` if `value` is correctly classified,
10415      *  else `false`.
10416      * @example
10417      *
10418      * _.isArguments(function() { return arguments; }());
10419      * // => true
10420      *
10421      * _.isArguments([1, 2, 3]);
10422      * // => false
10423      */
10424     function isArguments(value) {
10425       // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
10426       return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
10427         (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
10428     }
10429
10430     /**
10431      * Checks if `value` is classified as an `Array` object.
10432      *
10433      * @static
10434      * @memberOf _
10435      * @since 0.1.0
10436      * @type {Function}
10437      * @category Lang
10438      * @param {*} value The value to check.
10439      * @returns {boolean} Returns `true` if `value` is correctly classified,
10440      *  else `false`.
10441      * @example
10442      *
10443      * _.isArray([1, 2, 3]);
10444      * // => true
10445      *
10446      * _.isArray(document.body.children);
10447      * // => false
10448      *
10449      * _.isArray('abc');
10450      * // => false
10451      *
10452      * _.isArray(_.noop);
10453      * // => false
10454      */
10455     var isArray = Array.isArray;
10456
10457     /**
10458      * Checks if `value` is classified as an `ArrayBuffer` object.
10459      *
10460      * @static
10461      * @memberOf _
10462      * @since 4.3.0
10463      * @category Lang
10464      * @param {*} value The value to check.
10465      * @returns {boolean} Returns `true` if `value` is correctly classified,
10466      *  else `false`.
10467      * @example
10468      *
10469      * _.isArrayBuffer(new ArrayBuffer(2));
10470      * // => true
10471      *
10472      * _.isArrayBuffer(new Array(2));
10473      * // => false
10474      */
10475     function isArrayBuffer(value) {
10476       return isObjectLike(value) && objectToString.call(value) == arrayBufferTag;
10477     }
10478
10479     /**
10480      * Checks if `value` is array-like. A value is considered array-like if it's
10481      * not a function and has a `value.length` that's an integer greater than or
10482      * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
10483      *
10484      * @static
10485      * @memberOf _
10486      * @since 4.0.0
10487      * @category Lang
10488      * @param {*} value The value to check.
10489      * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
10490      * @example
10491      *
10492      * _.isArrayLike([1, 2, 3]);
10493      * // => true
10494      *
10495      * _.isArrayLike(document.body.children);
10496      * // => true
10497      *
10498      * _.isArrayLike('abc');
10499      * // => true
10500      *
10501      * _.isArrayLike(_.noop);
10502      * // => false
10503      */
10504     function isArrayLike(value) {
10505       return value != null && isLength(getLength(value)) && !isFunction(value);
10506     }
10507
10508     /**
10509      * This method is like `_.isArrayLike` except that it also checks if `value`
10510      * is an object.
10511      *
10512      * @static
10513      * @memberOf _
10514      * @since 4.0.0
10515      * @category Lang
10516      * @param {*} value The value to check.
10517      * @returns {boolean} Returns `true` if `value` is an array-like object,
10518      *  else `false`.
10519      * @example
10520      *
10521      * _.isArrayLikeObject([1, 2, 3]);
10522      * // => true
10523      *
10524      * _.isArrayLikeObject(document.body.children);
10525      * // => true
10526      *
10527      * _.isArrayLikeObject('abc');
10528      * // => false
10529      *
10530      * _.isArrayLikeObject(_.noop);
10531      * // => false
10532      */
10533     function isArrayLikeObject(value) {
10534       return isObjectLike(value) && isArrayLike(value);
10535     }
10536
10537     /**
10538      * Checks if `value` is classified as a boolean primitive or object.
10539      *
10540      * @static
10541      * @memberOf _
10542      * @since 0.1.0
10543      * @category Lang
10544      * @param {*} value The value to check.
10545      * @returns {boolean} Returns `true` if `value` is correctly classified,
10546      *  else `false`.
10547      * @example
10548      *
10549      * _.isBoolean(false);
10550      * // => true
10551      *
10552      * _.isBoolean(null);
10553      * // => false
10554      */
10555     function isBoolean(value) {
10556       return value === true || value === false ||
10557         (isObjectLike(value) && objectToString.call(value) == boolTag);
10558     }
10559
10560     /**
10561      * Checks if `value` is a buffer.
10562      *
10563      * @static
10564      * @memberOf _
10565      * @since 4.3.0
10566      * @category Lang
10567      * @param {*} value The value to check.
10568      * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
10569      * @example
10570      *
10571      * _.isBuffer(new Buffer(2));
10572      * // => true
10573      *
10574      * _.isBuffer(new Uint8Array(2));
10575      * // => false
10576      */
10577     var isBuffer = !Buffer ? constant(false) : function(value) {
10578       return value instanceof Buffer;
10579     };
10580
10581     /**
10582      * Checks if `value` is classified as a `Date` object.
10583      *
10584      * @static
10585      * @memberOf _
10586      * @since 0.1.0
10587      * @category Lang
10588      * @param {*} value The value to check.
10589      * @returns {boolean} Returns `true` if `value` is correctly classified,
10590      *  else `false`.
10591      * @example
10592      *
10593      * _.isDate(new Date);
10594      * // => true
10595      *
10596      * _.isDate('Mon April 23 2012');
10597      * // => false
10598      */
10599     function isDate(value) {
10600       return isObjectLike(value) && objectToString.call(value) == dateTag;
10601     }
10602
10603     /**
10604      * Checks if `value` is likely a DOM element.
10605      *
10606      * @static
10607      * @memberOf _
10608      * @since 0.1.0
10609      * @category Lang
10610      * @param {*} value The value to check.
10611      * @returns {boolean} Returns `true` if `value` is a DOM element,
10612      *  else `false`.
10613      * @example
10614      *
10615      * _.isElement(document.body);
10616      * // => true
10617      *
10618      * _.isElement('<body>');
10619      * // => false
10620      */
10621     function isElement(value) {
10622       return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
10623     }
10624
10625     /**
10626      * Checks if `value` is an empty object, collection, map, or set.
10627      *
10628      * Objects are considered empty if they have no own enumerable string keyed
10629      * properties.
10630      *
10631      * Array-like values such as `arguments` objects, arrays, buffers, strings, or
10632      * jQuery-like collections are considered empty if they have a `length` of `0`.
10633      * Similarly, maps and sets are considered empty if they have a `size` of `0`.
10634      *
10635      * @static
10636      * @memberOf _
10637      * @since 0.1.0
10638      * @category Lang
10639      * @param {*} value The value to check.
10640      * @returns {boolean} Returns `true` if `value` is empty, else `false`.
10641      * @example
10642      *
10643      * _.isEmpty(null);
10644      * // => true
10645      *
10646      * _.isEmpty(true);
10647      * // => true
10648      *
10649      * _.isEmpty(1);
10650      * // => true
10651      *
10652      * _.isEmpty([1, 2, 3]);
10653      * // => false
10654      *
10655      * _.isEmpty({ 'a': 1 });
10656      * // => false
10657      */
10658     function isEmpty(value) {
10659       if (isArrayLike(value) &&
10660           (isArray(value) || isString(value) || isFunction(value.splice) ||
10661             isArguments(value) || isBuffer(value))) {
10662         return !value.length;
10663       }
10664       if (isObjectLike(value)) {
10665         var tag = getTag(value);
10666         if (tag == mapTag || tag == setTag) {
10667           return !value.size;
10668         }
10669       }
10670       for (var key in value) {
10671         if (hasOwnProperty.call(value, key)) {
10672           return false;
10673         }
10674       }
10675       return !(nonEnumShadows && keys(value).length);
10676     }
10677
10678     /**
10679      * Performs a deep comparison between two values to determine if they are
10680      * equivalent.
10681      *
10682      * **Note:** This method supports comparing arrays, array buffers, booleans,
10683      * date objects, error objects, maps, numbers, `Object` objects, regexes,
10684      * sets, strings, symbols, and typed arrays. `Object` objects are compared
10685      * by their own, not inherited, enumerable properties. Functions and DOM
10686      * nodes are **not** supported.
10687      *
10688      * @static
10689      * @memberOf _
10690      * @since 0.1.0
10691      * @category Lang
10692      * @param {*} value The value to compare.
10693      * @param {*} other The other value to compare.
10694      * @returns {boolean} Returns `true` if the values are equivalent,
10695      *  else `false`.
10696      * @example
10697      *
10698      * var object = { 'user': 'fred' };
10699      * var other = { 'user': 'fred' };
10700      *
10701      * _.isEqual(object, other);
10702      * // => true
10703      *
10704      * object === other;
10705      * // => false
10706      */
10707     function isEqual(value, other) {
10708       return baseIsEqual(value, other);
10709     }
10710
10711     /**
10712      * This method is like `_.isEqual` except that it accepts `customizer` which
10713      * is invoked to compare values. If `customizer` returns `undefined`, comparisons
10714      * are handled by the method instead. The `customizer` is invoked with up to
10715      * six arguments: (objValue, othValue [, index|key, object, other, stack]).
10716      *
10717      * @static
10718      * @memberOf _
10719      * @since 4.0.0
10720      * @category Lang
10721      * @param {*} value The value to compare.
10722      * @param {*} other The other value to compare.
10723      * @param {Function} [customizer] The function to customize comparisons.
10724      * @returns {boolean} Returns `true` if the values are equivalent,
10725      *  else `false`.
10726      * @example
10727      *
10728      * function isGreeting(value) {
10729      *   return /^h(?:i|ello)$/.test(value);
10730      * }
10731      *
10732      * function customizer(objValue, othValue) {
10733      *   if (isGreeting(objValue) && isGreeting(othValue)) {
10734      *     return true;
10735      *   }
10736      * }
10737      *
10738      * var array = ['hello', 'goodbye'];
10739      * var other = ['hi', 'goodbye'];
10740      *
10741      * _.isEqualWith(array, other, customizer);
10742      * // => true
10743      */
10744     function isEqualWith(value, other, customizer) {
10745       customizer = typeof customizer == 'function' ? customizer : undefined;
10746       var result = customizer ? customizer(value, other) : undefined;
10747       return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
10748     }
10749
10750     /**
10751      * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
10752      * `SyntaxError`, `TypeError`, or `URIError` object.
10753      *
10754      * @static
10755      * @memberOf _
10756      * @since 3.0.0
10757      * @category Lang
10758      * @param {*} value The value to check.
10759      * @returns {boolean} Returns `true` if `value` is an error object,
10760      *  else `false`.
10761      * @example
10762      *
10763      * _.isError(new Error);
10764      * // => true
10765      *
10766      * _.isError(Error);
10767      * // => false
10768      */
10769     function isError(value) {
10770       if (!isObjectLike(value)) {
10771         return false;
10772       }
10773       return (objectToString.call(value) == errorTag) ||
10774         (typeof value.message == 'string' && typeof value.name == 'string');
10775     }
10776
10777     /**
10778      * Checks if `value` is a finite primitive number.
10779      *
10780      * **Note:** This method is based on
10781      * [`Number.isFinite`](https://mdn.io/Number/isFinite).
10782      *
10783      * @static
10784      * @memberOf _
10785      * @since 0.1.0
10786      * @category Lang
10787      * @param {*} value The value to check.
10788      * @returns {boolean} Returns `true` if `value` is a finite number,
10789      *  else `false`.
10790      * @example
10791      *
10792      * _.isFinite(3);
10793      * // => true
10794      *
10795      * _.isFinite(Number.MAX_VALUE);
10796      * // => true
10797      *
10798      * _.isFinite(3.14);
10799      * // => true
10800      *
10801      * _.isFinite(Infinity);
10802      * // => false
10803      */
10804     function isFinite(value) {
10805       return typeof value == 'number' && nativeIsFinite(value);
10806     }
10807
10808     /**
10809      * Checks if `value` is classified as a `Function` object.
10810      *
10811      * @static
10812      * @memberOf _
10813      * @since 0.1.0
10814      * @category Lang
10815      * @param {*} value The value to check.
10816      * @returns {boolean} Returns `true` if `value` is correctly classified,
10817      *  else `false`.
10818      * @example
10819      *
10820      * _.isFunction(_);
10821      * // => true
10822      *
10823      * _.isFunction(/abc/);
10824      * // => false
10825      */
10826     function isFunction(value) {
10827       // The use of `Object#toString` avoids issues with the `typeof` operator
10828       // in Safari 8 which returns 'object' for typed array and weak map constructors,
10829       // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
10830       var tag = isObject(value) ? objectToString.call(value) : '';
10831       return tag == funcTag || tag == genTag;
10832     }
10833
10834     /**
10835      * Checks if `value` is an integer.
10836      *
10837      * **Note:** This method is based on
10838      * [`Number.isInteger`](https://mdn.io/Number/isInteger).
10839      *
10840      * @static
10841      * @memberOf _
10842      * @since 4.0.0
10843      * @category Lang
10844      * @param {*} value The value to check.
10845      * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
10846      * @example
10847      *
10848      * _.isInteger(3);
10849      * // => true
10850      *
10851      * _.isInteger(Number.MIN_VALUE);
10852      * // => false
10853      *
10854      * _.isInteger(Infinity);
10855      * // => false
10856      *
10857      * _.isInteger('3');
10858      * // => false
10859      */
10860     function isInteger(value) {
10861       return typeof value == 'number' && value == toInteger(value);
10862     }
10863
10864     /**
10865      * Checks if `value` is a valid array-like length.
10866      *
10867      * **Note:** This function is loosely based on
10868      * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
10869      *
10870      * @static
10871      * @memberOf _
10872      * @since 4.0.0
10873      * @category Lang
10874      * @param {*} value The value to check.
10875      * @returns {boolean} Returns `true` if `value` is a valid length,
10876      *  else `false`.
10877      * @example
10878      *
10879      * _.isLength(3);
10880      * // => true
10881      *
10882      * _.isLength(Number.MIN_VALUE);
10883      * // => false
10884      *
10885      * _.isLength(Infinity);
10886      * // => false
10887      *
10888      * _.isLength('3');
10889      * // => false
10890      */
10891     function isLength(value) {
10892       return typeof value == 'number' &&
10893         value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
10894     }
10895
10896     /**
10897      * Checks if `value` is the
10898      * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)
10899      * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
10900      *
10901      * @static
10902      * @memberOf _
10903      * @since 0.1.0
10904      * @category Lang
10905      * @param {*} value The value to check.
10906      * @returns {boolean} Returns `true` if `value` is an object, else `false`.
10907      * @example
10908      *
10909      * _.isObject({});
10910      * // => true
10911      *
10912      * _.isObject([1, 2, 3]);
10913      * // => true
10914      *
10915      * _.isObject(_.noop);
10916      * // => true
10917      *
10918      * _.isObject(null);
10919      * // => false
10920      */
10921     function isObject(value) {
10922       var type = typeof value;
10923       return !!value && (type == 'object' || type == 'function');
10924     }
10925
10926     /**
10927      * Checks if `value` is object-like. A value is object-like if it's not `null`
10928      * and has a `typeof` result of "object".
10929      *
10930      * @static
10931      * @memberOf _
10932      * @since 4.0.0
10933      * @category Lang
10934      * @param {*} value The value to check.
10935      * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
10936      * @example
10937      *
10938      * _.isObjectLike({});
10939      * // => true
10940      *
10941      * _.isObjectLike([1, 2, 3]);
10942      * // => true
10943      *
10944      * _.isObjectLike(_.noop);
10945      * // => false
10946      *
10947      * _.isObjectLike(null);
10948      * // => false
10949      */
10950     function isObjectLike(value) {
10951       return !!value && typeof value == 'object';
10952     }
10953
10954     /**
10955      * Checks if `value` is classified as a `Map` object.
10956      *
10957      * @static
10958      * @memberOf _
10959      * @since 4.3.0
10960      * @category Lang
10961      * @param {*} value The value to check.
10962      * @returns {boolean} Returns `true` if `value` is correctly classified,
10963      *  else `false`.
10964      * @example
10965      *
10966      * _.isMap(new Map);
10967      * // => true
10968      *
10969      * _.isMap(new WeakMap);
10970      * // => false
10971      */
10972     function isMap(value) {
10973       return isObjectLike(value) && getTag(value) == mapTag;
10974     }
10975
10976     /**
10977      * Performs a partial deep comparison between `object` and `source` to
10978      * determine if `object` contains equivalent property values. This method is
10979      * equivalent to a `_.matches` function when `source` is partially applied.
10980      *
10981      * **Note:** This method supports comparing the same values as `_.isEqual`.
10982      *
10983      * @static
10984      * @memberOf _
10985      * @since 3.0.0
10986      * @category Lang
10987      * @param {Object} object The object to inspect.
10988      * @param {Object} source The object of property values to match.
10989      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
10990      * @example
10991      *
10992      * var object = { 'user': 'fred', 'age': 40 };
10993      *
10994      * _.isMatch(object, { 'age': 40 });
10995      * // => true
10996      *
10997      * _.isMatch(object, { 'age': 36 });
10998      * // => false
10999      */
11000     function isMatch(object, source) {
11001       return object === source || baseIsMatch(object, source, getMatchData(source));
11002     }
11003
11004     /**
11005      * This method is like `_.isMatch` except that it accepts `customizer` which
11006      * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11007      * are handled by the method instead. The `customizer` is invoked with five
11008      * arguments: (objValue, srcValue, index|key, object, source).
11009      *
11010      * @static
11011      * @memberOf _
11012      * @since 4.0.0
11013      * @category Lang
11014      * @param {Object} object The object to inspect.
11015      * @param {Object} source The object of property values to match.
11016      * @param {Function} [customizer] The function to customize comparisons.
11017      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11018      * @example
11019      *
11020      * function isGreeting(value) {
11021      *   return /^h(?:i|ello)$/.test(value);
11022      * }
11023      *
11024      * function customizer(objValue, srcValue) {
11025      *   if (isGreeting(objValue) && isGreeting(srcValue)) {
11026      *     return true;
11027      *   }
11028      * }
11029      *
11030      * var object = { 'greeting': 'hello' };
11031      * var source = { 'greeting': 'hi' };
11032      *
11033      * _.isMatchWith(object, source, customizer);
11034      * // => true
11035      */
11036     function isMatchWith(object, source, customizer) {
11037       customizer = typeof customizer == 'function' ? customizer : undefined;
11038       return baseIsMatch(object, source, getMatchData(source), customizer);
11039     }
11040
11041     /**
11042      * Checks if `value` is `NaN`.
11043      *
11044      * **Note:** This method is based on
11045      * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
11046      * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
11047      * `undefined` and other non-number values.
11048      *
11049      * @static
11050      * @memberOf _
11051      * @since 0.1.0
11052      * @category Lang
11053      * @param {*} value The value to check.
11054      * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
11055      * @example
11056      *
11057      * _.isNaN(NaN);
11058      * // => true
11059      *
11060      * _.isNaN(new Number(NaN));
11061      * // => true
11062      *
11063      * isNaN(undefined);
11064      * // => true
11065      *
11066      * _.isNaN(undefined);
11067      * // => false
11068      */
11069     function isNaN(value) {
11070       // An `NaN` primitive is the only value that is not equal to itself.
11071       // Perform the `toStringTag` check first to avoid errors with some
11072       // ActiveX objects in IE.
11073       return isNumber(value) && value != +value;
11074     }
11075
11076     /**
11077      * Checks if `value` is a native function.
11078      *
11079      * @static
11080      * @memberOf _
11081      * @since 3.0.0
11082      * @category Lang
11083      * @param {*} value The value to check.
11084      * @returns {boolean} Returns `true` if `value` is a native function,
11085      *  else `false`.
11086      * @example
11087      *
11088      * _.isNative(Array.prototype.push);
11089      * // => true
11090      *
11091      * _.isNative(_);
11092      * // => false
11093      */
11094     function isNative(value) {
11095       if (!isObject(value)) {
11096         return false;
11097       }
11098       var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
11099       return pattern.test(toSource(value));
11100     }
11101
11102     /**
11103      * Checks if `value` is `null`.
11104      *
11105      * @static
11106      * @memberOf _
11107      * @since 0.1.0
11108      * @category Lang
11109      * @param {*} value The value to check.
11110      * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
11111      * @example
11112      *
11113      * _.isNull(null);
11114      * // => true
11115      *
11116      * _.isNull(void 0);
11117      * // => false
11118      */
11119     function isNull(value) {
11120       return value === null;
11121     }
11122
11123     /**
11124      * Checks if `value` is `null` or `undefined`.
11125      *
11126      * @static
11127      * @memberOf _
11128      * @since 4.0.0
11129      * @category Lang
11130      * @param {*} value The value to check.
11131      * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
11132      * @example
11133      *
11134      * _.isNil(null);
11135      * // => true
11136      *
11137      * _.isNil(void 0);
11138      * // => true
11139      *
11140      * _.isNil(NaN);
11141      * // => false
11142      */
11143     function isNil(value) {
11144       return value == null;
11145     }
11146
11147     /**
11148      * Checks if `value` is classified as a `Number` primitive or object.
11149      *
11150      * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
11151      * classified as numbers, use the `_.isFinite` method.
11152      *
11153      * @static
11154      * @memberOf _
11155      * @since 0.1.0
11156      * @category Lang
11157      * @param {*} value The value to check.
11158      * @returns {boolean} Returns `true` if `value` is correctly classified,
11159      *  else `false`.
11160      * @example
11161      *
11162      * _.isNumber(3);
11163      * // => true
11164      *
11165      * _.isNumber(Number.MIN_VALUE);
11166      * // => true
11167      *
11168      * _.isNumber(Infinity);
11169      * // => true
11170      *
11171      * _.isNumber('3');
11172      * // => false
11173      */
11174     function isNumber(value) {
11175       return typeof value == 'number' ||
11176         (isObjectLike(value) && objectToString.call(value) == numberTag);
11177     }
11178
11179     /**
11180      * Checks if `value` is a plain object, that is, an object created by the
11181      * `Object` constructor or one with a `[[Prototype]]` of `null`.
11182      *
11183      * @static
11184      * @memberOf _
11185      * @since 0.8.0
11186      * @category Lang
11187      * @param {*} value The value to check.
11188      * @returns {boolean} Returns `true` if `value` is a plain object,
11189      *  else `false`.
11190      * @example
11191      *
11192      * function Foo() {
11193      *   this.a = 1;
11194      * }
11195      *
11196      * _.isPlainObject(new Foo);
11197      * // => false
11198      *
11199      * _.isPlainObject([1, 2, 3]);
11200      * // => false
11201      *
11202      * _.isPlainObject({ 'x': 0, 'y': 0 });
11203      * // => true
11204      *
11205      * _.isPlainObject(Object.create(null));
11206      * // => true
11207      */
11208     function isPlainObject(value) {
11209       if (!isObjectLike(value) ||
11210           objectToString.call(value) != objectTag || isHostObject(value)) {
11211         return false;
11212       }
11213       var proto = getPrototype(value);
11214       if (proto === null) {
11215         return true;
11216       }
11217       var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
11218       return (typeof Ctor == 'function' &&
11219         Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
11220     }
11221
11222     /**
11223      * Checks if `value` is classified as a `RegExp` object.
11224      *
11225      * @static
11226      * @memberOf _
11227      * @since 0.1.0
11228      * @category Lang
11229      * @param {*} value The value to check.
11230      * @returns {boolean} Returns `true` if `value` is correctly classified,
11231      *  else `false`.
11232      * @example
11233      *
11234      * _.isRegExp(/abc/);
11235      * // => true
11236      *
11237      * _.isRegExp('/abc/');
11238      * // => false
11239      */
11240     function isRegExp(value) {
11241       return isObject(value) && objectToString.call(value) == regexpTag;
11242     }
11243
11244     /**
11245      * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
11246      * double precision number which isn't the result of a rounded unsafe integer.
11247      *
11248      * **Note:** This method is based on
11249      * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
11250      *
11251      * @static
11252      * @memberOf _
11253      * @since 4.0.0
11254      * @category Lang
11255      * @param {*} value The value to check.
11256      * @returns {boolean} Returns `true` if `value` is a safe integer,
11257      *  else `false`.
11258      * @example
11259      *
11260      * _.isSafeInteger(3);
11261      * // => true
11262      *
11263      * _.isSafeInteger(Number.MIN_VALUE);
11264      * // => false
11265      *
11266      * _.isSafeInteger(Infinity);
11267      * // => false
11268      *
11269      * _.isSafeInteger('3');
11270      * // => false
11271      */
11272     function isSafeInteger(value) {
11273       return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
11274     }
11275
11276     /**
11277      * Checks if `value` is classified as a `Set` object.
11278      *
11279      * @static
11280      * @memberOf _
11281      * @since 4.3.0
11282      * @category Lang
11283      * @param {*} value The value to check.
11284      * @returns {boolean} Returns `true` if `value` is correctly classified,
11285      *  else `false`.
11286      * @example
11287      *
11288      * _.isSet(new Set);
11289      * // => true
11290      *
11291      * _.isSet(new WeakSet);
11292      * // => false
11293      */
11294     function isSet(value) {
11295       return isObjectLike(value) && getTag(value) == setTag;
11296     }
11297
11298     /**
11299      * Checks if `value` is classified as a `String` primitive or object.
11300      *
11301      * @static
11302      * @since 0.1.0
11303      * @memberOf _
11304      * @category Lang
11305      * @param {*} value The value to check.
11306      * @returns {boolean} Returns `true` if `value` is correctly classified,
11307      *  else `false`.
11308      * @example
11309      *
11310      * _.isString('abc');
11311      * // => true
11312      *
11313      * _.isString(1);
11314      * // => false
11315      */
11316     function isString(value) {
11317       return typeof value == 'string' ||
11318         (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
11319     }
11320
11321     /**
11322      * Checks if `value` is classified as a `Symbol` primitive or object.
11323      *
11324      * @static
11325      * @memberOf _
11326      * @since 4.0.0
11327      * @category Lang
11328      * @param {*} value The value to check.
11329      * @returns {boolean} Returns `true` if `value` is correctly classified,
11330      *  else `false`.
11331      * @example
11332      *
11333      * _.isSymbol(Symbol.iterator);
11334      * // => true
11335      *
11336      * _.isSymbol('abc');
11337      * // => false
11338      */
11339     function isSymbol(value) {
11340       return typeof value == 'symbol' ||
11341         (isObjectLike(value) && objectToString.call(value) == symbolTag);
11342     }
11343
11344     /**
11345      * Checks if `value` is classified as a typed array.
11346      *
11347      * @static
11348      * @memberOf _
11349      * @since 3.0.0
11350      * @category Lang
11351      * @param {*} value The value to check.
11352      * @returns {boolean} Returns `true` if `value` is correctly classified,
11353      *  else `false`.
11354      * @example
11355      *
11356      * _.isTypedArray(new Uint8Array);
11357      * // => true
11358      *
11359      * _.isTypedArray([]);
11360      * // => false
11361      */
11362     function isTypedArray(value) {
11363       return isObjectLike(value) &&
11364         isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
11365     }
11366
11367     /**
11368      * Checks if `value` is `undefined`.
11369      *
11370      * @static
11371      * @since 0.1.0
11372      * @memberOf _
11373      * @category Lang
11374      * @param {*} value The value to check.
11375      * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
11376      * @example
11377      *
11378      * _.isUndefined(void 0);
11379      * // => true
11380      *
11381      * _.isUndefined(null);
11382      * // => false
11383      */
11384     function isUndefined(value) {
11385       return value === undefined;
11386     }
11387
11388     /**
11389      * Checks if `value` is classified as a `WeakMap` object.
11390      *
11391      * @static
11392      * @memberOf _
11393      * @since 4.3.0
11394      * @category Lang
11395      * @param {*} value The value to check.
11396      * @returns {boolean} Returns `true` if `value` is correctly classified,
11397      *  else `false`.
11398      * @example
11399      *
11400      * _.isWeakMap(new WeakMap);
11401      * // => true
11402      *
11403      * _.isWeakMap(new Map);
11404      * // => false
11405      */
11406     function isWeakMap(value) {
11407       return isObjectLike(value) && getTag(value) == weakMapTag;
11408     }
11409
11410     /**
11411      * Checks if `value` is classified as a `WeakSet` object.
11412      *
11413      * @static
11414      * @memberOf _
11415      * @since 4.3.0
11416      * @category Lang
11417      * @param {*} value The value to check.
11418      * @returns {boolean} Returns `true` if `value` is correctly classified,
11419      *  else `false`.
11420      * @example
11421      *
11422      * _.isWeakSet(new WeakSet);
11423      * // => true
11424      *
11425      * _.isWeakSet(new Set);
11426      * // => false
11427      */
11428     function isWeakSet(value) {
11429       return isObjectLike(value) && objectToString.call(value) == weakSetTag;
11430     }
11431
11432     /**
11433      * Checks if `value` is less than `other`.
11434      *
11435      * @static
11436      * @memberOf _
11437      * @since 3.9.0
11438      * @category Lang
11439      * @param {*} value The value to compare.
11440      * @param {*} other The other value to compare.
11441      * @returns {boolean} Returns `true` if `value` is less than `other`,
11442      *  else `false`.
11443      * @see _.gt
11444      * @example
11445      *
11446      * _.lt(1, 3);
11447      * // => true
11448      *
11449      * _.lt(3, 3);
11450      * // => false
11451      *
11452      * _.lt(3, 1);
11453      * // => false
11454      */
11455     var lt = createRelationalOperation(baseLt);
11456
11457     /**
11458      * Checks if `value` is less than or equal to `other`.
11459      *
11460      * @static
11461      * @memberOf _
11462      * @since 3.9.0
11463      * @category Lang
11464      * @param {*} value The value to compare.
11465      * @param {*} other The other value to compare.
11466      * @returns {boolean} Returns `true` if `value` is less than or equal to
11467      *  `other`, else `false`.
11468      * @see _.gte
11469      * @example
11470      *
11471      * _.lte(1, 3);
11472      * // => true
11473      *
11474      * _.lte(3, 3);
11475      * // => true
11476      *
11477      * _.lte(3, 1);
11478      * // => false
11479      */
11480     var lte = createRelationalOperation(function(value, other) {
11481       return value <= other;
11482     });
11483
11484     /**
11485      * Converts `value` to an array.
11486      *
11487      * @static
11488      * @since 0.1.0
11489      * @memberOf _
11490      * @category Lang
11491      * @param {*} value The value to convert.
11492      * @returns {Array} Returns the converted array.
11493      * @example
11494      *
11495      * _.toArray({ 'a': 1, 'b': 2 });
11496      * // => [1, 2]
11497      *
11498      * _.toArray('abc');
11499      * // => ['a', 'b', 'c']
11500      *
11501      * _.toArray(1);
11502      * // => []
11503      *
11504      * _.toArray(null);
11505      * // => []
11506      */
11507     function toArray(value) {
11508       if (!value) {
11509         return [];
11510       }
11511       if (isArrayLike(value)) {
11512         return isString(value) ? stringToArray(value) : copyArray(value);
11513       }
11514       if (iteratorSymbol && value[iteratorSymbol]) {
11515         return iteratorToArray(value[iteratorSymbol]());
11516       }
11517       var tag = getTag(value),
11518           func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
11519
11520       return func(value);
11521     }
11522
11523     /**
11524      * Converts `value` to an integer.
11525      *
11526      * **Note:** This function is loosely based on
11527      * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
11528      *
11529      * @static
11530      * @memberOf _
11531      * @since 4.0.0
11532      * @category Lang
11533      * @param {*} value The value to convert.
11534      * @returns {number} Returns the converted integer.
11535      * @example
11536      *
11537      * _.toInteger(3);
11538      * // => 3
11539      *
11540      * _.toInteger(Number.MIN_VALUE);
11541      * // => 0
11542      *
11543      * _.toInteger(Infinity);
11544      * // => 1.7976931348623157e+308
11545      *
11546      * _.toInteger('3');
11547      * // => 3
11548      */
11549     function toInteger(value) {
11550       if (!value) {
11551         return value === 0 ? value : 0;
11552       }
11553       value = toNumber(value);
11554       if (value === INFINITY || value === -INFINITY) {
11555         var sign = (value < 0 ? -1 : 1);
11556         return sign * MAX_INTEGER;
11557       }
11558       var remainder = value % 1;
11559       return value === value ? (remainder ? value - remainder : value) : 0;
11560     }
11561
11562     /**
11563      * Converts `value` to an integer suitable for use as the length of an
11564      * array-like object.
11565      *
11566      * **Note:** This method is based on
11567      * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
11568      *
11569      * @static
11570      * @memberOf _
11571      * @since 4.0.0
11572      * @category Lang
11573      * @param {*} value The value to convert.
11574      * @returns {number} Returns the converted integer.
11575      * @example
11576      *
11577      * _.toLength(3);
11578      * // => 3
11579      *
11580      * _.toLength(Number.MIN_VALUE);
11581      * // => 0
11582      *
11583      * _.toLength(Infinity);
11584      * // => 4294967295
11585      *
11586      * _.toLength('3');
11587      * // => 3
11588      */
11589     function toLength(value) {
11590       return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
11591     }
11592
11593     /**
11594      * Converts `value` to a number.
11595      *
11596      * @static
11597      * @memberOf _
11598      * @since 4.0.0
11599      * @category Lang
11600      * @param {*} value The value to process.
11601      * @returns {number} Returns the number.
11602      * @example
11603      *
11604      * _.toNumber(3);
11605      * // => 3
11606      *
11607      * _.toNumber(Number.MIN_VALUE);
11608      * // => 5e-324
11609      *
11610      * _.toNumber(Infinity);
11611      * // => Infinity
11612      *
11613      * _.toNumber('3');
11614      * // => 3
11615      */
11616     function toNumber(value) {
11617       if (typeof value == 'number') {
11618         return value;
11619       }
11620       if (isSymbol(value)) {
11621         return NAN;
11622       }
11623       if (isObject(value)) {
11624         var other = isFunction(value.valueOf) ? value.valueOf() : value;
11625         value = isObject(other) ? (other + '') : other;
11626       }
11627       if (typeof value != 'string') {
11628         return value === 0 ? value : +value;
11629       }
11630       value = value.replace(reTrim, '');
11631       var isBinary = reIsBinary.test(value);
11632       return (isBinary || reIsOctal.test(value))
11633         ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
11634         : (reIsBadHex.test(value) ? NAN : +value);
11635     }
11636
11637     /**
11638      * Converts `value` to a plain object flattening inherited enumerable string
11639      * keyed properties of `value` to own properties of the plain object.
11640      *
11641      * @static
11642      * @memberOf _
11643      * @since 3.0.0
11644      * @category Lang
11645      * @param {*} value The value to convert.
11646      * @returns {Object} Returns the converted plain object.
11647      * @example
11648      *
11649      * function Foo() {
11650      *   this.b = 2;
11651      * }
11652      *
11653      * Foo.prototype.c = 3;
11654      *
11655      * _.assign({ 'a': 1 }, new Foo);
11656      * // => { 'a': 1, 'b': 2 }
11657      *
11658      * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
11659      * // => { 'a': 1, 'b': 2, 'c': 3 }
11660      */
11661     function toPlainObject(value) {
11662       return copyObject(value, keysIn(value));
11663     }
11664
11665     /**
11666      * Converts `value` to a safe integer. A safe integer can be compared and
11667      * represented correctly.
11668      *
11669      * @static
11670      * @memberOf _
11671      * @since 4.0.0
11672      * @category Lang
11673      * @param {*} value The value to convert.
11674      * @returns {number} Returns the converted integer.
11675      * @example
11676      *
11677      * _.toSafeInteger(3);
11678      * // => 3
11679      *
11680      * _.toSafeInteger(Number.MIN_VALUE);
11681      * // => 0
11682      *
11683      * _.toSafeInteger(Infinity);
11684      * // => 9007199254740991
11685      *
11686      * _.toSafeInteger('3');
11687      * // => 3
11688      */
11689     function toSafeInteger(value) {
11690       return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
11691     }
11692
11693     /**
11694      * Converts `value` to a string. An empty string is returned for `null`
11695      * and `undefined` values. The sign of `-0` is preserved.
11696      *
11697      * @static
11698      * @memberOf _
11699      * @since 4.0.0
11700      * @category Lang
11701      * @param {*} value The value to process.
11702      * @returns {string} Returns the string.
11703      * @example
11704      *
11705      * _.toString(null);
11706      * // => ''
11707      *
11708      * _.toString(-0);
11709      * // => '-0'
11710      *
11711      * _.toString([1, 2, 3]);
11712      * // => '1,2,3'
11713      */
11714     function toString(value) {
11715       return value == null ? '' : baseToString(value);
11716     }
11717
11718     /*------------------------------------------------------------------------*/
11719
11720     /**
11721      * Assigns own enumerable string keyed properties of source objects to the
11722      * destination object. Source objects are applied from left to right.
11723      * Subsequent sources overwrite property assignments of previous sources.
11724      *
11725      * **Note:** This method mutates `object` and is loosely based on
11726      * [`Object.assign`](https://mdn.io/Object/assign).
11727      *
11728      * @static
11729      * @memberOf _
11730      * @since 0.10.0
11731      * @category Object
11732      * @param {Object} object The destination object.
11733      * @param {...Object} [sources] The source objects.
11734      * @returns {Object} Returns `object`.
11735      * @see _.assignIn
11736      * @example
11737      *
11738      * function Foo() {
11739      *   this.c = 3;
11740      * }
11741      *
11742      * function Bar() {
11743      *   this.e = 5;
11744      * }
11745      *
11746      * Foo.prototype.d = 4;
11747      * Bar.prototype.f = 6;
11748      *
11749      * _.assign({ 'a': 1 }, new Foo, new Bar);
11750      * // => { 'a': 1, 'c': 3, 'e': 5 }
11751      */
11752     var assign = createAssigner(function(object, source) {
11753       if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {
11754         copyObject(source, keys(source), object);
11755         return;
11756       }
11757       for (var key in source) {
11758         if (hasOwnProperty.call(source, key)) {
11759           assignValue(object, key, source[key]);
11760         }
11761       }
11762     });
11763
11764     /**
11765      * This method is like `_.assign` except that it iterates over own and
11766      * inherited source properties.
11767      *
11768      * **Note:** This method mutates `object`.
11769      *
11770      * @static
11771      * @memberOf _
11772      * @since 4.0.0
11773      * @alias extend
11774      * @category Object
11775      * @param {Object} object The destination object.
11776      * @param {...Object} [sources] The source objects.
11777      * @returns {Object} Returns `object`.
11778      * @see _.assign
11779      * @example
11780      *
11781      * function Foo() {
11782      *   this.b = 2;
11783      * }
11784      *
11785      * function Bar() {
11786      *   this.d = 4;
11787      * }
11788      *
11789      * Foo.prototype.c = 3;
11790      * Bar.prototype.e = 5;
11791      *
11792      * _.assignIn({ 'a': 1 }, new Foo, new Bar);
11793      * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
11794      */
11795     var assignIn = createAssigner(function(object, source) {
11796       if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {
11797         copyObject(source, keysIn(source), object);
11798         return;
11799       }
11800       for (var key in source) {
11801         assignValue(object, key, source[key]);
11802       }
11803     });
11804
11805     /**
11806      * This method is like `_.assignIn` except that it accepts `customizer`
11807      * which is invoked to produce the assigned values. If `customizer` returns
11808      * `undefined`, assignment is handled by the method instead. The `customizer`
11809      * is invoked with five arguments: (objValue, srcValue, key, object, source).
11810      *
11811      * **Note:** This method mutates `object`.
11812      *
11813      * @static
11814      * @memberOf _
11815      * @since 4.0.0
11816      * @alias extendWith
11817      * @category Object
11818      * @param {Object} object The destination object.
11819      * @param {...Object} sources The source objects.
11820      * @param {Function} [customizer] The function to customize assigned values.
11821      * @returns {Object} Returns `object`.
11822      * @see _.assignWith
11823      * @example
11824      *
11825      * function customizer(objValue, srcValue) {
11826      *   return _.isUndefined(objValue) ? srcValue : objValue;
11827      * }
11828      *
11829      * var defaults = _.partialRight(_.assignInWith, customizer);
11830      *
11831      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
11832      * // => { 'a': 1, 'b': 2 }
11833      */
11834     var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
11835       copyObject(source, keysIn(source), object, customizer);
11836     });
11837
11838     /**
11839      * This method is like `_.assign` except that it accepts `customizer`
11840      * which is invoked to produce the assigned values. If `customizer` returns
11841      * `undefined`, assignment is handled by the method instead. The `customizer`
11842      * is invoked with five arguments: (objValue, srcValue, key, object, source).
11843      *
11844      * **Note:** This method mutates `object`.
11845      *
11846      * @static
11847      * @memberOf _
11848      * @since 4.0.0
11849      * @category Object
11850      * @param {Object} object The destination object.
11851      * @param {...Object} sources The source objects.
11852      * @param {Function} [customizer] The function to customize assigned values.
11853      * @returns {Object} Returns `object`.
11854      * @see _.assignInWith
11855      * @example
11856      *
11857      * function customizer(objValue, srcValue) {
11858      *   return _.isUndefined(objValue) ? srcValue : objValue;
11859      * }
11860      *
11861      * var defaults = _.partialRight(_.assignWith, customizer);
11862      *
11863      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
11864      * // => { 'a': 1, 'b': 2 }
11865      */
11866     var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
11867       copyObject(source, keys(source), object, customizer);
11868     });
11869
11870     /**
11871      * Creates an array of values corresponding to `paths` of `object`.
11872      *
11873      * @static
11874      * @memberOf _
11875      * @since 1.0.0
11876      * @category Object
11877      * @param {Object} object The object to iterate over.
11878      * @param {...(string|string[])} [paths] The property paths of elements to pick.
11879      * @returns {Array} Returns the new array of picked elements.
11880      * @example
11881      *
11882      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
11883      *
11884      * _.at(object, ['a[0].b.c', 'a[1]']);
11885      * // => [3, 4]
11886      *
11887      * _.at(['a', 'b', 'c'], 0, 2);
11888      * // => ['a', 'c']
11889      */
11890     var at = rest(function(object, paths) {
11891       return baseAt(object, baseFlatten(paths, 1));
11892     });
11893
11894     /**
11895      * Creates an object that inherits from the `prototype` object. If a
11896      * `properties` object is given, its own enumerable string keyed properties
11897      * are assigned to the created object.
11898      *
11899      * @static
11900      * @memberOf _
11901      * @since 2.3.0
11902      * @category Object
11903      * @param {Object} prototype The object to inherit from.
11904      * @param {Object} [properties] The properties to assign to the object.
11905      * @returns {Object} Returns the new object.
11906      * @example
11907      *
11908      * function Shape() {
11909      *   this.x = 0;
11910      *   this.y = 0;
11911      * }
11912      *
11913      * function Circle() {
11914      *   Shape.call(this);
11915      * }
11916      *
11917      * Circle.prototype = _.create(Shape.prototype, {
11918      *   'constructor': Circle
11919      * });
11920      *
11921      * var circle = new Circle;
11922      * circle instanceof Circle;
11923      * // => true
11924      *
11925      * circle instanceof Shape;
11926      * // => true
11927      */
11928     function create(prototype, properties) {
11929       var result = baseCreate(prototype);
11930       return properties ? baseAssign(result, properties) : result;
11931     }
11932
11933     /**
11934      * Assigns own and inherited enumerable string keyed properties of source
11935      * objects to the destination object for all destination properties that
11936      * resolve to `undefined`. Source objects are applied from left to right.
11937      * Once a property is set, additional values of the same property are ignored.
11938      *
11939      * **Note:** This method mutates `object`.
11940      *
11941      * @static
11942      * @since 0.1.0
11943      * @memberOf _
11944      * @category Object
11945      * @param {Object} object The destination object.
11946      * @param {...Object} [sources] The source objects.
11947      * @returns {Object} Returns `object`.
11948      * @see _.defaultsDeep
11949      * @example
11950      *
11951      * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
11952      * // => { 'user': 'barney', 'age': 36 }
11953      */
11954     var defaults = rest(function(args) {
11955       args.push(undefined, assignInDefaults);
11956       return apply(assignInWith, undefined, args);
11957     });
11958
11959     /**
11960      * This method is like `_.defaults` except that it recursively assigns
11961      * default properties.
11962      *
11963      * **Note:** This method mutates `object`.
11964      *
11965      * @static
11966      * @memberOf _
11967      * @since 3.10.0
11968      * @category Object
11969      * @param {Object} object The destination object.
11970      * @param {...Object} [sources] The source objects.
11971      * @returns {Object} Returns `object`.
11972      * @see _.defaults
11973      * @example
11974      *
11975      * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
11976      * // => { 'user': { 'name': 'barney', 'age': 36 } }
11977      *
11978      */
11979     var defaultsDeep = rest(function(args) {
11980       args.push(undefined, mergeDefaults);
11981       return apply(mergeWith, undefined, args);
11982     });
11983
11984     /**
11985      * This method is like `_.find` except that it returns the key of the first
11986      * element `predicate` returns truthy for instead of the element itself.
11987      *
11988      * @static
11989      * @memberOf _
11990      * @since 1.1.0
11991      * @category Object
11992      * @param {Object} object The object to search.
11993      * @param {Array|Function|Object|string} [predicate=_.identity]
11994      *  The function invoked per iteration.
11995      * @returns {string|undefined} Returns the key of the matched element,
11996      *  else `undefined`.
11997      * @example
11998      *
11999      * var users = {
12000      *   'barney':  { 'age': 36, 'active': true },
12001      *   'fred':    { 'age': 40, 'active': false },
12002      *   'pebbles': { 'age': 1,  'active': true }
12003      * };
12004      *
12005      * _.findKey(users, function(o) { return o.age < 40; });
12006      * // => 'barney' (iteration order is not guaranteed)
12007      *
12008      * // The `_.matches` iteratee shorthand.
12009      * _.findKey(users, { 'age': 1, 'active': true });
12010      * // => 'pebbles'
12011      *
12012      * // The `_.matchesProperty` iteratee shorthand.
12013      * _.findKey(users, ['active', false]);
12014      * // => 'fred'
12015      *
12016      * // The `_.property` iteratee shorthand.
12017      * _.findKey(users, 'active');
12018      * // => 'barney'
12019      */
12020     function findKey(object, predicate) {
12021       return baseFind(object, getIteratee(predicate, 3), baseForOwn, true);
12022     }
12023
12024     /**
12025      * This method is like `_.findKey` except that it iterates over elements of
12026      * a collection in the opposite order.
12027      *
12028      * @static
12029      * @memberOf _
12030      * @since 2.0.0
12031      * @category Object
12032      * @param {Object} object The object to search.
12033      * @param {Array|Function|Object|string} [predicate=_.identity]
12034      *  The function invoked per iteration.
12035      * @returns {string|undefined} Returns the key of the matched element,
12036      *  else `undefined`.
12037      * @example
12038      *
12039      * var users = {
12040      *   'barney':  { 'age': 36, 'active': true },
12041      *   'fred':    { 'age': 40, 'active': false },
12042      *   'pebbles': { 'age': 1,  'active': true }
12043      * };
12044      *
12045      * _.findLastKey(users, function(o) { return o.age < 40; });
12046      * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
12047      *
12048      * // The `_.matches` iteratee shorthand.
12049      * _.findLastKey(users, { 'age': 36, 'active': true });
12050      * // => 'barney'
12051      *
12052      * // The `_.matchesProperty` iteratee shorthand.
12053      * _.findLastKey(users, ['active', false]);
12054      * // => 'fred'
12055      *
12056      * // The `_.property` iteratee shorthand.
12057      * _.findLastKey(users, 'active');
12058      * // => 'pebbles'
12059      */
12060     function findLastKey(object, predicate) {
12061       return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true);
12062     }
12063
12064     /**
12065      * Iterates over own and inherited enumerable string keyed properties of an
12066      * object and invokes `iteratee` for each property. The iteratee is invoked
12067      * with three arguments: (value, key, object). Iteratee functions may exit
12068      * iteration early by explicitly returning `false`.
12069      *
12070      * @static
12071      * @memberOf _
12072      * @since 0.3.0
12073      * @category Object
12074      * @param {Object} object The object to iterate over.
12075      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12076      * @returns {Object} Returns `object`.
12077      * @see _.forInRight
12078      * @example
12079      *
12080      * function Foo() {
12081      *   this.a = 1;
12082      *   this.b = 2;
12083      * }
12084      *
12085      * Foo.prototype.c = 3;
12086      *
12087      * _.forIn(new Foo, function(value, key) {
12088      *   console.log(key);
12089      * });
12090      * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
12091      */
12092     function forIn(object, iteratee) {
12093       return object == null
12094         ? object
12095         : baseFor(object, getIteratee(iteratee), keysIn);
12096     }
12097
12098     /**
12099      * This method is like `_.forIn` except that it iterates over properties of
12100      * `object` in the opposite order.
12101      *
12102      * @static
12103      * @memberOf _
12104      * @since 2.0.0
12105      * @category Object
12106      * @param {Object} object The object to iterate over.
12107      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12108      * @returns {Object} Returns `object`.
12109      * @see _.forIn
12110      * @example
12111      *
12112      * function Foo() {
12113      *   this.a = 1;
12114      *   this.b = 2;
12115      * }
12116      *
12117      * Foo.prototype.c = 3;
12118      *
12119      * _.forInRight(new Foo, function(value, key) {
12120      *   console.log(key);
12121      * });
12122      * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
12123      */
12124     function forInRight(object, iteratee) {
12125       return object == null
12126         ? object
12127         : baseForRight(object, getIteratee(iteratee), keysIn);
12128     }
12129
12130     /**
12131      * Iterates over own enumerable string keyed properties of an object and
12132      * invokes `iteratee` for each property. The iteratee is invoked with three
12133      * arguments: (value, key, object). Iteratee functions may exit iteration
12134      * early by explicitly returning `false`.
12135      *
12136      * @static
12137      * @memberOf _
12138      * @since 0.3.0
12139      * @category Object
12140      * @param {Object} object The object to iterate over.
12141      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12142      * @returns {Object} Returns `object`.
12143      * @see _.forOwnRight
12144      * @example
12145      *
12146      * function Foo() {
12147      *   this.a = 1;
12148      *   this.b = 2;
12149      * }
12150      *
12151      * Foo.prototype.c = 3;
12152      *
12153      * _.forOwn(new Foo, function(value, key) {
12154      *   console.log(key);
12155      * });
12156      * // => Logs 'a' then 'b' (iteration order is not guaranteed).
12157      */
12158     function forOwn(object, iteratee) {
12159       return object && baseForOwn(object, getIteratee(iteratee));
12160     }
12161
12162     /**
12163      * This method is like `_.forOwn` except that it iterates over properties of
12164      * `object` in the opposite order.
12165      *
12166      * @static
12167      * @memberOf _
12168      * @since 2.0.0
12169      * @category Object
12170      * @param {Object} object The object to iterate over.
12171      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12172      * @returns {Object} Returns `object`.
12173      * @see _.forOwn
12174      * @example
12175      *
12176      * function Foo() {
12177      *   this.a = 1;
12178      *   this.b = 2;
12179      * }
12180      *
12181      * Foo.prototype.c = 3;
12182      *
12183      * _.forOwnRight(new Foo, function(value, key) {
12184      *   console.log(key);
12185      * });
12186      * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
12187      */
12188     function forOwnRight(object, iteratee) {
12189       return object && baseForOwnRight(object, getIteratee(iteratee));
12190     }
12191
12192     /**
12193      * Creates an array of function property names from own enumerable properties
12194      * of `object`.
12195      *
12196      * @static
12197      * @since 0.1.0
12198      * @memberOf _
12199      * @category Object
12200      * @param {Object} object The object to inspect.
12201      * @returns {Array} Returns the new array of property names.
12202      * @see _.functionsIn
12203      * @example
12204      *
12205      * function Foo() {
12206      *   this.a = _.constant('a');
12207      *   this.b = _.constant('b');
12208      * }
12209      *
12210      * Foo.prototype.c = _.constant('c');
12211      *
12212      * _.functions(new Foo);
12213      * // => ['a', 'b']
12214      */
12215     function functions(object) {
12216       return object == null ? [] : baseFunctions(object, keys(object));
12217     }
12218
12219     /**
12220      * Creates an array of function property names from own and inherited
12221      * enumerable properties of `object`.
12222      *
12223      * @static
12224      * @memberOf _
12225      * @since 4.0.0
12226      * @category Object
12227      * @param {Object} object The object to inspect.
12228      * @returns {Array} Returns the new array of property names.
12229      * @see _.functions
12230      * @example
12231      *
12232      * function Foo() {
12233      *   this.a = _.constant('a');
12234      *   this.b = _.constant('b');
12235      * }
12236      *
12237      * Foo.prototype.c = _.constant('c');
12238      *
12239      * _.functionsIn(new Foo);
12240      * // => ['a', 'b', 'c']
12241      */
12242     function functionsIn(object) {
12243       return object == null ? [] : baseFunctions(object, keysIn(object));
12244     }
12245
12246     /**
12247      * Gets the value at `path` of `object`. If the resolved value is
12248      * `undefined`, the `defaultValue` is used in its place.
12249      *
12250      * @static
12251      * @memberOf _
12252      * @since 3.7.0
12253      * @category Object
12254      * @param {Object} object The object to query.
12255      * @param {Array|string} path The path of the property to get.
12256      * @param {*} [defaultValue] The value returned for `undefined` resolved values.
12257      * @returns {*} Returns the resolved value.
12258      * @example
12259      *
12260      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
12261      *
12262      * _.get(object, 'a[0].b.c');
12263      * // => 3
12264      *
12265      * _.get(object, ['a', '0', 'b', 'c']);
12266      * // => 3
12267      *
12268      * _.get(object, 'a.b.c', 'default');
12269      * // => 'default'
12270      */
12271     function get(object, path, defaultValue) {
12272       var result = object == null ? undefined : baseGet(object, path);
12273       return result === undefined ? defaultValue : result;
12274     }
12275
12276     /**
12277      * Checks if `path` is a direct property of `object`.
12278      *
12279      * @static
12280      * @since 0.1.0
12281      * @memberOf _
12282      * @category Object
12283      * @param {Object} object The object to query.
12284      * @param {Array|string} path The path to check.
12285      * @returns {boolean} Returns `true` if `path` exists, else `false`.
12286      * @example
12287      *
12288      * var object = { 'a': { 'b': 2 } };
12289      * var other = _.create({ 'a': _.create({ 'b': 2 }) });
12290      *
12291      * _.has(object, 'a');
12292      * // => true
12293      *
12294      * _.has(object, 'a.b');
12295      * // => true
12296      *
12297      * _.has(object, ['a', 'b']);
12298      * // => true
12299      *
12300      * _.has(other, 'a');
12301      * // => false
12302      */
12303     function has(object, path) {
12304       return object != null && hasPath(object, path, baseHas);
12305     }
12306
12307     /**
12308      * Checks if `path` is a direct or inherited property of `object`.
12309      *
12310      * @static
12311      * @memberOf _
12312      * @since 4.0.0
12313      * @category Object
12314      * @param {Object} object The object to query.
12315      * @param {Array|string} path The path to check.
12316      * @returns {boolean} Returns `true` if `path` exists, else `false`.
12317      * @example
12318      *
12319      * var object = _.create({ 'a': _.create({ 'b': 2 }) });
12320      *
12321      * _.hasIn(object, 'a');
12322      * // => true
12323      *
12324      * _.hasIn(object, 'a.b');
12325      * // => true
12326      *
12327      * _.hasIn(object, ['a', 'b']);
12328      * // => true
12329      *
12330      * _.hasIn(object, 'b');
12331      * // => false
12332      */
12333     function hasIn(object, path) {
12334       return object != null && hasPath(object, path, baseHasIn);
12335     }
12336
12337     /**
12338      * Creates an object composed of the inverted keys and values of `object`.
12339      * If `object` contains duplicate values, subsequent values overwrite
12340      * property assignments of previous values.
12341      *
12342      * @static
12343      * @memberOf _
12344      * @since 0.7.0
12345      * @category Object
12346      * @param {Object} object The object to invert.
12347      * @returns {Object} Returns the new inverted object.
12348      * @example
12349      *
12350      * var object = { 'a': 1, 'b': 2, 'c': 1 };
12351      *
12352      * _.invert(object);
12353      * // => { '1': 'c', '2': 'b' }
12354      */
12355     var invert = createInverter(function(result, value, key) {
12356       result[value] = key;
12357     }, constant(identity));
12358
12359     /**
12360      * This method is like `_.invert` except that the inverted object is generated
12361      * from the results of running each element of `object` thru `iteratee`. The
12362      * corresponding inverted value of each inverted key is an array of keys
12363      * responsible for generating the inverted value. The iteratee is invoked
12364      * with one argument: (value).
12365      *
12366      * @static
12367      * @memberOf _
12368      * @since 4.1.0
12369      * @category Object
12370      * @param {Object} object The object to invert.
12371      * @param {Array|Function|Object|string} [iteratee=_.identity]
12372      *  The iteratee invoked per element.
12373      * @returns {Object} Returns the new inverted object.
12374      * @example
12375      *
12376      * var object = { 'a': 1, 'b': 2, 'c': 1 };
12377      *
12378      * _.invertBy(object);
12379      * // => { '1': ['a', 'c'], '2': ['b'] }
12380      *
12381      * _.invertBy(object, function(value) {
12382      *   return 'group' + value;
12383      * });
12384      * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
12385      */
12386     var invertBy = createInverter(function(result, value, key) {
12387       if (hasOwnProperty.call(result, value)) {
12388         result[value].push(key);
12389       } else {
12390         result[value] = [key];
12391       }
12392     }, getIteratee);
12393
12394     /**
12395      * Invokes the method at `path` of `object`.
12396      *
12397      * @static
12398      * @memberOf _
12399      * @since 4.0.0
12400      * @category Object
12401      * @param {Object} object The object to query.
12402      * @param {Array|string} path The path of the method to invoke.
12403      * @param {...*} [args] The arguments to invoke the method with.
12404      * @returns {*} Returns the result of the invoked method.
12405      * @example
12406      *
12407      * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
12408      *
12409      * _.invoke(object, 'a[0].b.c.slice', 1, 3);
12410      * // => [2, 3]
12411      */
12412     var invoke = rest(baseInvoke);
12413
12414     /**
12415      * Creates an array of the own enumerable property names of `object`.
12416      *
12417      * **Note:** Non-object values are coerced to objects. See the
12418      * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
12419      * for more details.
12420      *
12421      * @static
12422      * @since 0.1.0
12423      * @memberOf _
12424      * @category Object
12425      * @param {Object} object The object to query.
12426      * @returns {Array} Returns the array of property names.
12427      * @example
12428      *
12429      * function Foo() {
12430      *   this.a = 1;
12431      *   this.b = 2;
12432      * }
12433      *
12434      * Foo.prototype.c = 3;
12435      *
12436      * _.keys(new Foo);
12437      * // => ['a', 'b'] (iteration order is not guaranteed)
12438      *
12439      * _.keys('hi');
12440      * // => ['0', '1']
12441      */
12442     function keys(object) {
12443       var isProto = isPrototype(object);
12444       if (!(isProto || isArrayLike(object))) {
12445         return baseKeys(object);
12446       }
12447       var indexes = indexKeys(object),
12448           skipIndexes = !!indexes,
12449           result = indexes || [],
12450           length = result.length;
12451
12452       for (var key in object) {
12453         if (baseHas(object, key) &&
12454             !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
12455             !(isProto && key == 'constructor')) {
12456           result.push(key);
12457         }
12458       }
12459       return result;
12460     }
12461
12462     /**
12463      * Creates an array of the own and inherited enumerable property names of `object`.
12464      *
12465      * **Note:** Non-object values are coerced to objects.
12466      *
12467      * @static
12468      * @memberOf _
12469      * @since 3.0.0
12470      * @category Object
12471      * @param {Object} object The object to query.
12472      * @returns {Array} Returns the array of property names.
12473      * @example
12474      *
12475      * function Foo() {
12476      *   this.a = 1;
12477      *   this.b = 2;
12478      * }
12479      *
12480      * Foo.prototype.c = 3;
12481      *
12482      * _.keysIn(new Foo);
12483      * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
12484      */
12485     function keysIn(object) {
12486       var index = -1,
12487           isProto = isPrototype(object),
12488           props = baseKeysIn(object),
12489           propsLength = props.length,
12490           indexes = indexKeys(object),
12491           skipIndexes = !!indexes,
12492           result = indexes || [],
12493           length = result.length;
12494
12495       while (++index < propsLength) {
12496         var key = props[index];
12497         if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
12498             !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
12499           result.push(key);
12500         }
12501       }
12502       return result;
12503     }
12504
12505     /**
12506      * The opposite of `_.mapValues`; this method creates an object with the
12507      * same values as `object` and keys generated by running each own enumerable
12508      * string keyed property of `object` thru `iteratee`. The iteratee is invoked
12509      * with three arguments: (value, key, object).
12510      *
12511      * @static
12512      * @memberOf _
12513      * @since 3.8.0
12514      * @category Object
12515      * @param {Object} object The object to iterate over.
12516      * @param {Array|Function|Object|string} [iteratee=_.identity]
12517      *  The function invoked per iteration.
12518      * @returns {Object} Returns the new mapped object.
12519      * @see _.mapValues
12520      * @example
12521      *
12522      * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
12523      *   return key + value;
12524      * });
12525      * // => { 'a1': 1, 'b2': 2 }
12526      */
12527     function mapKeys(object, iteratee) {
12528       var result = {};
12529       iteratee = getIteratee(iteratee, 3);
12530
12531       baseForOwn(object, function(value, key, object) {
12532         result[iteratee(value, key, object)] = value;
12533       });
12534       return result;
12535     }
12536
12537     /**
12538      * Creates an object with the same keys as `object` and values generated
12539      * by running each own enumerable string keyed property of `object` thru
12540      * `iteratee`. The iteratee is invoked with three arguments:
12541      * (value, key, object).
12542      *
12543      * @static
12544      * @memberOf _
12545      * @since 2.4.0
12546      * @category Object
12547      * @param {Object} object The object to iterate over.
12548      * @param {Array|Function|Object|string} [iteratee=_.identity]
12549      *  The function invoked per iteration.
12550      * @returns {Object} Returns the new mapped object.
12551      * @see _.mapKeys
12552      * @example
12553      *
12554      * var users = {
12555      *   'fred':    { 'user': 'fred',    'age': 40 },
12556      *   'pebbles': { 'user': 'pebbles', 'age': 1 }
12557      * };
12558      *
12559      * _.mapValues(users, function(o) { return o.age; });
12560      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
12561      *
12562      * // The `_.property` iteratee shorthand.
12563      * _.mapValues(users, 'age');
12564      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
12565      */
12566     function mapValues(object, iteratee) {
12567       var result = {};
12568       iteratee = getIteratee(iteratee, 3);
12569
12570       baseForOwn(object, function(value, key, object) {
12571         result[key] = iteratee(value, key, object);
12572       });
12573       return result;
12574     }
12575
12576     /**
12577      * This method is like `_.assign` except that it recursively merges own and
12578      * inherited enumerable string keyed properties of source objects into the
12579      * destination object. Source properties that resolve to `undefined` are
12580      * skipped if a destination value exists. Array and plain object properties
12581      * are merged recursively.Other objects and value types are overridden by
12582      * assignment. Source objects are applied from left to right. Subsequent
12583      * sources overwrite property assignments of previous sources.
12584      *
12585      * **Note:** This method mutates `object`.
12586      *
12587      * @static
12588      * @memberOf _
12589      * @since 0.5.0
12590      * @category Object
12591      * @param {Object} object The destination object.
12592      * @param {...Object} [sources] The source objects.
12593      * @returns {Object} Returns `object`.
12594      * @example
12595      *
12596      * var users = {
12597      *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
12598      * };
12599      *
12600      * var ages = {
12601      *   'data': [{ 'age': 36 }, { 'age': 40 }]
12602      * };
12603      *
12604      * _.merge(users, ages);
12605      * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
12606      */
12607     var merge = createAssigner(function(object, source, srcIndex) {
12608       baseMerge(object, source, srcIndex);
12609     });
12610
12611     /**
12612      * This method is like `_.merge` except that it accepts `customizer` which
12613      * is invoked to produce the merged values of the destination and source
12614      * properties. If `customizer` returns `undefined`, merging is handled by the
12615      * method instead. The `customizer` is invoked with seven arguments:
12616      * (objValue, srcValue, key, object, source, stack).
12617      *
12618      * **Note:** This method mutates `object`.
12619      *
12620      * @static
12621      * @memberOf _
12622      * @since 4.0.0
12623      * @category Object
12624      * @param {Object} object The destination object.
12625      * @param {...Object} sources The source objects.
12626      * @param {Function} customizer The function to customize assigned values.
12627      * @returns {Object} Returns `object`.
12628      * @example
12629      *
12630      * function customizer(objValue, srcValue) {
12631      *   if (_.isArray(objValue)) {
12632      *     return objValue.concat(srcValue);
12633      *   }
12634      * }
12635      *
12636      * var object = {
12637      *   'fruits': ['apple'],
12638      *   'vegetables': ['beet']
12639      * };
12640      *
12641      * var other = {
12642      *   'fruits': ['banana'],
12643      *   'vegetables': ['carrot']
12644      * };
12645      *
12646      * _.mergeWith(object, other, customizer);
12647      * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
12648      */
12649     var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
12650       baseMerge(object, source, srcIndex, customizer);
12651     });
12652
12653     /**
12654      * The opposite of `_.pick`; this method creates an object composed of the
12655      * own and inherited enumerable string keyed properties of `object` that are
12656      * not omitted.
12657      *
12658      * @static
12659      * @since 0.1.0
12660      * @memberOf _
12661      * @category Object
12662      * @param {Object} object The source object.
12663      * @param {...(string|string[])} [props] The property identifiers to omit.
12664      * @returns {Object} Returns the new object.
12665      * @example
12666      *
12667      * var object = { 'a': 1, 'b': '2', 'c': 3 };
12668      *
12669      * _.omit(object, ['a', 'c']);
12670      * // => { 'b': '2' }
12671      */
12672     var omit = rest(function(object, props) {
12673       if (object == null) {
12674         return {};
12675       }
12676       props = arrayMap(baseFlatten(props, 1), toKey);
12677       return basePick(object, baseDifference(getAllKeysIn(object), props));
12678     });
12679
12680     /**
12681      * The opposite of `_.pickBy`; this method creates an object composed of
12682      * the own and inherited enumerable string keyed properties of `object` that
12683      * `predicate` doesn't return truthy for. The predicate is invoked with two
12684      * arguments: (value, key).
12685      *
12686      * @static
12687      * @memberOf _
12688      * @since 4.0.0
12689      * @category Object
12690      * @param {Object} object The source object.
12691      * @param {Array|Function|Object|string} [predicate=_.identity]
12692      *  The function invoked per property.
12693      * @returns {Object} Returns the new object.
12694      * @example
12695      *
12696      * var object = { 'a': 1, 'b': '2', 'c': 3 };
12697      *
12698      * _.omitBy(object, _.isNumber);
12699      * // => { 'b': '2' }
12700      */
12701     function omitBy(object, predicate) {
12702       predicate = getIteratee(predicate);
12703       return basePickBy(object, function(value, key) {
12704         return !predicate(value, key);
12705       });
12706     }
12707
12708     /**
12709      * Creates an object composed of the picked `object` properties.
12710      *
12711      * @static
12712      * @since 0.1.0
12713      * @memberOf _
12714      * @category Object
12715      * @param {Object} object The source object.
12716      * @param {...(string|string[])} [props] The property identifiers to pick.
12717      * @returns {Object} Returns the new object.
12718      * @example
12719      *
12720      * var object = { 'a': 1, 'b': '2', 'c': 3 };
12721      *
12722      * _.pick(object, ['a', 'c']);
12723      * // => { 'a': 1, 'c': 3 }
12724      */
12725     var pick = rest(function(object, props) {
12726       return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey));
12727     });
12728
12729     /**
12730      * Creates an object composed of the `object` properties `predicate` returns
12731      * truthy for. The predicate is invoked with two arguments: (value, key).
12732      *
12733      * @static
12734      * @memberOf _
12735      * @since 4.0.0
12736      * @category Object
12737      * @param {Object} object The source object.
12738      * @param {Array|Function|Object|string} [predicate=_.identity]
12739      *  The function invoked per property.
12740      * @returns {Object} Returns the new object.
12741      * @example
12742      *
12743      * var object = { 'a': 1, 'b': '2', 'c': 3 };
12744      *
12745      * _.pickBy(object, _.isNumber);
12746      * // => { 'a': 1, 'c': 3 }
12747      */
12748     function pickBy(object, predicate) {
12749       return object == null ? {} : basePickBy(object, getIteratee(predicate));
12750     }
12751
12752     /**
12753      * This method is like `_.get` except that if the resolved value is a
12754      * function it's invoked with the `this` binding of its parent object and
12755      * its result is returned.
12756      *
12757      * @static
12758      * @since 0.1.0
12759      * @memberOf _
12760      * @category Object
12761      * @param {Object} object The object to query.
12762      * @param {Array|string} path The path of the property to resolve.
12763      * @param {*} [defaultValue] The value returned for `undefined` resolved values.
12764      * @returns {*} Returns the resolved value.
12765      * @example
12766      *
12767      * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
12768      *
12769      * _.result(object, 'a[0].b.c1');
12770      * // => 3
12771      *
12772      * _.result(object, 'a[0].b.c2');
12773      * // => 4
12774      *
12775      * _.result(object, 'a[0].b.c3', 'default');
12776      * // => 'default'
12777      *
12778      * _.result(object, 'a[0].b.c3', _.constant('default'));
12779      * // => 'default'
12780      */
12781     function result(object, path, defaultValue) {
12782       path = isKey(path, object) ? [path] : castPath(path);
12783
12784       var index = -1,
12785           length = path.length;
12786
12787       // Ensure the loop is entered when path is empty.
12788       if (!length) {
12789         object = undefined;
12790         length = 1;
12791       }
12792       while (++index < length) {
12793         var value = object == null ? undefined : object[toKey(path[index])];
12794         if (value === undefined) {
12795           index = length;
12796           value = defaultValue;
12797         }
12798         object = isFunction(value) ? value.call(object) : value;
12799       }
12800       return object;
12801     }
12802
12803     /**
12804      * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
12805      * it's created. Arrays are created for missing index properties while objects
12806      * are created for all other missing properties. Use `_.setWith` to customize
12807      * `path` creation.
12808      *
12809      * **Note:** This method mutates `object`.
12810      *
12811      * @static
12812      * @memberOf _
12813      * @since 3.7.0
12814      * @category Object
12815      * @param {Object} object The object to modify.
12816      * @param {Array|string} path The path of the property to set.
12817      * @param {*} value The value to set.
12818      * @returns {Object} Returns `object`.
12819      * @example
12820      *
12821      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
12822      *
12823      * _.set(object, 'a[0].b.c', 4);
12824      * console.log(object.a[0].b.c);
12825      * // => 4
12826      *
12827      * _.set(object, ['x', '0', 'y', 'z'], 5);
12828      * console.log(object.x[0].y.z);
12829      * // => 5
12830      */
12831     function set(object, path, value) {
12832       return object == null ? object : baseSet(object, path, value);
12833     }
12834
12835     /**
12836      * This method is like `_.set` except that it accepts `customizer` which is
12837      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
12838      * path creation is handled by the method instead. The `customizer` is invoked
12839      * with three arguments: (nsValue, key, nsObject).
12840      *
12841      * **Note:** This method mutates `object`.
12842      *
12843      * @static
12844      * @memberOf _
12845      * @since 4.0.0
12846      * @category Object
12847      * @param {Object} object The object to modify.
12848      * @param {Array|string} path The path of the property to set.
12849      * @param {*} value The value to set.
12850      * @param {Function} [customizer] The function to customize assigned values.
12851      * @returns {Object} Returns `object`.
12852      * @example
12853      *
12854      * var object = {};
12855      *
12856      * _.setWith(object, '[0][1]', 'a', Object);
12857      * // => { '0': { '1': 'a' } }
12858      */
12859     function setWith(object, path, value, customizer) {
12860       customizer = typeof customizer == 'function' ? customizer : undefined;
12861       return object == null ? object : baseSet(object, path, value, customizer);
12862     }
12863
12864     /**
12865      * Creates an array of own enumerable string keyed-value pairs for `object`
12866      * which can be consumed by `_.fromPairs`.
12867      *
12868      * @static
12869      * @memberOf _
12870      * @since 4.0.0
12871      * @alias entries
12872      * @category Object
12873      * @param {Object} object The object to query.
12874      * @returns {Array} Returns the new array of key-value pairs.
12875      * @example
12876      *
12877      * function Foo() {
12878      *   this.a = 1;
12879      *   this.b = 2;
12880      * }
12881      *
12882      * Foo.prototype.c = 3;
12883      *
12884      * _.toPairs(new Foo);
12885      * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
12886      */
12887     function toPairs(object) {
12888       return baseToPairs(object, keys(object));
12889     }
12890
12891     /**
12892      * Creates an array of own and inherited enumerable string keyed-value pairs
12893      * for `object` which can be consumed by `_.fromPairs`.
12894      *
12895      * @static
12896      * @memberOf _
12897      * @since 4.0.0
12898      * @alias entriesIn
12899      * @category Object
12900      * @param {Object} object The object to query.
12901      * @returns {Array} Returns the new array of key-value pairs.
12902      * @example
12903      *
12904      * function Foo() {
12905      *   this.a = 1;
12906      *   this.b = 2;
12907      * }
12908      *
12909      * Foo.prototype.c = 3;
12910      *
12911      * _.toPairsIn(new Foo);
12912      * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
12913      */
12914     function toPairsIn(object) {
12915       return baseToPairs(object, keysIn(object));
12916     }
12917
12918     /**
12919      * An alternative to `_.reduce`; this method transforms `object` to a new
12920      * `accumulator` object which is the result of running each of its own
12921      * enumerable string keyed properties thru `iteratee`, with each invocation
12922      * potentially mutating the `accumulator` object. The iteratee is invoked
12923      * with four arguments: (accumulator, value, key, object). Iteratee functions
12924      * may exit iteration early by explicitly returning `false`.
12925      *
12926      * @static
12927      * @memberOf _
12928      * @since 1.3.0
12929      * @category Object
12930      * @param {Array|Object} object The object to iterate over.
12931      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12932      * @param {*} [accumulator] The custom accumulator value.
12933      * @returns {*} Returns the accumulated value.
12934      * @example
12935      *
12936      * _.transform([2, 3, 4], function(result, n) {
12937      *   result.push(n *= n);
12938      *   return n % 2 == 0;
12939      * }, []);
12940      * // => [4, 9]
12941      *
12942      * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
12943      *   (result[value] || (result[value] = [])).push(key);
12944      * }, {});
12945      * // => { '1': ['a', 'c'], '2': ['b'] }
12946      */
12947     function transform(object, iteratee, accumulator) {
12948       var isArr = isArray(object) || isTypedArray(object);
12949       iteratee = getIteratee(iteratee, 4);
12950
12951       if (accumulator == null) {
12952         if (isArr || isObject(object)) {
12953           var Ctor = object.constructor;
12954           if (isArr) {
12955             accumulator = isArray(object) ? new Ctor : [];
12956           } else {
12957             accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
12958           }
12959         } else {
12960           accumulator = {};
12961         }
12962       }
12963       (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
12964         return iteratee(accumulator, value, index, object);
12965       });
12966       return accumulator;
12967     }
12968
12969     /**
12970      * Removes the property at `path` of `object`.
12971      *
12972      * **Note:** This method mutates `object`.
12973      *
12974      * @static
12975      * @memberOf _
12976      * @since 4.0.0
12977      * @category Object
12978      * @param {Object} object The object to modify.
12979      * @param {Array|string} path The path of the property to unset.
12980      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
12981      * @example
12982      *
12983      * var object = { 'a': [{ 'b': { 'c': 7 } }] };
12984      * _.unset(object, 'a[0].b.c');
12985      * // => true
12986      *
12987      * console.log(object);
12988      * // => { 'a': [{ 'b': {} }] };
12989      *
12990      * _.unset(object, ['a', '0', 'b', 'c']);
12991      * // => true
12992      *
12993      * console.log(object);
12994      * // => { 'a': [{ 'b': {} }] };
12995      */
12996     function unset(object, path) {
12997       return object == null ? true : baseUnset(object, path);
12998     }
12999
13000     /**
13001      * This method is like `_.set` except that accepts `updater` to produce the
13002      * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
13003      * is invoked with one argument: (value).
13004      *
13005      * **Note:** This method mutates `object`.
13006      *
13007      * @static
13008      * @memberOf _
13009      * @since 4.6.0
13010      * @category Object
13011      * @param {Object} object The object to modify.
13012      * @param {Array|string} path The path of the property to set.
13013      * @param {Function} updater The function to produce the updated value.
13014      * @returns {Object} Returns `object`.
13015      * @example
13016      *
13017      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13018      *
13019      * _.update(object, 'a[0].b.c', function(n) { return n * n; });
13020      * console.log(object.a[0].b.c);
13021      * // => 9
13022      *
13023      * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
13024      * console.log(object.x[0].y.z);
13025      * // => 0
13026      */
13027     function update(object, path, updater) {
13028       return object == null ? object : baseUpdate(object, path, castFunction(updater));
13029     }
13030
13031     /**
13032      * This method is like `_.update` except that it accepts `customizer` which is
13033      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
13034      * path creation is handled by the method instead. The `customizer` is invoked
13035      * with three arguments: (nsValue, key, nsObject).
13036      *
13037      * **Note:** This method mutates `object`.
13038      *
13039      * @static
13040      * @memberOf _
13041      * @since 4.6.0
13042      * @category Object
13043      * @param {Object} object The object to modify.
13044      * @param {Array|string} path The path of the property to set.
13045      * @param {Function} updater The function to produce the updated value.
13046      * @param {Function} [customizer] The function to customize assigned values.
13047      * @returns {Object} Returns `object`.
13048      * @example
13049      *
13050      * var object = {};
13051      *
13052      * _.updateWith(object, '[0][1]', _.constant('a'), Object);
13053      * // => { '0': { '1': 'a' } }
13054      */
13055     function updateWith(object, path, updater, customizer) {
13056       customizer = typeof customizer == 'function' ? customizer : undefined;
13057       return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
13058     }
13059
13060     /**
13061      * Creates an array of the own enumerable string keyed property values of `object`.
13062      *
13063      * **Note:** Non-object values are coerced to objects.
13064      *
13065      * @static
13066      * @since 0.1.0
13067      * @memberOf _
13068      * @category Object
13069      * @param {Object} object The object to query.
13070      * @returns {Array} Returns the array of property values.
13071      * @example
13072      *
13073      * function Foo() {
13074      *   this.a = 1;
13075      *   this.b = 2;
13076      * }
13077      *
13078      * Foo.prototype.c = 3;
13079      *
13080      * _.values(new Foo);
13081      * // => [1, 2] (iteration order is not guaranteed)
13082      *
13083      * _.values('hi');
13084      * // => ['h', 'i']
13085      */
13086     function values(object) {
13087       return object ? baseValues(object, keys(object)) : [];
13088     }
13089
13090     /**
13091      * Creates an array of the own and inherited enumerable string keyed property
13092      * values of `object`.
13093      *
13094      * **Note:** Non-object values are coerced to objects.
13095      *
13096      * @static
13097      * @memberOf _
13098      * @since 3.0.0
13099      * @category Object
13100      * @param {Object} object The object to query.
13101      * @returns {Array} Returns the array of property values.
13102      * @example
13103      *
13104      * function Foo() {
13105      *   this.a = 1;
13106      *   this.b = 2;
13107      * }
13108      *
13109      * Foo.prototype.c = 3;
13110      *
13111      * _.valuesIn(new Foo);
13112      * // => [1, 2, 3] (iteration order is not guaranteed)
13113      */
13114     function valuesIn(object) {
13115       return object == null ? [] : baseValues(object, keysIn(object));
13116     }
13117
13118     /*------------------------------------------------------------------------*/
13119
13120     /**
13121      * Clamps `number` within the inclusive `lower` and `upper` bounds.
13122      *
13123      * @static
13124      * @memberOf _
13125      * @since 4.0.0
13126      * @category Number
13127      * @param {number} number The number to clamp.
13128      * @param {number} [lower] The lower bound.
13129      * @param {number} upper The upper bound.
13130      * @returns {number} Returns the clamped number.
13131      * @example
13132      *
13133      * _.clamp(-10, -5, 5);
13134      * // => -5
13135      *
13136      * _.clamp(10, -5, 5);
13137      * // => 5
13138      */
13139     function clamp(number, lower, upper) {
13140       if (upper === undefined) {
13141         upper = lower;
13142         lower = undefined;
13143       }
13144       if (upper !== undefined) {
13145         upper = toNumber(upper);
13146         upper = upper === upper ? upper : 0;
13147       }
13148       if (lower !== undefined) {
13149         lower = toNumber(lower);
13150         lower = lower === lower ? lower : 0;
13151       }
13152       return baseClamp(toNumber(number), lower, upper);
13153     }
13154
13155     /**
13156      * Checks if `n` is between `start` and up to, but not including, `end`. If
13157      * `end` is not specified, it's set to `start` with `start` then set to `0`.
13158      * If `start` is greater than `end` the params are swapped to support
13159      * negative ranges.
13160      *
13161      * @static
13162      * @memberOf _
13163      * @since 3.3.0
13164      * @category Number
13165      * @param {number} number The number to check.
13166      * @param {number} [start=0] The start of the range.
13167      * @param {number} end The end of the range.
13168      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
13169      * @see _.range, _.rangeRight
13170      * @example
13171      *
13172      * _.inRange(3, 2, 4);
13173      * // => true
13174      *
13175      * _.inRange(4, 8);
13176      * // => true
13177      *
13178      * _.inRange(4, 2);
13179      * // => false
13180      *
13181      * _.inRange(2, 2);
13182      * // => false
13183      *
13184      * _.inRange(1.2, 2);
13185      * // => true
13186      *
13187      * _.inRange(5.2, 4);
13188      * // => false
13189      *
13190      * _.inRange(-3, -2, -6);
13191      * // => true
13192      */
13193     function inRange(number, start, end) {
13194       start = toNumber(start) || 0;
13195       if (end === undefined) {
13196         end = start;
13197         start = 0;
13198       } else {
13199         end = toNumber(end) || 0;
13200       }
13201       number = toNumber(number);
13202       return baseInRange(number, start, end);
13203     }
13204
13205     /**
13206      * Produces a random number between the inclusive `lower` and `upper` bounds.
13207      * If only one argument is provided a number between `0` and the given number
13208      * is returned. If `floating` is `true`, or either `lower` or `upper` are
13209      * floats, a floating-point number is returned instead of an integer.
13210      *
13211      * **Note:** JavaScript follows the IEEE-754 standard for resolving
13212      * floating-point values which can produce unexpected results.
13213      *
13214      * @static
13215      * @memberOf _
13216      * @since 0.7.0
13217      * @category Number
13218      * @param {number} [lower=0] The lower bound.
13219      * @param {number} [upper=1] The upper bound.
13220      * @param {boolean} [floating] Specify returning a floating-point number.
13221      * @returns {number} Returns the random number.
13222      * @example
13223      *
13224      * _.random(0, 5);
13225      * // => an integer between 0 and 5
13226      *
13227      * _.random(5);
13228      * // => also an integer between 0 and 5
13229      *
13230      * _.random(5, true);
13231      * // => a floating-point number between 0 and 5
13232      *
13233      * _.random(1.2, 5.2);
13234      * // => a floating-point number between 1.2 and 5.2
13235      */
13236     function random(lower, upper, floating) {
13237       if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
13238         upper = floating = undefined;
13239       }
13240       if (floating === undefined) {
13241         if (typeof upper == 'boolean') {
13242           floating = upper;
13243           upper = undefined;
13244         }
13245         else if (typeof lower == 'boolean') {
13246           floating = lower;
13247           lower = undefined;
13248         }
13249       }
13250       if (lower === undefined && upper === undefined) {
13251         lower = 0;
13252         upper = 1;
13253       }
13254       else {
13255         lower = toNumber(lower) || 0;
13256         if (upper === undefined) {
13257           upper = lower;
13258           lower = 0;
13259         } else {
13260           upper = toNumber(upper) || 0;
13261         }
13262       }
13263       if (lower > upper) {
13264         var temp = lower;
13265         lower = upper;
13266         upper = temp;
13267       }
13268       if (floating || lower % 1 || upper % 1) {
13269         var rand = nativeRandom();
13270         return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
13271       }
13272       return baseRandom(lower, upper);
13273     }
13274
13275     /*------------------------------------------------------------------------*/
13276
13277     /**
13278      * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
13279      *
13280      * @static
13281      * @memberOf _
13282      * @since 3.0.0
13283      * @category String
13284      * @param {string} [string=''] The string to convert.
13285      * @returns {string} Returns the camel cased string.
13286      * @example
13287      *
13288      * _.camelCase('Foo Bar');
13289      * // => 'fooBar'
13290      *
13291      * _.camelCase('--foo-bar--');
13292      * // => 'fooBar'
13293      *
13294      * _.camelCase('__FOO_BAR__');
13295      * // => 'fooBar'
13296      */
13297     var camelCase = createCompounder(function(result, word, index) {
13298       word = word.toLowerCase();
13299       return result + (index ? capitalize(word) : word);
13300     });
13301
13302     /**
13303      * Converts the first character of `string` to upper case and the remaining
13304      * to lower case.
13305      *
13306      * @static
13307      * @memberOf _
13308      * @since 3.0.0
13309      * @category String
13310      * @param {string} [string=''] The string to capitalize.
13311      * @returns {string} Returns the capitalized string.
13312      * @example
13313      *
13314      * _.capitalize('FRED');
13315      * // => 'Fred'
13316      */
13317     function capitalize(string) {
13318       return upperFirst(toString(string).toLowerCase());
13319     }
13320
13321     /**
13322      * Deburrs `string` by converting
13323      * [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
13324      * to basic latin letters and removing
13325      * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
13326      *
13327      * @static
13328      * @memberOf _
13329      * @since 3.0.0
13330      * @category String
13331      * @param {string} [string=''] The string to deburr.
13332      * @returns {string} Returns the deburred string.
13333      * @example
13334      *
13335      * _.deburr('déjà vu');
13336      * // => 'deja vu'
13337      */
13338     function deburr(string) {
13339       string = toString(string);
13340       return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
13341     }
13342
13343     /**
13344      * Checks if `string` ends with the given target string.
13345      *
13346      * @static
13347      * @memberOf _
13348      * @since 3.0.0
13349      * @category String
13350      * @param {string} [string=''] The string to search.
13351      * @param {string} [target] The string to search for.
13352      * @param {number} [position=string.length] The position to search from.
13353      * @returns {boolean} Returns `true` if `string` ends with `target`,
13354      *  else `false`.
13355      * @example
13356      *
13357      * _.endsWith('abc', 'c');
13358      * // => true
13359      *
13360      * _.endsWith('abc', 'b');
13361      * // => false
13362      *
13363      * _.endsWith('abc', 'b', 2);
13364      * // => true
13365      */
13366     function endsWith(string, target, position) {
13367       string = toString(string);
13368       target = baseToString(target);
13369
13370       var length = string.length;
13371       position = position === undefined
13372         ? length
13373         : baseClamp(toInteger(position), 0, length);
13374
13375       position -= target.length;
13376       return position >= 0 && string.indexOf(target, position) == position;
13377     }
13378
13379     /**
13380      * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
13381      * their corresponding HTML entities.
13382      *
13383      * **Note:** No other characters are escaped. To escape additional
13384      * characters use a third-party library like [_he_](https://mths.be/he).
13385      *
13386      * Though the ">" character is escaped for symmetry, characters like
13387      * ">" and "/" don't need escaping in HTML and have no special meaning
13388      * unless they're part of a tag or unquoted attribute value. See
13389      * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
13390      * (under "semi-related fun fact") for more details.
13391      *
13392      * Backticks are escaped because in IE < 9, they can break out of
13393      * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
13394      * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
13395      * [#133](https://html5sec.org/#133) of the
13396      * [HTML5 Security Cheatsheet](https://html5sec.org/) for more details.
13397      *
13398      * When working with HTML you should always
13399      * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
13400      * XSS vectors.
13401      *
13402      * @static
13403      * @since 0.1.0
13404      * @memberOf _
13405      * @category String
13406      * @param {string} [string=''] The string to escape.
13407      * @returns {string} Returns the escaped string.
13408      * @example
13409      *
13410      * _.escape('fred, barney, & pebbles');
13411      * // => 'fred, barney, &amp; pebbles'
13412      */
13413     function escape(string) {
13414       string = toString(string);
13415       return (string && reHasUnescapedHtml.test(string))
13416         ? string.replace(reUnescapedHtml, escapeHtmlChar)
13417         : string;
13418     }
13419
13420     /**
13421      * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
13422      * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
13423      *
13424      * @static
13425      * @memberOf _
13426      * @since 3.0.0
13427      * @category String
13428      * @param {string} [string=''] The string to escape.
13429      * @returns {string} Returns the escaped string.
13430      * @example
13431      *
13432      * _.escapeRegExp('[lodash](https://lodash.com/)');
13433      * // => '\[lodash\]\(https://lodash\.com/\)'
13434      */
13435     function escapeRegExp(string) {
13436       string = toString(string);
13437       return (string && reHasRegExpChar.test(string))
13438         ? string.replace(reRegExpChar, '\\$&')
13439         : string;
13440     }
13441
13442     /**
13443      * Converts `string` to
13444      * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
13445      *
13446      * @static
13447      * @memberOf _
13448      * @since 3.0.0
13449      * @category String
13450      * @param {string} [string=''] The string to convert.
13451      * @returns {string} Returns the kebab cased string.
13452      * @example
13453      *
13454      * _.kebabCase('Foo Bar');
13455      * // => 'foo-bar'
13456      *
13457      * _.kebabCase('fooBar');
13458      * // => 'foo-bar'
13459      *
13460      * _.kebabCase('__FOO_BAR__');
13461      * // => 'foo-bar'
13462      */
13463     var kebabCase = createCompounder(function(result, word, index) {
13464       return result + (index ? '-' : '') + word.toLowerCase();
13465     });
13466
13467     /**
13468      * Converts `string`, as space separated words, to lower case.
13469      *
13470      * @static
13471      * @memberOf _
13472      * @since 4.0.0
13473      * @category String
13474      * @param {string} [string=''] The string to convert.
13475      * @returns {string} Returns the lower cased string.
13476      * @example
13477      *
13478      * _.lowerCase('--Foo-Bar--');
13479      * // => 'foo bar'
13480      *
13481      * _.lowerCase('fooBar');
13482      * // => 'foo bar'
13483      *
13484      * _.lowerCase('__FOO_BAR__');
13485      * // => 'foo bar'
13486      */
13487     var lowerCase = createCompounder(function(result, word, index) {
13488       return result + (index ? ' ' : '') + word.toLowerCase();
13489     });
13490
13491     /**
13492      * Converts the first character of `string` to lower case.
13493      *
13494      * @static
13495      * @memberOf _
13496      * @since 4.0.0
13497      * @category String
13498      * @param {string} [string=''] The string to convert.
13499      * @returns {string} Returns the converted string.
13500      * @example
13501      *
13502      * _.lowerFirst('Fred');
13503      * // => 'fred'
13504      *
13505      * _.lowerFirst('FRED');
13506      * // => 'fRED'
13507      */
13508     var lowerFirst = createCaseFirst('toLowerCase');
13509
13510     /**
13511      * Pads `string` on the left and right sides if it's shorter than `length`.
13512      * Padding characters are truncated if they can't be evenly divided by `length`.
13513      *
13514      * @static
13515      * @memberOf _
13516      * @since 3.0.0
13517      * @category String
13518      * @param {string} [string=''] The string to pad.
13519      * @param {number} [length=0] The padding length.
13520      * @param {string} [chars=' '] The string used as padding.
13521      * @returns {string} Returns the padded string.
13522      * @example
13523      *
13524      * _.pad('abc', 8);
13525      * // => '  abc   '
13526      *
13527      * _.pad('abc', 8, '_-');
13528      * // => '_-abc_-_'
13529      *
13530      * _.pad('abc', 3);
13531      * // => 'abc'
13532      */
13533     function pad(string, length, chars) {
13534       string = toString(string);
13535       length = toInteger(length);
13536
13537       var strLength = length ? stringSize(string) : 0;
13538       if (!length || strLength >= length) {
13539         return string;
13540       }
13541       var mid = (length - strLength) / 2;
13542       return (
13543         createPadding(nativeFloor(mid), chars) +
13544         string +
13545         createPadding(nativeCeil(mid), chars)
13546       );
13547     }
13548
13549     /**
13550      * Pads `string` on the right side if it's shorter than `length`. Padding
13551      * characters are truncated if they exceed `length`.
13552      *
13553      * @static
13554      * @memberOf _
13555      * @since 4.0.0
13556      * @category String
13557      * @param {string} [string=''] The string to pad.
13558      * @param {number} [length=0] The padding length.
13559      * @param {string} [chars=' '] The string used as padding.
13560      * @returns {string} Returns the padded string.
13561      * @example
13562      *
13563      * _.padEnd('abc', 6);
13564      * // => 'abc   '
13565      *
13566      * _.padEnd('abc', 6, '_-');
13567      * // => 'abc_-_'
13568      *
13569      * _.padEnd('abc', 3);
13570      * // => 'abc'
13571      */
13572     function padEnd(string, length, chars) {
13573       string = toString(string);
13574       length = toInteger(length);
13575
13576       var strLength = length ? stringSize(string) : 0;
13577       return (length && strLength < length)
13578         ? (string + createPadding(length - strLength, chars))
13579         : string;
13580     }
13581
13582     /**
13583      * Pads `string` on the left side if it's shorter than `length`. Padding
13584      * characters are truncated if they exceed `length`.
13585      *
13586      * @static
13587      * @memberOf _
13588      * @since 4.0.0
13589      * @category String
13590      * @param {string} [string=''] The string to pad.
13591      * @param {number} [length=0] The padding length.
13592      * @param {string} [chars=' '] The string used as padding.
13593      * @returns {string} Returns the padded string.
13594      * @example
13595      *
13596      * _.padStart('abc', 6);
13597      * // => '   abc'
13598      *
13599      * _.padStart('abc', 6, '_-');
13600      * // => '_-_abc'
13601      *
13602      * _.padStart('abc', 3);
13603      * // => 'abc'
13604      */
13605     function padStart(string, length, chars) {
13606       string = toString(string);
13607       length = toInteger(length);
13608
13609       var strLength = length ? stringSize(string) : 0;
13610       return (length && strLength < length)
13611         ? (createPadding(length - strLength, chars) + string)
13612         : string;
13613     }
13614
13615     /**
13616      * Converts `string` to an integer of the specified radix. If `radix` is
13617      * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
13618      * hexadecimal, in which case a `radix` of `16` is used.
13619      *
13620      * **Note:** This method aligns with the
13621      * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
13622      *
13623      * @static
13624      * @memberOf _
13625      * @since 1.1.0
13626      * @category String
13627      * @param {string} string The string to convert.
13628      * @param {number} [radix=10] The radix to interpret `value` by.
13629      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
13630      * @returns {number} Returns the converted integer.
13631      * @example
13632      *
13633      * _.parseInt('08');
13634      * // => 8
13635      *
13636      * _.map(['6', '08', '10'], _.parseInt);
13637      * // => [6, 8, 10]
13638      */
13639     function parseInt(string, radix, guard) {
13640       // Chrome fails to trim leading <BOM> whitespace characters.
13641       // See https://bugs.chromium.org/p/v8/issues/detail?id=3109 for more details.
13642       if (guard || radix == null) {
13643         radix = 0;
13644       } else if (radix) {
13645         radix = +radix;
13646       }
13647       string = toString(string).replace(reTrim, '');
13648       return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
13649     }
13650
13651     /**
13652      * Repeats the given string `n` times.
13653      *
13654      * @static
13655      * @memberOf _
13656      * @since 3.0.0
13657      * @category String
13658      * @param {string} [string=''] The string to repeat.
13659      * @param {number} [n=1] The number of times to repeat the string.
13660      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
13661      * @returns {string} Returns the repeated string.
13662      * @example
13663      *
13664      * _.repeat('*', 3);
13665      * // => '***'
13666      *
13667      * _.repeat('abc', 2);
13668      * // => 'abcabc'
13669      *
13670      * _.repeat('abc', 0);
13671      * // => ''
13672      */
13673     function repeat(string, n, guard) {
13674       if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
13675         n = 1;
13676       } else {
13677         n = toInteger(n);
13678       }
13679       return baseRepeat(toString(string), n);
13680     }
13681
13682     /**
13683      * Replaces matches for `pattern` in `string` with `replacement`.
13684      *
13685      * **Note:** This method is based on
13686      * [`String#replace`](https://mdn.io/String/replace).
13687      *
13688      * @static
13689      * @memberOf _
13690      * @since 4.0.0
13691      * @category String
13692      * @param {string} [string=''] The string to modify.
13693      * @param {RegExp|string} pattern The pattern to replace.
13694      * @param {Function|string} replacement The match replacement.
13695      * @returns {string} Returns the modified string.
13696      * @example
13697      *
13698      * _.replace('Hi Fred', 'Fred', 'Barney');
13699      * // => 'Hi Barney'
13700      */
13701     function replace() {
13702       var args = arguments,
13703           string = toString(args[0]);
13704
13705       return args.length < 3 ? string : nativeReplace.call(string, args[1], args[2]);
13706     }
13707
13708     /**
13709      * Converts `string` to
13710      * [snake case](https://en.wikipedia.org/wiki/Snake_case).
13711      *
13712      * @static
13713      * @memberOf _
13714      * @since 3.0.0
13715      * @category String
13716      * @param {string} [string=''] The string to convert.
13717      * @returns {string} Returns the snake cased string.
13718      * @example
13719      *
13720      * _.snakeCase('Foo Bar');
13721      * // => 'foo_bar'
13722      *
13723      * _.snakeCase('fooBar');
13724      * // => 'foo_bar'
13725      *
13726      * _.snakeCase('--FOO-BAR--');
13727      * // => 'foo_bar'
13728      */
13729     var snakeCase = createCompounder(function(result, word, index) {
13730       return result + (index ? '_' : '') + word.toLowerCase();
13731     });
13732
13733     /**
13734      * Splits `string` by `separator`.
13735      *
13736      * **Note:** This method is based on
13737      * [`String#split`](https://mdn.io/String/split).
13738      *
13739      * @static
13740      * @memberOf _
13741      * @since 4.0.0
13742      * @category String
13743      * @param {string} [string=''] The string to split.
13744      * @param {RegExp|string} separator The separator pattern to split by.
13745      * @param {number} [limit] The length to truncate results to.
13746      * @returns {Array} Returns the new array of string segments.
13747      * @example
13748      *
13749      * _.split('a-b-c', '-', 2);
13750      * // => ['a', 'b']
13751      */
13752     function split(string, separator, limit) {
13753       if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
13754         separator = limit = undefined;
13755       }
13756       limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
13757       if (!limit) {
13758         return [];
13759       }
13760       string = toString(string);
13761       if (string && (
13762             typeof separator == 'string' ||
13763             (separator != null && !isRegExp(separator))
13764           )) {
13765         separator = baseToString(separator);
13766         if (separator == '' && reHasComplexSymbol.test(string)) {
13767           return castSlice(stringToArray(string), 0, limit);
13768         }
13769       }
13770       return nativeSplit.call(string, separator, limit);
13771     }
13772
13773     /**
13774      * Converts `string` to
13775      * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
13776      *
13777      * @static
13778      * @memberOf _
13779      * @since 3.1.0
13780      * @category String
13781      * @param {string} [string=''] The string to convert.
13782      * @returns {string} Returns the start cased string.
13783      * @example
13784      *
13785      * _.startCase('--foo-bar--');
13786      * // => 'Foo Bar'
13787      *
13788      * _.startCase('fooBar');
13789      * // => 'Foo Bar'
13790      *
13791      * _.startCase('__FOO_BAR__');
13792      * // => 'FOO BAR'
13793      */
13794     var startCase = createCompounder(function(result, word, index) {
13795       return result + (index ? ' ' : '') + upperFirst(word);
13796     });
13797
13798     /**
13799      * Checks if `string` starts with the given target string.
13800      *
13801      * @static
13802      * @memberOf _
13803      * @since 3.0.0
13804      * @category String
13805      * @param {string} [string=''] The string to search.
13806      * @param {string} [target] The string to search for.
13807      * @param {number} [position=0] The position to search from.
13808      * @returns {boolean} Returns `true` if `string` starts with `target`,
13809      *  else `false`.
13810      * @example
13811      *
13812      * _.startsWith('abc', 'a');
13813      * // => true
13814      *
13815      * _.startsWith('abc', 'b');
13816      * // => false
13817      *
13818      * _.startsWith('abc', 'b', 1);
13819      * // => true
13820      */
13821     function startsWith(string, target, position) {
13822       string = toString(string);
13823       position = baseClamp(toInteger(position), 0, string.length);
13824       return string.lastIndexOf(baseToString(target), position) == position;
13825     }
13826
13827     /**
13828      * Creates a compiled template function that can interpolate data properties
13829      * in "interpolate" delimiters, HTML-escape interpolated data properties in
13830      * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
13831      * properties may be accessed as free variables in the template. If a setting
13832      * object is given, it takes precedence over `_.templateSettings` values.
13833      *
13834      * **Note:** In the development build `_.template` utilizes
13835      * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
13836      * for easier debugging.
13837      *
13838      * For more information on precompiling templates see
13839      * [lodash's custom builds documentation](https://lodash.com/custom-builds).
13840      *
13841      * For more information on Chrome extension sandboxes see
13842      * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
13843      *
13844      * @static
13845      * @since 0.1.0
13846      * @memberOf _
13847      * @category String
13848      * @param {string} [string=''] The template string.
13849      * @param {Object} [options={}] The options object.
13850      * @param {RegExp} [options.escape=_.templateSettings.escape]
13851      *  The HTML "escape" delimiter.
13852      * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
13853      *  The "evaluate" delimiter.
13854      * @param {Object} [options.imports=_.templateSettings.imports]
13855      *  An object to import into the template as free variables.
13856      * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
13857      *  The "interpolate" delimiter.
13858      * @param {string} [options.sourceURL='lodash.templateSources[n]']
13859      *  The sourceURL of the compiled template.
13860      * @param {string} [options.variable='obj']
13861      *  The data object variable name.
13862      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
13863      * @returns {Function} Returns the compiled template function.
13864      * @example
13865      *
13866      * // Use the "interpolate" delimiter to create a compiled template.
13867      * var compiled = _.template('hello <%= user %>!');
13868      * compiled({ 'user': 'fred' });
13869      * // => 'hello fred!'
13870      *
13871      * // Use the HTML "escape" delimiter to escape data property values.
13872      * var compiled = _.template('<b><%- value %></b>');
13873      * compiled({ 'value': '<script>' });
13874      * // => '<b>&lt;script&gt;</b>'
13875      *
13876      * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
13877      * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
13878      * compiled({ 'users': ['fred', 'barney'] });
13879      * // => '<li>fred</li><li>barney</li>'
13880      *
13881      * // Use the internal `print` function in "evaluate" delimiters.
13882      * var compiled = _.template('<% print("hello " + user); %>!');
13883      * compiled({ 'user': 'barney' });
13884      * // => 'hello barney!'
13885      *
13886      * // Use the ES delimiter as an alternative to the default "interpolate" delimiter.
13887      * var compiled = _.template('hello ${ user }!');
13888      * compiled({ 'user': 'pebbles' });
13889      * // => 'hello pebbles!'
13890      *
13891      * // Use custom template delimiters.
13892      * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
13893      * var compiled = _.template('hello {{ user }}!');
13894      * compiled({ 'user': 'mustache' });
13895      * // => 'hello mustache!'
13896      *
13897      * // Use backslashes to treat delimiters as plain text.
13898      * var compiled = _.template('<%= "\\<%- value %\\>" %>');
13899      * compiled({ 'value': 'ignored' });
13900      * // => '<%- value %>'
13901      *
13902      * // Use the `imports` option to import `jQuery` as `jq`.
13903      * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
13904      * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
13905      * compiled({ 'users': ['fred', 'barney'] });
13906      * // => '<li>fred</li><li>barney</li>'
13907      *
13908      * // Use the `sourceURL` option to specify a custom sourceURL for the template.
13909      * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
13910      * compiled(data);
13911      * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
13912      *
13913      * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
13914      * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
13915      * compiled.source;
13916      * // => function(data) {
13917      * //   var __t, __p = '';
13918      * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
13919      * //   return __p;
13920      * // }
13921      *
13922      * // Use the `source` property to inline compiled templates for meaningful
13923      * // line numbers in error messages and stack traces.
13924      * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
13925      *   var JST = {\
13926      *     "main": ' + _.template(mainText).source + '\
13927      *   };\
13928      * ');
13929      */
13930     function template(string, options, guard) {
13931       // Based on John Resig's `tmpl` implementation
13932       // (http://ejohn.org/blog/javascript-micro-templating/)
13933       // and Laura Doktorova's doT.js (https://github.com/olado/doT).
13934       var settings = lodash.templateSettings;
13935
13936       if (guard && isIterateeCall(string, options, guard)) {
13937         options = undefined;
13938       }
13939       string = toString(string);
13940       options = assignInWith({}, options, settings, assignInDefaults);
13941
13942       var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
13943           importsKeys = keys(imports),
13944           importsValues = baseValues(imports, importsKeys);
13945
13946       var isEscaping,
13947           isEvaluating,
13948           index = 0,
13949           interpolate = options.interpolate || reNoMatch,
13950           source = "__p += '";
13951
13952       // Compile the regexp to match each delimiter.
13953       var reDelimiters = RegExp(
13954         (options.escape || reNoMatch).source + '|' +
13955         interpolate.source + '|' +
13956         (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
13957         (options.evaluate || reNoMatch).source + '|$'
13958       , 'g');
13959
13960       // Use a sourceURL for easier debugging.
13961       var sourceURL = '//# sourceURL=' +
13962         ('sourceURL' in options
13963           ? options.sourceURL
13964           : ('lodash.templateSources[' + (++templateCounter) + ']')
13965         ) + '\n';
13966
13967       string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
13968         interpolateValue || (interpolateValue = esTemplateValue);
13969
13970         // Escape characters that can't be included in string literals.
13971         source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
13972
13973         // Replace delimiters with snippets.
13974         if (escapeValue) {
13975           isEscaping = true;
13976           source += "' +\n__e(" + escapeValue + ") +\n'";
13977         }
13978         if (evaluateValue) {
13979           isEvaluating = true;
13980           source += "';\n" + evaluateValue + ";\n__p += '";
13981         }
13982         if (interpolateValue) {
13983           source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
13984         }
13985         index = offset + match.length;
13986
13987         // The JS engine embedded in Adobe products needs `match` returned in
13988         // order to produce the correct `offset` value.
13989         return match;
13990       });
13991
13992       source += "';\n";
13993
13994       // If `variable` is not specified wrap a with-statement around the generated
13995       // code to add the data object to the top of the scope chain.
13996       var variable = options.variable;
13997       if (!variable) {
13998         source = 'with (obj) {\n' + source + '\n}\n';
13999       }
14000       // Cleanup code by stripping empty strings.
14001       source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
14002         .replace(reEmptyStringMiddle, '$1')
14003         .replace(reEmptyStringTrailing, '$1;');
14004
14005       // Frame code as the function body.
14006       source = 'function(' + (variable || 'obj') + ') {\n' +
14007         (variable
14008           ? ''
14009           : 'obj || (obj = {});\n'
14010         ) +
14011         "var __t, __p = ''" +
14012         (isEscaping
14013            ? ', __e = _.escape'
14014            : ''
14015         ) +
14016         (isEvaluating
14017           ? ', __j = Array.prototype.join;\n' +
14018             "function print() { __p += __j.call(arguments, '') }\n"
14019           : ';\n'
14020         ) +
14021         source +
14022         'return __p\n}';
14023
14024       var result = attempt(function() {
14025         return Function(importsKeys, sourceURL + 'return ' + source)
14026           .apply(undefined, importsValues);
14027       });
14028
14029       // Provide the compiled function's source by its `toString` method or
14030       // the `source` property as a convenience for inlining compiled templates.
14031       result.source = source;
14032       if (isError(result)) {
14033         throw result;
14034       }
14035       return result;
14036     }
14037
14038     /**
14039      * Converts `string`, as a whole, to lower case just like
14040      * [String#toLowerCase](https://mdn.io/toLowerCase).
14041      *
14042      * @static
14043      * @memberOf _
14044      * @since 4.0.0
14045      * @category String
14046      * @param {string} [string=''] The string to convert.
14047      * @returns {string} Returns the lower cased string.
14048      * @example
14049      *
14050      * _.toLower('--Foo-Bar--');
14051      * // => '--foo-bar--'
14052      *
14053      * _.toLower('fooBar');
14054      * // => 'foobar'
14055      *
14056      * _.toLower('__FOO_BAR__');
14057      * // => '__foo_bar__'
14058      */
14059     function toLower(value) {
14060       return toString(value).toLowerCase();
14061     }
14062
14063     /**
14064      * Converts `string`, as a whole, to upper case just like
14065      * [String#toUpperCase](https://mdn.io/toUpperCase).
14066      *
14067      * @static
14068      * @memberOf _
14069      * @since 4.0.0
14070      * @category String
14071      * @param {string} [string=''] The string to convert.
14072      * @returns {string} Returns the upper cased string.
14073      * @example
14074      *
14075      * _.toUpper('--foo-bar--');
14076      * // => '--FOO-BAR--'
14077      *
14078      * _.toUpper('fooBar');
14079      * // => 'FOOBAR'
14080      *
14081      * _.toUpper('__foo_bar__');
14082      * // => '__FOO_BAR__'
14083      */
14084     function toUpper(value) {
14085       return toString(value).toUpperCase();
14086     }
14087
14088     /**
14089      * Removes leading and trailing whitespace or specified characters from `string`.
14090      *
14091      * @static
14092      * @memberOf _
14093      * @since 3.0.0
14094      * @category String
14095      * @param {string} [string=''] The string to trim.
14096      * @param {string} [chars=whitespace] The characters to trim.
14097      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14098      * @returns {string} Returns the trimmed string.
14099      * @example
14100      *
14101      * _.trim('  abc  ');
14102      * // => 'abc'
14103      *
14104      * _.trim('-_-abc-_-', '_-');
14105      * // => 'abc'
14106      *
14107      * _.map(['  foo  ', '  bar  '], _.trim);
14108      * // => ['foo', 'bar']
14109      */
14110     function trim(string, chars, guard) {
14111       string = toString(string);
14112       if (string && (guard || chars === undefined)) {
14113         return string.replace(reTrim, '');
14114       }
14115       if (!string || !(chars = baseToString(chars))) {
14116         return string;
14117       }
14118       var strSymbols = stringToArray(string),
14119           chrSymbols = stringToArray(chars),
14120           start = charsStartIndex(strSymbols, chrSymbols),
14121           end = charsEndIndex(strSymbols, chrSymbols) + 1;
14122
14123       return castSlice(strSymbols, start, end).join('');
14124     }
14125
14126     /**
14127      * Removes trailing whitespace or specified characters from `string`.
14128      *
14129      * @static
14130      * @memberOf _
14131      * @since 4.0.0
14132      * @category String
14133      * @param {string} [string=''] The string to trim.
14134      * @param {string} [chars=whitespace] The characters to trim.
14135      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14136      * @returns {string} Returns the trimmed string.
14137      * @example
14138      *
14139      * _.trimEnd('  abc  ');
14140      * // => '  abc'
14141      *
14142      * _.trimEnd('-_-abc-_-', '_-');
14143      * // => '-_-abc'
14144      */
14145     function trimEnd(string, chars, guard) {
14146       string = toString(string);
14147       if (string && (guard || chars === undefined)) {
14148         return string.replace(reTrimEnd, '');
14149       }
14150       if (!string || !(chars = baseToString(chars))) {
14151         return string;
14152       }
14153       var strSymbols = stringToArray(string),
14154           end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
14155
14156       return castSlice(strSymbols, 0, end).join('');
14157     }
14158
14159     /**
14160      * Removes leading whitespace or specified characters from `string`.
14161      *
14162      * @static
14163      * @memberOf _
14164      * @since 4.0.0
14165      * @category String
14166      * @param {string} [string=''] The string to trim.
14167      * @param {string} [chars=whitespace] The characters to trim.
14168      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14169      * @returns {string} Returns the trimmed string.
14170      * @example
14171      *
14172      * _.trimStart('  abc  ');
14173      * // => 'abc  '
14174      *
14175      * _.trimStart('-_-abc-_-', '_-');
14176      * // => 'abc-_-'
14177      */
14178     function trimStart(string, chars, guard) {
14179       string = toString(string);
14180       if (string && (guard || chars === undefined)) {
14181         return string.replace(reTrimStart, '');
14182       }
14183       if (!string || !(chars = baseToString(chars))) {
14184         return string;
14185       }
14186       var strSymbols = stringToArray(string),
14187           start = charsStartIndex(strSymbols, stringToArray(chars));
14188
14189       return castSlice(strSymbols, start).join('');
14190     }
14191
14192     /**
14193      * Truncates `string` if it's longer than the given maximum string length.
14194      * The last characters of the truncated string are replaced with the omission
14195      * string which defaults to "...".
14196      *
14197      * @static
14198      * @memberOf _
14199      * @since 4.0.0
14200      * @category String
14201      * @param {string} [string=''] The string to truncate.
14202      * @param {Object} [options={}] The options object.
14203      * @param {number} [options.length=30] The maximum string length.
14204      * @param {string} [options.omission='...'] The string to indicate text is omitted.
14205      * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
14206      * @returns {string} Returns the truncated string.
14207      * @example
14208      *
14209      * _.truncate('hi-diddly-ho there, neighborino');
14210      * // => 'hi-diddly-ho there, neighbo...'
14211      *
14212      * _.truncate('hi-diddly-ho there, neighborino', {
14213      *   'length': 24,
14214      *   'separator': ' '
14215      * });
14216      * // => 'hi-diddly-ho there,...'
14217      *
14218      * _.truncate('hi-diddly-ho there, neighborino', {
14219      *   'length': 24,
14220      *   'separator': /,? +/
14221      * });
14222      * // => 'hi-diddly-ho there...'
14223      *
14224      * _.truncate('hi-diddly-ho there, neighborino', {
14225      *   'omission': ' [...]'
14226      * });
14227      * // => 'hi-diddly-ho there, neig [...]'
14228      */
14229     function truncate(string, options) {
14230       var length = DEFAULT_TRUNC_LENGTH,
14231           omission = DEFAULT_TRUNC_OMISSION;
14232
14233       if (isObject(options)) {
14234         var separator = 'separator' in options ? options.separator : separator;
14235         length = 'length' in options ? toInteger(options.length) : length;
14236         omission = 'omission' in options ? baseToString(options.omission) : omission;
14237       }
14238       string = toString(string);
14239
14240       var strLength = string.length;
14241       if (reHasComplexSymbol.test(string)) {
14242         var strSymbols = stringToArray(string);
14243         strLength = strSymbols.length;
14244       }
14245       if (length >= strLength) {
14246         return string;
14247       }
14248       var end = length - stringSize(omission);
14249       if (end < 1) {
14250         return omission;
14251       }
14252       var result = strSymbols
14253         ? castSlice(strSymbols, 0, end).join('')
14254         : string.slice(0, end);
14255
14256       if (separator === undefined) {
14257         return result + omission;
14258       }
14259       if (strSymbols) {
14260         end += (result.length - end);
14261       }
14262       if (isRegExp(separator)) {
14263         if (string.slice(end).search(separator)) {
14264           var match,
14265               substring = result;
14266
14267           if (!separator.global) {
14268             separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
14269           }
14270           separator.lastIndex = 0;
14271           while ((match = separator.exec(substring))) {
14272             var newEnd = match.index;
14273           }
14274           result = result.slice(0, newEnd === undefined ? end : newEnd);
14275         }
14276       } else if (string.indexOf(baseToString(separator), end) != end) {
14277         var index = result.lastIndexOf(separator);
14278         if (index > -1) {
14279           result = result.slice(0, index);
14280         }
14281       }
14282       return result + omission;
14283     }
14284
14285     /**
14286      * The inverse of `_.escape`; this method converts the HTML entities
14287      * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to
14288      * their corresponding characters.
14289      *
14290      * **Note:** No other HTML entities are unescaped. To unescape additional
14291      * HTML entities use a third-party library like [_he_](https://mths.be/he).
14292      *
14293      * @static
14294      * @memberOf _
14295      * @since 0.6.0
14296      * @category String
14297      * @param {string} [string=''] The string to unescape.
14298      * @returns {string} Returns the unescaped string.
14299      * @example
14300      *
14301      * _.unescape('fred, barney, &amp; pebbles');
14302      * // => 'fred, barney, & pebbles'
14303      */
14304     function unescape(string) {
14305       string = toString(string);
14306       return (string && reHasEscapedHtml.test(string))
14307         ? string.replace(reEscapedHtml, unescapeHtmlChar)
14308         : string;
14309     }
14310
14311     /**
14312      * Converts `string`, as space separated words, to upper case.
14313      *
14314      * @static
14315      * @memberOf _
14316      * @since 4.0.0
14317      * @category String
14318      * @param {string} [string=''] The string to convert.
14319      * @returns {string} Returns the upper cased string.
14320      * @example
14321      *
14322      * _.upperCase('--foo-bar');
14323      * // => 'FOO BAR'
14324      *
14325      * _.upperCase('fooBar');
14326      * // => 'FOO BAR'
14327      *
14328      * _.upperCase('__foo_bar__');
14329      * // => 'FOO BAR'
14330      */
14331     var upperCase = createCompounder(function(result, word, index) {
14332       return result + (index ? ' ' : '') + word.toUpperCase();
14333     });
14334
14335     /**
14336      * Converts the first character of `string` to upper case.
14337      *
14338      * @static
14339      * @memberOf _
14340      * @since 4.0.0
14341      * @category String
14342      * @param {string} [string=''] The string to convert.
14343      * @returns {string} Returns the converted string.
14344      * @example
14345      *
14346      * _.upperFirst('fred');
14347      * // => 'Fred'
14348      *
14349      * _.upperFirst('FRED');
14350      * // => 'FRED'
14351      */
14352     var upperFirst = createCaseFirst('toUpperCase');
14353
14354     /**
14355      * Splits `string` into an array of its words.
14356      *
14357      * @static
14358      * @memberOf _
14359      * @since 3.0.0
14360      * @category String
14361      * @param {string} [string=''] The string to inspect.
14362      * @param {RegExp|string} [pattern] The pattern to match words.
14363      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14364      * @returns {Array} Returns the words of `string`.
14365      * @example
14366      *
14367      * _.words('fred, barney, & pebbles');
14368      * // => ['fred', 'barney', 'pebbles']
14369      *
14370      * _.words('fred, barney, & pebbles', /[^, ]+/g);
14371      * // => ['fred', 'barney', '&', 'pebbles']
14372      */
14373     function words(string, pattern, guard) {
14374       string = toString(string);
14375       pattern = guard ? undefined : pattern;
14376
14377       if (pattern === undefined) {
14378         pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
14379       }
14380       return string.match(pattern) || [];
14381     }
14382
14383     /*------------------------------------------------------------------------*/
14384
14385     /**
14386      * Attempts to invoke `func`, returning either the result or the caught error
14387      * object. Any additional arguments are provided to `func` when it's invoked.
14388      *
14389      * @static
14390      * @memberOf _
14391      * @since 3.0.0
14392      * @category Util
14393      * @param {Function} func The function to attempt.
14394      * @param {...*} [args] The arguments to invoke `func` with.
14395      * @returns {*} Returns the `func` result or error object.
14396      * @example
14397      *
14398      * // Avoid throwing errors for invalid selectors.
14399      * var elements = _.attempt(function(selector) {
14400      *   return document.querySelectorAll(selector);
14401      * }, '>_>');
14402      *
14403      * if (_.isError(elements)) {
14404      *   elements = [];
14405      * }
14406      */
14407     var attempt = rest(function(func, args) {
14408       try {
14409         return apply(func, undefined, args);
14410       } catch (e) {
14411         return isError(e) ? e : new Error(e);
14412       }
14413     });
14414
14415     /**
14416      * Binds methods of an object to the object itself, overwriting the existing
14417      * method.
14418      *
14419      * **Note:** This method doesn't set the "length" property of bound functions.
14420      *
14421      * @static
14422      * @since 0.1.0
14423      * @memberOf _
14424      * @category Util
14425      * @param {Object} object The object to bind and assign the bound methods to.
14426      * @param {...(string|string[])} methodNames The object method names to bind.
14427      * @returns {Object} Returns `object`.
14428      * @example
14429      *
14430      * var view = {
14431      *   'label': 'docs',
14432      *   'onClick': function() {
14433      *     console.log('clicked ' + this.label);
14434      *   }
14435      * };
14436      *
14437      * _.bindAll(view, 'onClick');
14438      * jQuery(element).on('click', view.onClick);
14439      * // => Logs 'clicked docs' when clicked.
14440      */
14441     var bindAll = rest(function(object, methodNames) {
14442       arrayEach(baseFlatten(methodNames, 1), function(key) {
14443         key = toKey(key);
14444         object[key] = bind(object[key], object);
14445       });
14446       return object;
14447     });
14448
14449     /**
14450      * Creates a function that iterates over `pairs` and invokes the corresponding
14451      * function of the first predicate to return truthy. The predicate-function
14452      * pairs are invoked with the `this` binding and arguments of the created
14453      * function.
14454      *
14455      * @static
14456      * @memberOf _
14457      * @since 4.0.0
14458      * @category Util
14459      * @param {Array} pairs The predicate-function pairs.
14460      * @returns {Function} Returns the new function.
14461      * @example
14462      *
14463      * var func = _.cond([
14464      *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
14465      *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
14466      *   [_.constant(true),                _.constant('no match')]
14467      * ]);
14468      *
14469      * func({ 'a': 1, 'b': 2 });
14470      * // => 'matches A'
14471      *
14472      * func({ 'a': 0, 'b': 1 });
14473      * // => 'matches B'
14474      *
14475      * func({ 'a': '1', 'b': '2' });
14476      * // => 'no match'
14477      */
14478     function cond(pairs) {
14479       var length = pairs ? pairs.length : 0,
14480           toIteratee = getIteratee();
14481
14482       pairs = !length ? [] : arrayMap(pairs, function(pair) {
14483         if (typeof pair[1] != 'function') {
14484           throw new TypeError(FUNC_ERROR_TEXT);
14485         }
14486         return [toIteratee(pair[0]), pair[1]];
14487       });
14488
14489       return rest(function(args) {
14490         var index = -1;
14491         while (++index < length) {
14492           var pair = pairs[index];
14493           if (apply(pair[0], this, args)) {
14494             return apply(pair[1], this, args);
14495           }
14496         }
14497       });
14498     }
14499
14500     /**
14501      * Creates a function that invokes the predicate properties of `source` with
14502      * the corresponding property values of a given object, returning `true` if
14503      * all predicates return truthy, else `false`.
14504      *
14505      * @static
14506      * @memberOf _
14507      * @since 4.0.0
14508      * @category Util
14509      * @param {Object} source The object of property predicates to conform to.
14510      * @returns {Function} Returns the new function.
14511      * @example
14512      *
14513      * var users = [
14514      *   { 'user': 'barney', 'age': 36 },
14515      *   { 'user': 'fred',   'age': 40 }
14516      * ];
14517      *
14518      * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
14519      * // => [{ 'user': 'fred', 'age': 40 }]
14520      */
14521     function conforms(source) {
14522       return baseConforms(baseClone(source, true));
14523     }
14524
14525     /**
14526      * Creates a function that returns `value`.
14527      *
14528      * @static
14529      * @memberOf _
14530      * @since 2.4.0
14531      * @category Util
14532      * @param {*} value The value to return from the new function.
14533      * @returns {Function} Returns the new function.
14534      * @example
14535      *
14536      * var object = { 'user': 'fred' };
14537      * var getter = _.constant(object);
14538      *
14539      * getter() === object;
14540      * // => true
14541      */
14542     function constant(value) {
14543       return function() {
14544         return value;
14545       };
14546     }
14547
14548     /**
14549      * Creates a function that returns the result of invoking the given functions
14550      * with the `this` binding of the created function, where each successive
14551      * invocation is supplied the return value of the previous.
14552      *
14553      * @static
14554      * @memberOf _
14555      * @since 3.0.0
14556      * @category Util
14557      * @param {...(Function|Function[])} [funcs] Functions to invoke.
14558      * @returns {Function} Returns the new function.
14559      * @see _.flowRight
14560      * @example
14561      *
14562      * function square(n) {
14563      *   return n * n;
14564      * }
14565      *
14566      * var addSquare = _.flow(_.add, square);
14567      * addSquare(1, 2);
14568      * // => 9
14569      */
14570     var flow = createFlow();
14571
14572     /**
14573      * This method is like `_.flow` except that it creates a function that
14574      * invokes the given functions from right to left.
14575      *
14576      * @static
14577      * @since 3.0.0
14578      * @memberOf _
14579      * @category Util
14580      * @param {...(Function|Function[])} [funcs] Functions to invoke.
14581      * @returns {Function} Returns the new function.
14582      * @see _.flow
14583      * @example
14584      *
14585      * function square(n) {
14586      *   return n * n;
14587      * }
14588      *
14589      * var addSquare = _.flowRight(square, _.add);
14590      * addSquare(1, 2);
14591      * // => 9
14592      */
14593     var flowRight = createFlow(true);
14594
14595     /**
14596      * This method returns the first argument given to it.
14597      *
14598      * @static
14599      * @since 0.1.0
14600      * @memberOf _
14601      * @category Util
14602      * @param {*} value Any value.
14603      * @returns {*} Returns `value`.
14604      * @example
14605      *
14606      * var object = { 'user': 'fred' };
14607      *
14608      * _.identity(object) === object;
14609      * // => true
14610      */
14611     function identity(value) {
14612       return value;
14613     }
14614
14615     /**
14616      * Creates a function that invokes `func` with the arguments of the created
14617      * function. If `func` is a property name, the created function returns the
14618      * property value for a given element. If `func` is an array or object, the
14619      * created function returns `true` for elements that contain the equivalent
14620      * source properties, otherwise it returns `false`.
14621      *
14622      * @static
14623      * @since 4.0.0
14624      * @memberOf _
14625      * @category Util
14626      * @param {*} [func=_.identity] The value to convert to a callback.
14627      * @returns {Function} Returns the callback.
14628      * @example
14629      *
14630      * var users = [
14631      *   { 'user': 'barney', 'age': 36, 'active': true },
14632      *   { 'user': 'fred',   'age': 40, 'active': false }
14633      * ];
14634      *
14635      * // The `_.matches` iteratee shorthand.
14636      * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
14637      * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
14638      *
14639      * // The `_.matchesProperty` iteratee shorthand.
14640      * _.filter(users, _.iteratee(['user', 'fred']));
14641      * // => [{ 'user': 'fred', 'age': 40 }]
14642      *
14643      * // The `_.property` iteratee shorthand.
14644      * _.map(users, _.iteratee('user'));
14645      * // => ['barney', 'fred']
14646      *
14647      * // Create custom iteratee shorthands.
14648      * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
14649      *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
14650      *     return func.test(string);
14651      *   };
14652      * });
14653      *
14654      * _.filter(['abc', 'def'], /ef/);
14655      * // => ['def']
14656      */
14657     function iteratee(func) {
14658       return baseIteratee(typeof func == 'function' ? func : baseClone(func, true));
14659     }
14660
14661     /**
14662      * Creates a function that performs a partial deep comparison between a given
14663      * object and `source`, returning `true` if the given object has equivalent
14664      * property values, else `false`. The created function is equivalent to
14665      * `_.isMatch` with a `source` partially applied.
14666      *
14667      * **Note:** This method supports comparing the same values as `_.isEqual`.
14668      *
14669      * @static
14670      * @memberOf _
14671      * @since 3.0.0
14672      * @category Util
14673      * @param {Object} source The object of property values to match.
14674      * @returns {Function} Returns the new function.
14675      * @example
14676      *
14677      * var users = [
14678      *   { 'user': 'barney', 'age': 36, 'active': true },
14679      *   { 'user': 'fred',   'age': 40, 'active': false }
14680      * ];
14681      *
14682      * _.filter(users, _.matches({ 'age': 40, 'active': false }));
14683      * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
14684      */
14685     function matches(source) {
14686       return baseMatches(baseClone(source, true));
14687     }
14688
14689     /**
14690      * Creates a function that performs a partial deep comparison between the
14691      * value at `path` of a given object to `srcValue`, returning `true` if the
14692      * object value is equivalent, else `false`.
14693      *
14694      * **Note:** This method supports comparing the same values as `_.isEqual`.
14695      *
14696      * @static
14697      * @memberOf _
14698      * @since 3.2.0
14699      * @category Util
14700      * @param {Array|string} path The path of the property to get.
14701      * @param {*} srcValue The value to match.
14702      * @returns {Function} Returns the new function.
14703      * @example
14704      *
14705      * var users = [
14706      *   { 'user': 'barney' },
14707      *   { 'user': 'fred' }
14708      * ];
14709      *
14710      * _.find(users, _.matchesProperty('user', 'fred'));
14711      * // => { 'user': 'fred' }
14712      */
14713     function matchesProperty(path, srcValue) {
14714       return baseMatchesProperty(path, baseClone(srcValue, true));
14715     }
14716
14717     /**
14718      * Creates a function that invokes the method at `path` of a given object.
14719      * Any additional arguments are provided to the invoked method.
14720      *
14721      * @static
14722      * @memberOf _
14723      * @since 3.7.0
14724      * @category Util
14725      * @param {Array|string} path The path of the method to invoke.
14726      * @param {...*} [args] The arguments to invoke the method with.
14727      * @returns {Function} Returns the new function.
14728      * @example
14729      *
14730      * var objects = [
14731      *   { 'a': { 'b': _.constant(2) } },
14732      *   { 'a': { 'b': _.constant(1) } }
14733      * ];
14734      *
14735      * _.map(objects, _.method('a.b'));
14736      * // => [2, 1]
14737      *
14738      * _.map(objects, _.method(['a', 'b']));
14739      * // => [2, 1]
14740      */
14741     var method = rest(function(path, args) {
14742       return function(object) {
14743         return baseInvoke(object, path, args);
14744       };
14745     });
14746
14747     /**
14748      * The opposite of `_.method`; this method creates a function that invokes
14749      * the method at a given path of `object`. Any additional arguments are
14750      * provided to the invoked method.
14751      *
14752      * @static
14753      * @memberOf _
14754      * @since 3.7.0
14755      * @category Util
14756      * @param {Object} object The object to query.
14757      * @param {...*} [args] The arguments to invoke the method with.
14758      * @returns {Function} Returns the new function.
14759      * @example
14760      *
14761      * var array = _.times(3, _.constant),
14762      *     object = { 'a': array, 'b': array, 'c': array };
14763      *
14764      * _.map(['a[2]', 'c[0]'], _.methodOf(object));
14765      * // => [2, 0]
14766      *
14767      * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
14768      * // => [2, 0]
14769      */
14770     var methodOf = rest(function(object, args) {
14771       return function(path) {
14772         return baseInvoke(object, path, args);
14773       };
14774     });
14775
14776     /**
14777      * Adds all own enumerable string keyed function properties of a source
14778      * object to the destination object. If `object` is a function, then methods
14779      * are added to its prototype as well.
14780      *
14781      * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
14782      * avoid conflicts caused by modifying the original.
14783      *
14784      * @static
14785      * @since 0.1.0
14786      * @memberOf _
14787      * @category Util
14788      * @param {Function|Object} [object=lodash] The destination object.
14789      * @param {Object} source The object of functions to add.
14790      * @param {Object} [options={}] The options object.
14791      * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
14792      * @returns {Function|Object} Returns `object`.
14793      * @example
14794      *
14795      * function vowels(string) {
14796      *   return _.filter(string, function(v) {
14797      *     return /[aeiou]/i.test(v);
14798      *   });
14799      * }
14800      *
14801      * _.mixin({ 'vowels': vowels });
14802      * _.vowels('fred');
14803      * // => ['e']
14804      *
14805      * _('fred').vowels().value();
14806      * // => ['e']
14807      *
14808      * _.mixin({ 'vowels': vowels }, { 'chain': false });
14809      * _('fred').vowels();
14810      * // => ['e']
14811      */
14812     function mixin(object, source, options) {
14813       var props = keys(source),
14814           methodNames = baseFunctions(source, props);
14815
14816       if (options == null &&
14817           !(isObject(source) && (methodNames.length || !props.length))) {
14818         options = source;
14819         source = object;
14820         object = this;
14821         methodNames = baseFunctions(source, keys(source));
14822       }
14823       var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
14824           isFunc = isFunction(object);
14825
14826       arrayEach(methodNames, function(methodName) {
14827         var func = source[methodName];
14828         object[methodName] = func;
14829         if (isFunc) {
14830           object.prototype[methodName] = function() {
14831             var chainAll = this.__chain__;
14832             if (chain || chainAll) {
14833               var result = object(this.__wrapped__),
14834                   actions = result.__actions__ = copyArray(this.__actions__);
14835
14836               actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
14837               result.__chain__ = chainAll;
14838               return result;
14839             }
14840             return func.apply(object, arrayPush([this.value()], arguments));
14841           };
14842         }
14843       });
14844
14845       return object;
14846     }
14847
14848     /**
14849      * Reverts the `_` variable to its previous value and returns a reference to
14850      * the `lodash` function.
14851      *
14852      * @static
14853      * @since 0.1.0
14854      * @memberOf _
14855      * @category Util
14856      * @returns {Function} Returns the `lodash` function.
14857      * @example
14858      *
14859      * var lodash = _.noConflict();
14860      */
14861     function noConflict() {
14862       if (root._ === this) {
14863         root._ = oldDash;
14864       }
14865       return this;
14866     }
14867
14868     /**
14869      * A no-operation function that returns `undefined` regardless of the
14870      * arguments it receives.
14871      *
14872      * @static
14873      * @memberOf _
14874      * @since 2.3.0
14875      * @category Util
14876      * @example
14877      *
14878      * var object = { 'user': 'fred' };
14879      *
14880      * _.noop(object) === undefined;
14881      * // => true
14882      */
14883     function noop() {
14884       // No operation performed.
14885     }
14886
14887     /**
14888      * Creates a function that returns its nth argument. If `n` is negative,
14889      * the nth argument from the end is returned.
14890      *
14891      * @static
14892      * @memberOf _
14893      * @since 4.0.0
14894      * @category Util
14895      * @param {number} [n=0] The index of the argument to return.
14896      * @returns {Function} Returns the new function.
14897      * @example
14898      *
14899      * var func = _.nthArg(1);
14900      * func('a', 'b', 'c', 'd');
14901      * // => 'b'
14902      *
14903      * var func = _.nthArg(-2);
14904      * func('a', 'b', 'c', 'd');
14905      * // => 'c'
14906      */
14907     function nthArg(n) {
14908       n = toInteger(n);
14909       return rest(function(args) {
14910         return baseNth(args, n);
14911       });
14912     }
14913
14914     /**
14915      * Creates a function that invokes `iteratees` with the arguments it receives
14916      * and returns their results.
14917      *
14918      * @static
14919      * @memberOf _
14920      * @since 4.0.0
14921      * @category Util
14922      * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
14923      *  [iteratees=[_.identity]] The iteratees to invoke.
14924      * @returns {Function} Returns the new function.
14925      * @example
14926      *
14927      * var func = _.over(Math.max, Math.min);
14928      *
14929      * func(1, 2, 3, 4);
14930      * // => [4, 1]
14931      */
14932     var over = createOver(arrayMap);
14933
14934     /**
14935      * Creates a function that checks if **all** of the `predicates` return
14936      * truthy when invoked with the arguments it receives.
14937      *
14938      * @static
14939      * @memberOf _
14940      * @since 4.0.0
14941      * @category Util
14942      * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
14943      *  [predicates=[_.identity]] The predicates to check.
14944      * @returns {Function} Returns the new function.
14945      * @example
14946      *
14947      * var func = _.overEvery(Boolean, isFinite);
14948      *
14949      * func('1');
14950      * // => true
14951      *
14952      * func(null);
14953      * // => false
14954      *
14955      * func(NaN);
14956      * // => false
14957      */
14958     var overEvery = createOver(arrayEvery);
14959
14960     /**
14961      * Creates a function that checks if **any** of the `predicates` return
14962      * truthy when invoked with the arguments it receives.
14963      *
14964      * @static
14965      * @memberOf _
14966      * @since 4.0.0
14967      * @category Util
14968      * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
14969      *  [predicates=[_.identity]] The predicates to check.
14970      * @returns {Function} Returns the new function.
14971      * @example
14972      *
14973      * var func = _.overSome(Boolean, isFinite);
14974      *
14975      * func('1');
14976      * // => true
14977      *
14978      * func(null);
14979      * // => true
14980      *
14981      * func(NaN);
14982      * // => false
14983      */
14984     var overSome = createOver(arraySome);
14985
14986     /**
14987      * Creates a function that returns the value at `path` of a given object.
14988      *
14989      * @static
14990      * @memberOf _
14991      * @since 2.4.0
14992      * @category Util
14993      * @param {Array|string} path The path of the property to get.
14994      * @returns {Function} Returns the new function.
14995      * @example
14996      *
14997      * var objects = [
14998      *   { 'a': { 'b': 2 } },
14999      *   { 'a': { 'b': 1 } }
15000      * ];
15001      *
15002      * _.map(objects, _.property('a.b'));
15003      * // => [2, 1]
15004      *
15005      * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
15006      * // => [1, 2]
15007      */
15008     function property(path) {
15009       return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
15010     }
15011
15012     /**
15013      * The opposite of `_.property`; this method creates a function that returns
15014      * the value at a given path of `object`.
15015      *
15016      * @static
15017      * @memberOf _
15018      * @since 3.0.0
15019      * @category Util
15020      * @param {Object} object The object to query.
15021      * @returns {Function} Returns the new function.
15022      * @example
15023      *
15024      * var array = [0, 1, 2],
15025      *     object = { 'a': array, 'b': array, 'c': array };
15026      *
15027      * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
15028      * // => [2, 0]
15029      *
15030      * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
15031      * // => [2, 0]
15032      */
15033     function propertyOf(object) {
15034       return function(path) {
15035         return object == null ? undefined : baseGet(object, path);
15036       };
15037     }
15038
15039     /**
15040      * Creates an array of numbers (positive and/or negative) progressing from
15041      * `start` up to, but not including, `end`. A step of `-1` is used if a negative
15042      * `start` is specified without an `end` or `step`. If `end` is not specified,
15043      * it's set to `start` with `start` then set to `0`.
15044      *
15045      * **Note:** JavaScript follows the IEEE-754 standard for resolving
15046      * floating-point values which can produce unexpected results.
15047      *
15048      * @static
15049      * @since 0.1.0
15050      * @memberOf _
15051      * @category Util
15052      * @param {number} [start=0] The start of the range.
15053      * @param {number} end The end of the range.
15054      * @param {number} [step=1] The value to increment or decrement by.
15055      * @returns {Array} Returns the new array of numbers.
15056      * @see _.inRange, _.rangeRight
15057      * @example
15058      *
15059      * _.range(4);
15060      * // => [0, 1, 2, 3]
15061      *
15062      * _.range(-4);
15063      * // => [0, -1, -2, -3]
15064      *
15065      * _.range(1, 5);
15066      * // => [1, 2, 3, 4]
15067      *
15068      * _.range(0, 20, 5);
15069      * // => [0, 5, 10, 15]
15070      *
15071      * _.range(0, -4, -1);
15072      * // => [0, -1, -2, -3]
15073      *
15074      * _.range(1, 4, 0);
15075      * // => [1, 1, 1]
15076      *
15077      * _.range(0);
15078      * // => []
15079      */
15080     var range = createRange();
15081
15082     /**
15083      * This method is like `_.range` except that it populates values in
15084      * descending order.
15085      *
15086      * @static
15087      * @memberOf _
15088      * @since 4.0.0
15089      * @category Util
15090      * @param {number} [start=0] The start of the range.
15091      * @param {number} end The end of the range.
15092      * @param {number} [step=1] The value to increment or decrement by.
15093      * @returns {Array} Returns the new array of numbers.
15094      * @see _.inRange, _.range
15095      * @example
15096      *
15097      * _.rangeRight(4);
15098      * // => [3, 2, 1, 0]
15099      *
15100      * _.rangeRight(-4);
15101      * // => [-3, -2, -1, 0]
15102      *
15103      * _.rangeRight(1, 5);
15104      * // => [4, 3, 2, 1]
15105      *
15106      * _.rangeRight(0, 20, 5);
15107      * // => [15, 10, 5, 0]
15108      *
15109      * _.rangeRight(0, -4, -1);
15110      * // => [-3, -2, -1, 0]
15111      *
15112      * _.rangeRight(1, 4, 0);
15113      * // => [1, 1, 1]
15114      *
15115      * _.rangeRight(0);
15116      * // => []
15117      */
15118     var rangeRight = createRange(true);
15119
15120     /**
15121      * Invokes the iteratee `n` times, returning an array of the results of
15122      * each invocation. The iteratee is invoked with one argument; (index).
15123      *
15124      * @static
15125      * @since 0.1.0
15126      * @memberOf _
15127      * @category Util
15128      * @param {number} n The number of times to invoke `iteratee`.
15129      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
15130      * @returns {Array} Returns the array of results.
15131      * @example
15132      *
15133      * _.times(3, String);
15134      * // => ['0', '1', '2']
15135      *
15136      *  _.times(4, _.constant(true));
15137      * // => [true, true, true, true]
15138      */
15139     function times(n, iteratee) {
15140       n = toInteger(n);
15141       if (n < 1 || n > MAX_SAFE_INTEGER) {
15142         return [];
15143       }
15144       var index = MAX_ARRAY_LENGTH,
15145           length = nativeMin(n, MAX_ARRAY_LENGTH);
15146
15147       iteratee = getIteratee(iteratee);
15148       n -= MAX_ARRAY_LENGTH;
15149
15150       var result = baseTimes(length, iteratee);
15151       while (++index < n) {
15152         iteratee(index);
15153       }
15154       return result;
15155     }
15156
15157     /**
15158      * Converts `value` to a property path array.
15159      *
15160      * @static
15161      * @memberOf _
15162      * @since 4.0.0
15163      * @category Util
15164      * @param {*} value The value to convert.
15165      * @returns {Array} Returns the new property path array.
15166      * @example
15167      *
15168      * _.toPath('a.b.c');
15169      * // => ['a', 'b', 'c']
15170      *
15171      * _.toPath('a[0].b.c');
15172      * // => ['a', '0', 'b', 'c']
15173      *
15174      * var path = ['a', 'b', 'c'],
15175      *     newPath = _.toPath(path);
15176      *
15177      * console.log(newPath);
15178      * // => ['a', 'b', 'c']
15179      *
15180      * console.log(path === newPath);
15181      * // => false
15182      */
15183     function toPath(value) {
15184       if (isArray(value)) {
15185         return arrayMap(value, toKey);
15186       }
15187       return isSymbol(value) ? [value] : copyArray(stringToPath(value));
15188     }
15189
15190     /**
15191      * Generates a unique ID. If `prefix` is given, the ID is appended to it.
15192      *
15193      * @static
15194      * @since 0.1.0
15195      * @memberOf _
15196      * @category Util
15197      * @param {string} [prefix=''] The value to prefix the ID with.
15198      * @returns {string} Returns the unique ID.
15199      * @example
15200      *
15201      * _.uniqueId('contact_');
15202      * // => 'contact_104'
15203      *
15204      * _.uniqueId();
15205      * // => '105'
15206      */
15207     function uniqueId(prefix) {
15208       var id = ++idCounter;
15209       return toString(prefix) + id;
15210     }
15211
15212     /*------------------------------------------------------------------------*/
15213
15214     /**
15215      * Adds two numbers.
15216      *
15217      * @static
15218      * @memberOf _
15219      * @since 3.4.0
15220      * @category Math
15221      * @param {number} augend The first number in an addition.
15222      * @param {number} addend The second number in an addition.
15223      * @returns {number} Returns the total.
15224      * @example
15225      *
15226      * _.add(6, 4);
15227      * // => 10
15228      */
15229     var add = createMathOperation(function(augend, addend) {
15230       return augend + addend;
15231     });
15232
15233     /**
15234      * Computes `number` rounded up to `precision`.
15235      *
15236      * @static
15237      * @memberOf _
15238      * @since 3.10.0
15239      * @category Math
15240      * @param {number} number The number to round up.
15241      * @param {number} [precision=0] The precision to round up to.
15242      * @returns {number} Returns the rounded up number.
15243      * @example
15244      *
15245      * _.ceil(4.006);
15246      * // => 5
15247      *
15248      * _.ceil(6.004, 2);
15249      * // => 6.01
15250      *
15251      * _.ceil(6040, -2);
15252      * // => 6100
15253      */
15254     var ceil = createRound('ceil');
15255
15256     /**
15257      * Divide two numbers.
15258      *
15259      * @static
15260      * @memberOf _
15261      * @since 4.7.0
15262      * @category Math
15263      * @param {number} dividend The first number in a division.
15264      * @param {number} divisor The second number in a division.
15265      * @returns {number} Returns the quotient.
15266      * @example
15267      *
15268      * _.divide(6, 4);
15269      * // => 1.5
15270      */
15271     var divide = createMathOperation(function(dividend, divisor) {
15272       return dividend / divisor;
15273     });
15274
15275     /**
15276      * Computes `number` rounded down to `precision`.
15277      *
15278      * @static
15279      * @memberOf _
15280      * @since 3.10.0
15281      * @category Math
15282      * @param {number} number The number to round down.
15283      * @param {number} [precision=0] The precision to round down to.
15284      * @returns {number} Returns the rounded down number.
15285      * @example
15286      *
15287      * _.floor(4.006);
15288      * // => 4
15289      *
15290      * _.floor(0.046, 2);
15291      * // => 0.04
15292      *
15293      * _.floor(4060, -2);
15294      * // => 4000
15295      */
15296     var floor = createRound('floor');
15297
15298     /**
15299      * Computes the maximum value of `array`. If `array` is empty or falsey,
15300      * `undefined` is returned.
15301      *
15302      * @static
15303      * @since 0.1.0
15304      * @memberOf _
15305      * @category Math
15306      * @param {Array} array The array to iterate over.
15307      * @returns {*} Returns the maximum value.
15308      * @example
15309      *
15310      * _.max([4, 2, 8, 6]);
15311      * // => 8
15312      *
15313      * _.max([]);
15314      * // => undefined
15315      */
15316     function max(array) {
15317       return (array && array.length)
15318         ? baseExtremum(array, identity, baseGt)
15319         : undefined;
15320     }
15321
15322     /**
15323      * This method is like `_.max` except that it accepts `iteratee` which is
15324      * invoked for each element in `array` to generate the criterion by which
15325      * the value is ranked. The iteratee is invoked with one argument: (value).
15326      *
15327      * @static
15328      * @memberOf _
15329      * @since 4.0.0
15330      * @category Math
15331      * @param {Array} array The array to iterate over.
15332      * @param {Array|Function|Object|string} [iteratee=_.identity]
15333      *  The iteratee invoked per element.
15334      * @returns {*} Returns the maximum value.
15335      * @example
15336      *
15337      * var objects = [{ 'n': 1 }, { 'n': 2 }];
15338      *
15339      * _.maxBy(objects, function(o) { return o.n; });
15340      * // => { 'n': 2 }
15341      *
15342      * // The `_.property` iteratee shorthand.
15343      * _.maxBy(objects, 'n');
15344      * // => { 'n': 2 }
15345      */
15346     function maxBy(array, iteratee) {
15347       return (array && array.length)
15348         ? baseExtremum(array, getIteratee(iteratee), baseGt)
15349         : undefined;
15350     }
15351
15352     /**
15353      * Computes the mean of the values in `array`.
15354      *
15355      * @static
15356      * @memberOf _
15357      * @since 4.0.0
15358      * @category Math
15359      * @param {Array} array The array to iterate over.
15360      * @returns {number} Returns the mean.
15361      * @example
15362      *
15363      * _.mean([4, 2, 8, 6]);
15364      * // => 5
15365      */
15366     function mean(array) {
15367       return baseMean(array, identity);
15368     }
15369
15370     /**
15371      * This method is like `_.mean` except that it accepts `iteratee` which is
15372      * invoked for each element in `array` to generate the value to be averaged.
15373      * The iteratee is invoked with one argument: (value).
15374      *
15375      * @static
15376      * @memberOf _
15377      * @since 4.7.0
15378      * @category Math
15379      * @param {Array} array The array to iterate over.
15380      * @param {Array|Function|Object|string} [iteratee=_.identity]
15381      *  The iteratee invoked per element.
15382      * @returns {number} Returns the mean.
15383      * @example
15384      *
15385      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
15386      *
15387      * _.meanBy(objects, function(o) { return o.n; });
15388      * // => 5
15389      *
15390      * // The `_.property` iteratee shorthand.
15391      * _.meanBy(objects, 'n');
15392      * // => 5
15393      */
15394     function meanBy(array, iteratee) {
15395       return baseMean(array, getIteratee(iteratee));
15396     }
15397
15398     /**
15399      * Computes the minimum value of `array`. If `array` is empty or falsey,
15400      * `undefined` is returned.
15401      *
15402      * @static
15403      * @since 0.1.0
15404      * @memberOf _
15405      * @category Math
15406      * @param {Array} array The array to iterate over.
15407      * @returns {*} Returns the minimum value.
15408      * @example
15409      *
15410      * _.min([4, 2, 8, 6]);
15411      * // => 2
15412      *
15413      * _.min([]);
15414      * // => undefined
15415      */
15416     function min(array) {
15417       return (array && array.length)
15418         ? baseExtremum(array, identity, baseLt)
15419         : undefined;
15420     }
15421
15422     /**
15423      * This method is like `_.min` except that it accepts `iteratee` which is
15424      * invoked for each element in `array` to generate the criterion by which
15425      * the value is ranked. The iteratee is invoked with one argument: (value).
15426      *
15427      * @static
15428      * @memberOf _
15429      * @since 4.0.0
15430      * @category Math
15431      * @param {Array} array The array to iterate over.
15432      * @param {Array|Function|Object|string} [iteratee=_.identity]
15433      *  The iteratee invoked per element.
15434      * @returns {*} Returns the minimum value.
15435      * @example
15436      *
15437      * var objects = [{ 'n': 1 }, { 'n': 2 }];
15438      *
15439      * _.minBy(objects, function(o) { return o.n; });
15440      * // => { 'n': 1 }
15441      *
15442      * // The `_.property` iteratee shorthand.
15443      * _.minBy(objects, 'n');
15444      * // => { 'n': 1 }
15445      */
15446     function minBy(array, iteratee) {
15447       return (array && array.length)
15448         ? baseExtremum(array, getIteratee(iteratee), baseLt)
15449         : undefined;
15450     }
15451
15452     /**
15453      * Multiply two numbers.
15454      *
15455      * @static
15456      * @memberOf _
15457      * @since 4.7.0
15458      * @category Math
15459      * @param {number} multiplier The first number in a multiplication.
15460      * @param {number} multiplicand The second number in a multiplication.
15461      * @returns {number} Returns the product.
15462      * @example
15463      *
15464      * _.multiply(6, 4);
15465      * // => 24
15466      */
15467     var multiply = createMathOperation(function(multiplier, multiplicand) {
15468       return multiplier * multiplicand;
15469     });
15470
15471     /**
15472      * Computes `number` rounded to `precision`.
15473      *
15474      * @static
15475      * @memberOf _
15476      * @since 3.10.0
15477      * @category Math
15478      * @param {number} number The number to round.
15479      * @param {number} [precision=0] The precision to round to.
15480      * @returns {number} Returns the rounded number.
15481      * @example
15482      *
15483      * _.round(4.006);
15484      * // => 4
15485      *
15486      * _.round(4.006, 2);
15487      * // => 4.01
15488      *
15489      * _.round(4060, -2);
15490      * // => 4100
15491      */
15492     var round = createRound('round');
15493
15494     /**
15495      * Subtract two numbers.
15496      *
15497      * @static
15498      * @memberOf _
15499      * @since 4.0.0
15500      * @category Math
15501      * @param {number} minuend The first number in a subtraction.
15502      * @param {number} subtrahend The second number in a subtraction.
15503      * @returns {number} Returns the difference.
15504      * @example
15505      *
15506      * _.subtract(6, 4);
15507      * // => 2
15508      */
15509     var subtract = createMathOperation(function(minuend, subtrahend) {
15510       return minuend - subtrahend;
15511     });
15512
15513     /**
15514      * Computes the sum of the values in `array`.
15515      *
15516      * @static
15517      * @memberOf _
15518      * @since 3.4.0
15519      * @category Math
15520      * @param {Array} array The array to iterate over.
15521      * @returns {number} Returns the sum.
15522      * @example
15523      *
15524      * _.sum([4, 2, 8, 6]);
15525      * // => 20
15526      */
15527     function sum(array) {
15528       return (array && array.length)
15529         ? baseSum(array, identity)
15530         : 0;
15531     }
15532
15533     /**
15534      * This method is like `_.sum` except that it accepts `iteratee` which is
15535      * invoked for each element in `array` to generate the value to be summed.
15536      * The iteratee is invoked with one argument: (value).
15537      *
15538      * @static
15539      * @memberOf _
15540      * @since 4.0.0
15541      * @category Math
15542      * @param {Array} array The array to iterate over.
15543      * @param {Array|Function|Object|string} [iteratee=_.identity]
15544      *  The iteratee invoked per element.
15545      * @returns {number} Returns the sum.
15546      * @example
15547      *
15548      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
15549      *
15550      * _.sumBy(objects, function(o) { return o.n; });
15551      * // => 20
15552      *
15553      * // The `_.property` iteratee shorthand.
15554      * _.sumBy(objects, 'n');
15555      * // => 20
15556      */
15557     function sumBy(array, iteratee) {
15558       return (array && array.length)
15559         ? baseSum(array, getIteratee(iteratee))
15560         : 0;
15561     }
15562
15563     /*------------------------------------------------------------------------*/
15564
15565     // Add methods that return wrapped values in chain sequences.
15566     lodash.after = after;
15567     lodash.ary = ary;
15568     lodash.assign = assign;
15569     lodash.assignIn = assignIn;
15570     lodash.assignInWith = assignInWith;
15571     lodash.assignWith = assignWith;
15572     lodash.at = at;
15573     lodash.before = before;
15574     lodash.bind = bind;
15575     lodash.bindAll = bindAll;
15576     lodash.bindKey = bindKey;
15577     lodash.castArray = castArray;
15578     lodash.chain = chain;
15579     lodash.chunk = chunk;
15580     lodash.compact = compact;
15581     lodash.concat = concat;
15582     lodash.cond = cond;
15583     lodash.conforms = conforms;
15584     lodash.constant = constant;
15585     lodash.countBy = countBy;
15586     lodash.create = create;
15587     lodash.curry = curry;
15588     lodash.curryRight = curryRight;
15589     lodash.debounce = debounce;
15590     lodash.defaults = defaults;
15591     lodash.defaultsDeep = defaultsDeep;
15592     lodash.defer = defer;
15593     lodash.delay = delay;
15594     lodash.difference = difference;
15595     lodash.differenceBy = differenceBy;
15596     lodash.differenceWith = differenceWith;
15597     lodash.drop = drop;
15598     lodash.dropRight = dropRight;
15599     lodash.dropRightWhile = dropRightWhile;
15600     lodash.dropWhile = dropWhile;
15601     lodash.fill = fill;
15602     lodash.filter = filter;
15603     lodash.flatMap = flatMap;
15604     lodash.flatMapDeep = flatMapDeep;
15605     lodash.flatMapDepth = flatMapDepth;
15606     lodash.flatten = flatten;
15607     lodash.flattenDeep = flattenDeep;
15608     lodash.flattenDepth = flattenDepth;
15609     lodash.flip = flip;
15610     lodash.flow = flow;
15611     lodash.flowRight = flowRight;
15612     lodash.fromPairs = fromPairs;
15613     lodash.functions = functions;
15614     lodash.functionsIn = functionsIn;
15615     lodash.groupBy = groupBy;
15616     lodash.initial = initial;
15617     lodash.intersection = intersection;
15618     lodash.intersectionBy = intersectionBy;
15619     lodash.intersectionWith = intersectionWith;
15620     lodash.invert = invert;
15621     lodash.invertBy = invertBy;
15622     lodash.invokeMap = invokeMap;
15623     lodash.iteratee = iteratee;
15624     lodash.keyBy = keyBy;
15625     lodash.keys = keys;
15626     lodash.keysIn = keysIn;
15627     lodash.map = map;
15628     lodash.mapKeys = mapKeys;
15629     lodash.mapValues = mapValues;
15630     lodash.matches = matches;
15631     lodash.matchesProperty = matchesProperty;
15632     lodash.memoize = memoize;
15633     lodash.merge = merge;
15634     lodash.mergeWith = mergeWith;
15635     lodash.method = method;
15636     lodash.methodOf = methodOf;
15637     lodash.mixin = mixin;
15638     lodash.negate = negate;
15639     lodash.nthArg = nthArg;
15640     lodash.omit = omit;
15641     lodash.omitBy = omitBy;
15642     lodash.once = once;
15643     lodash.orderBy = orderBy;
15644     lodash.over = over;
15645     lodash.overArgs = overArgs;
15646     lodash.overEvery = overEvery;
15647     lodash.overSome = overSome;
15648     lodash.partial = partial;
15649     lodash.partialRight = partialRight;
15650     lodash.partition = partition;
15651     lodash.pick = pick;
15652     lodash.pickBy = pickBy;
15653     lodash.property = property;
15654     lodash.propertyOf = propertyOf;
15655     lodash.pull = pull;
15656     lodash.pullAll = pullAll;
15657     lodash.pullAllBy = pullAllBy;
15658     lodash.pullAllWith = pullAllWith;
15659     lodash.pullAt = pullAt;
15660     lodash.range = range;
15661     lodash.rangeRight = rangeRight;
15662     lodash.rearg = rearg;
15663     lodash.reject = reject;
15664     lodash.remove = remove;
15665     lodash.rest = rest;
15666     lodash.reverse = reverse;
15667     lodash.sampleSize = sampleSize;
15668     lodash.set = set;
15669     lodash.setWith = setWith;
15670     lodash.shuffle = shuffle;
15671     lodash.slice = slice;
15672     lodash.sortBy = sortBy;
15673     lodash.sortedUniq = sortedUniq;
15674     lodash.sortedUniqBy = sortedUniqBy;
15675     lodash.split = split;
15676     lodash.spread = spread;
15677     lodash.tail = tail;
15678     lodash.take = take;
15679     lodash.takeRight = takeRight;
15680     lodash.takeRightWhile = takeRightWhile;
15681     lodash.takeWhile = takeWhile;
15682     lodash.tap = tap;
15683     lodash.throttle = throttle;
15684     lodash.thru = thru;
15685     lodash.toArray = toArray;
15686     lodash.toPairs = toPairs;
15687     lodash.toPairsIn = toPairsIn;
15688     lodash.toPath = toPath;
15689     lodash.toPlainObject = toPlainObject;
15690     lodash.transform = transform;
15691     lodash.unary = unary;
15692     lodash.union = union;
15693     lodash.unionBy = unionBy;
15694     lodash.unionWith = unionWith;
15695     lodash.uniq = uniq;
15696     lodash.uniqBy = uniqBy;
15697     lodash.uniqWith = uniqWith;
15698     lodash.unset = unset;
15699     lodash.unzip = unzip;
15700     lodash.unzipWith = unzipWith;
15701     lodash.update = update;
15702     lodash.updateWith = updateWith;
15703     lodash.values = values;
15704     lodash.valuesIn = valuesIn;
15705     lodash.without = without;
15706     lodash.words = words;
15707     lodash.wrap = wrap;
15708     lodash.xor = xor;
15709     lodash.xorBy = xorBy;
15710     lodash.xorWith = xorWith;
15711     lodash.zip = zip;
15712     lodash.zipObject = zipObject;
15713     lodash.zipObjectDeep = zipObjectDeep;
15714     lodash.zipWith = zipWith;
15715
15716     // Add aliases.
15717     lodash.entries = toPairs;
15718     lodash.entriesIn = toPairsIn;
15719     lodash.extend = assignIn;
15720     lodash.extendWith = assignInWith;
15721
15722     // Add methods to `lodash.prototype`.
15723     mixin(lodash, lodash);
15724
15725     /*------------------------------------------------------------------------*/
15726
15727     // Add methods that return unwrapped values in chain sequences.
15728     lodash.add = add;
15729     lodash.attempt = attempt;
15730     lodash.camelCase = camelCase;
15731     lodash.capitalize = capitalize;
15732     lodash.ceil = ceil;
15733     lodash.clamp = clamp;
15734     lodash.clone = clone;
15735     lodash.cloneDeep = cloneDeep;
15736     lodash.cloneDeepWith = cloneDeepWith;
15737     lodash.cloneWith = cloneWith;
15738     lodash.deburr = deburr;
15739     lodash.divide = divide;
15740     lodash.endsWith = endsWith;
15741     lodash.eq = eq;
15742     lodash.escape = escape;
15743     lodash.escapeRegExp = escapeRegExp;
15744     lodash.every = every;
15745     lodash.find = find;
15746     lodash.findIndex = findIndex;
15747     lodash.findKey = findKey;
15748     lodash.findLast = findLast;
15749     lodash.findLastIndex = findLastIndex;
15750     lodash.findLastKey = findLastKey;
15751     lodash.floor = floor;
15752     lodash.forEach = forEach;
15753     lodash.forEachRight = forEachRight;
15754     lodash.forIn = forIn;
15755     lodash.forInRight = forInRight;
15756     lodash.forOwn = forOwn;
15757     lodash.forOwnRight = forOwnRight;
15758     lodash.get = get;
15759     lodash.gt = gt;
15760     lodash.gte = gte;
15761     lodash.has = has;
15762     lodash.hasIn = hasIn;
15763     lodash.head = head;
15764     lodash.identity = identity;
15765     lodash.includes = includes;
15766     lodash.indexOf = indexOf;
15767     lodash.inRange = inRange;
15768     lodash.invoke = invoke;
15769     lodash.isArguments = isArguments;
15770     lodash.isArray = isArray;
15771     lodash.isArrayBuffer = isArrayBuffer;
15772     lodash.isArrayLike = isArrayLike;
15773     lodash.isArrayLikeObject = isArrayLikeObject;
15774     lodash.isBoolean = isBoolean;
15775     lodash.isBuffer = isBuffer;
15776     lodash.isDate = isDate;
15777     lodash.isElement = isElement;
15778     lodash.isEmpty = isEmpty;
15779     lodash.isEqual = isEqual;
15780     lodash.isEqualWith = isEqualWith;
15781     lodash.isError = isError;
15782     lodash.isFinite = isFinite;
15783     lodash.isFunction = isFunction;
15784     lodash.isInteger = isInteger;
15785     lodash.isLength = isLength;
15786     lodash.isMap = isMap;
15787     lodash.isMatch = isMatch;
15788     lodash.isMatchWith = isMatchWith;
15789     lodash.isNaN = isNaN;
15790     lodash.isNative = isNative;
15791     lodash.isNil = isNil;
15792     lodash.isNull = isNull;
15793     lodash.isNumber = isNumber;
15794     lodash.isObject = isObject;
15795     lodash.isObjectLike = isObjectLike;
15796     lodash.isPlainObject = isPlainObject;
15797     lodash.isRegExp = isRegExp;
15798     lodash.isSafeInteger = isSafeInteger;
15799     lodash.isSet = isSet;
15800     lodash.isString = isString;
15801     lodash.isSymbol = isSymbol;
15802     lodash.isTypedArray = isTypedArray;
15803     lodash.isUndefined = isUndefined;
15804     lodash.isWeakMap = isWeakMap;
15805     lodash.isWeakSet = isWeakSet;
15806     lodash.join = join;
15807     lodash.kebabCase = kebabCase;
15808     lodash.last = last;
15809     lodash.lastIndexOf = lastIndexOf;
15810     lodash.lowerCase = lowerCase;
15811     lodash.lowerFirst = lowerFirst;
15812     lodash.lt = lt;
15813     lodash.lte = lte;
15814     lodash.max = max;
15815     lodash.maxBy = maxBy;
15816     lodash.mean = mean;
15817     lodash.meanBy = meanBy;
15818     lodash.min = min;
15819     lodash.minBy = minBy;
15820     lodash.multiply = multiply;
15821     lodash.nth = nth;
15822     lodash.noConflict = noConflict;
15823     lodash.noop = noop;
15824     lodash.now = now;
15825     lodash.pad = pad;
15826     lodash.padEnd = padEnd;
15827     lodash.padStart = padStart;
15828     lodash.parseInt = parseInt;
15829     lodash.random = random;
15830     lodash.reduce = reduce;
15831     lodash.reduceRight = reduceRight;
15832     lodash.repeat = repeat;
15833     lodash.replace = replace;
15834     lodash.result = result;
15835     lodash.round = round;
15836     lodash.runInContext = runInContext;
15837     lodash.sample = sample;
15838     lodash.size = size;
15839     lodash.snakeCase = snakeCase;
15840     lodash.some = some;
15841     lodash.sortedIndex = sortedIndex;
15842     lodash.sortedIndexBy = sortedIndexBy;
15843     lodash.sortedIndexOf = sortedIndexOf;
15844     lodash.sortedLastIndex = sortedLastIndex;
15845     lodash.sortedLastIndexBy = sortedLastIndexBy;
15846     lodash.sortedLastIndexOf = sortedLastIndexOf;
15847     lodash.startCase = startCase;
15848     lodash.startsWith = startsWith;
15849     lodash.subtract = subtract;
15850     lodash.sum = sum;
15851     lodash.sumBy = sumBy;
15852     lodash.template = template;
15853     lodash.times = times;
15854     lodash.toInteger = toInteger;
15855     lodash.toLength = toLength;
15856     lodash.toLower = toLower;
15857     lodash.toNumber = toNumber;
15858     lodash.toSafeInteger = toSafeInteger;
15859     lodash.toString = toString;
15860     lodash.toUpper = toUpper;
15861     lodash.trim = trim;
15862     lodash.trimEnd = trimEnd;
15863     lodash.trimStart = trimStart;
15864     lodash.truncate = truncate;
15865     lodash.unescape = unescape;
15866     lodash.uniqueId = uniqueId;
15867     lodash.upperCase = upperCase;
15868     lodash.upperFirst = upperFirst;
15869
15870     // Add aliases.
15871     lodash.each = forEach;
15872     lodash.eachRight = forEachRight;
15873     lodash.first = head;
15874
15875     mixin(lodash, (function() {
15876       var source = {};
15877       baseForOwn(lodash, function(func, methodName) {
15878         if (!hasOwnProperty.call(lodash.prototype, methodName)) {
15879           source[methodName] = func;
15880         }
15881       });
15882       return source;
15883     }()), { 'chain': false });
15884
15885     /*------------------------------------------------------------------------*/
15886
15887     /**
15888      * The semantic version number.
15889      *
15890      * @static
15891      * @memberOf _
15892      * @type {string}
15893      */
15894     lodash.VERSION = VERSION;
15895
15896     // Assign default placeholders.
15897     arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
15898       lodash[methodName].placeholder = lodash;
15899     });
15900
15901     // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
15902     arrayEach(['drop', 'take'], function(methodName, index) {
15903       LazyWrapper.prototype[methodName] = function(n) {
15904         var filtered = this.__filtered__;
15905         if (filtered && !index) {
15906           return new LazyWrapper(this);
15907         }
15908         n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
15909
15910         var result = this.clone();
15911         if (filtered) {
15912           result.__takeCount__ = nativeMin(n, result.__takeCount__);
15913         } else {
15914           result.__views__.push({
15915             'size': nativeMin(n, MAX_ARRAY_LENGTH),
15916             'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
15917           });
15918         }
15919         return result;
15920       };
15921
15922       LazyWrapper.prototype[methodName + 'Right'] = function(n) {
15923         return this.reverse()[methodName](n).reverse();
15924       };
15925     });
15926
15927     // Add `LazyWrapper` methods that accept an `iteratee` value.
15928     arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
15929       var type = index + 1,
15930           isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
15931
15932       LazyWrapper.prototype[methodName] = function(iteratee) {
15933         var result = this.clone();
15934         result.__iteratees__.push({
15935           'iteratee': getIteratee(iteratee, 3),
15936           'type': type
15937         });
15938         result.__filtered__ = result.__filtered__ || isFilter;
15939         return result;
15940       };
15941     });
15942
15943     // Add `LazyWrapper` methods for `_.head` and `_.last`.
15944     arrayEach(['head', 'last'], function(methodName, index) {
15945       var takeName = 'take' + (index ? 'Right' : '');
15946
15947       LazyWrapper.prototype[methodName] = function() {
15948         return this[takeName](1).value()[0];
15949       };
15950     });
15951
15952     // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
15953     arrayEach(['initial', 'tail'], function(methodName, index) {
15954       var dropName = 'drop' + (index ? '' : 'Right');
15955
15956       LazyWrapper.prototype[methodName] = function() {
15957         return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
15958       };
15959     });
15960
15961     LazyWrapper.prototype.compact = function() {
15962       return this.filter(identity);
15963     };
15964
15965     LazyWrapper.prototype.find = function(predicate) {
15966       return this.filter(predicate).head();
15967     };
15968
15969     LazyWrapper.prototype.findLast = function(predicate) {
15970       return this.reverse().find(predicate);
15971     };
15972
15973     LazyWrapper.prototype.invokeMap = rest(function(path, args) {
15974       if (typeof path == 'function') {
15975         return new LazyWrapper(this);
15976       }
15977       return this.map(function(value) {
15978         return baseInvoke(value, path, args);
15979       });
15980     });
15981
15982     LazyWrapper.prototype.reject = function(predicate) {
15983       predicate = getIteratee(predicate, 3);
15984       return this.filter(function(value) {
15985         return !predicate(value);
15986       });
15987     };
15988
15989     LazyWrapper.prototype.slice = function(start, end) {
15990       start = toInteger(start);
15991
15992       var result = this;
15993       if (result.__filtered__ && (start > 0 || end < 0)) {
15994         return new LazyWrapper(result);
15995       }
15996       if (start < 0) {
15997         result = result.takeRight(-start);
15998       } else if (start) {
15999         result = result.drop(start);
16000       }
16001       if (end !== undefined) {
16002         end = toInteger(end);
16003         result = end < 0 ? result.dropRight(-end) : result.take(end - start);
16004       }
16005       return result;
16006     };
16007
16008     LazyWrapper.prototype.takeRightWhile = function(predicate) {
16009       return this.reverse().takeWhile(predicate).reverse();
16010     };
16011
16012     LazyWrapper.prototype.toArray = function() {
16013       return this.take(MAX_ARRAY_LENGTH);
16014     };
16015
16016     // Add `LazyWrapper` methods to `lodash.prototype`.
16017     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
16018       var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
16019           isTaker = /^(?:head|last)$/.test(methodName),
16020           lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
16021           retUnwrapped = isTaker || /^find/.test(methodName);
16022
16023       if (!lodashFunc) {
16024         return;
16025       }
16026       lodash.prototype[methodName] = function() {
16027         var value = this.__wrapped__,
16028             args = isTaker ? [1] : arguments,
16029             isLazy = value instanceof LazyWrapper,
16030             iteratee = args[0],
16031             useLazy = isLazy || isArray(value);
16032
16033         var interceptor = function(value) {
16034           var result = lodashFunc.apply(lodash, arrayPush([value], args));
16035           return (isTaker && chainAll) ? result[0] : result;
16036         };
16037
16038         if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
16039           // Avoid lazy use if the iteratee has a "length" value other than `1`.
16040           isLazy = useLazy = false;
16041         }
16042         var chainAll = this.__chain__,
16043             isHybrid = !!this.__actions__.length,
16044             isUnwrapped = retUnwrapped && !chainAll,
16045             onlyLazy = isLazy && !isHybrid;
16046
16047         if (!retUnwrapped && useLazy) {
16048           value = onlyLazy ? value : new LazyWrapper(this);
16049           var result = func.apply(value, args);
16050           result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
16051           return new LodashWrapper(result, chainAll);
16052         }
16053         if (isUnwrapped && onlyLazy) {
16054           return func.apply(this, args);
16055         }
16056         result = this.thru(interceptor);
16057         return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
16058       };
16059     });
16060
16061     // Add `Array` methods to `lodash.prototype`.
16062     arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
16063       var func = arrayProto[methodName],
16064           chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
16065           retUnwrapped = /^(?:pop|shift)$/.test(methodName);
16066
16067       lodash.prototype[methodName] = function() {
16068         var args = arguments;
16069         if (retUnwrapped && !this.__chain__) {
16070           var value = this.value();
16071           return func.apply(isArray(value) ? value : [], args);
16072         }
16073         return this[chainName](function(value) {
16074           return func.apply(isArray(value) ? value : [], args);
16075         });
16076       };
16077     });
16078
16079     // Map minified method names to their real names.
16080     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
16081       var lodashFunc = lodash[methodName];
16082       if (lodashFunc) {
16083         var key = (lodashFunc.name + ''),
16084             names = realNames[key] || (realNames[key] = []);
16085
16086         names.push({ 'name': methodName, 'func': lodashFunc });
16087       }
16088     });
16089
16090     realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{
16091       'name': 'wrapper',
16092       'func': undefined
16093     }];
16094
16095     // Add methods to `LazyWrapper`.
16096     LazyWrapper.prototype.clone = lazyClone;
16097     LazyWrapper.prototype.reverse = lazyReverse;
16098     LazyWrapper.prototype.value = lazyValue;
16099
16100     // Add chain sequence methods to the `lodash` wrapper.
16101     lodash.prototype.at = wrapperAt;
16102     lodash.prototype.chain = wrapperChain;
16103     lodash.prototype.commit = wrapperCommit;
16104     lodash.prototype.next = wrapperNext;
16105     lodash.prototype.plant = wrapperPlant;
16106     lodash.prototype.reverse = wrapperReverse;
16107     lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
16108
16109     if (iteratorSymbol) {
16110       lodash.prototype[iteratorSymbol] = wrapperToIterator;
16111     }
16112     return lodash;
16113   }
16114
16115   /*--------------------------------------------------------------------------*/
16116
16117   // Export lodash.
16118   var _ = runInContext();
16119
16120   // Expose Lodash on the free variable `window` or `self` when available so it's
16121   // globally accessible, even when bundled with Browserify, Webpack, etc. This
16122   // also prevents errors in cases where Lodash is loaded by a script tag in the
16123   // presence of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch
16124   // for more details. Use `_.noConflict` to remove Lodash from the global object.
16125   (freeWindow || freeSelf || {})._ = _;
16126
16127   // Some AMD build optimizers like r.js check for condition patterns like the following:
16128   if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
16129     // Define as an anonymous module so, through path mapping, it can be
16130     // referenced as the "underscore" module.
16131     define(function() {
16132       return _;
16133     });
16134   }
16135   // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
16136   else if (freeExports && freeModule) {
16137     // Export for Node.js.
16138     if (moduleExports) {
16139       (freeModule.exports = _)._ = _;
16140     }
16141     // Export for CommonJS support.
16142     freeExports._ = _;
16143   }
16144   else {
16145     // Export to the global object.
16146     root._ = _;
16147   }
16148 }.call(this));